3 #include "network_backends.h"
5 #if defined(USE_OPENSSL)
16 # include <openssl/ssl.h>
17 # include <openssl/err.h>
19 static int load_next_chunk(server
*srv
, connection
*con
, chunkqueue
*cq
, off_t max_bytes
, const char **data
, size_t *data_len
) {
20 chunk
* const c
= cq
->first
;
22 #define LOCAL_SEND_BUFSIZE (64 * 1024)
23 /* this is a 64k sendbuffer
25 * it has to stay at the same location all the time to satisfy the needs
26 * of SSL_write to pass the SAME parameter in case of a _WANT_WRITE
28 * the buffer is allocated once, is NOT realloced and is NOT freed at shutdown
29 * -> we expect a 64k block to 'leak' in valgrind
31 static char *local_send_buffer
= NULL
;
33 force_assert(NULL
!= c
);
40 force_assert(c
->offset
>= 0 && c
->offset
<= (off_t
)buffer_string_length(c
->mem
));
42 have
= buffer_string_length(c
->mem
) - c
->offset
;
43 if ((off_t
) have
> max_bytes
) have
= max_bytes
;
45 *data
= c
->mem
->ptr
+ c
->offset
;
51 if (NULL
== local_send_buffer
) {
52 local_send_buffer
= malloc(LOCAL_SEND_BUFSIZE
);
53 force_assert(NULL
!= local_send_buffer
);
56 if (0 != network_open_file_chunk(srv
, con
, cq
)) return -1;
61 force_assert(c
->offset
>= 0 && c
->offset
<= c
->file
.length
);
62 offset
= c
->file
.start
+ c
->offset
;
63 toSend
= c
->file
.length
- c
->offset
;
65 if (toSend
> LOCAL_SEND_BUFSIZE
) toSend
= LOCAL_SEND_BUFSIZE
;
66 if (toSend
> max_bytes
) toSend
= max_bytes
;
68 if (-1 == lseek(c
->file
.fd
, offset
, SEEK_SET
)) {
69 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "lseek: ", strerror(errno
));
72 if (-1 == (toSend
= read(c
->file
.fd
, local_send_buffer
, toSend
))) {
73 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "read: ", strerror(errno
));
77 *data
= local_send_buffer
;
87 int network_write_chunkqueue_openssl(server
*srv
, connection
*con
, SSL
*ssl
, chunkqueue
*cq
, off_t max_bytes
) {
88 /* the remote side closed the connection before without shutdown request
91 * if keep-alive is disabled */
93 if (con
->keep_alive
== 0) {
94 SSL_set_shutdown(ssl
, SSL_RECEIVED_SHUTDOWN
);
97 chunkqueue_remove_finished_chunks(cq
);
99 while (max_bytes
> 0 && NULL
!= cq
->first
) {
104 if (0 != load_next_chunk(srv
, con
, cq
, max_bytes
, &data
, &data_len
)) return -1;
110 * When an SSL_write() operation has to be repeated because of
111 * SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be
112 * repeated with the same arguments.
116 r
= SSL_write(ssl
, data
, data_len
);
118 if (con
->renegotiations
> 1 && con
->conf
.ssl_disable_client_renegotiation
) {
119 log_error_write(srv
, __FILE__
, __LINE__
, "s", "SSL: renegotiation initiated by client, killing connection");
127 switch ((ssl_r
= SSL_get_error(ssl
, r
))) {
128 case SSL_ERROR_WANT_READ
:
129 con
->is_readable
= -1;
130 return 0; /* try again later */
131 case SSL_ERROR_WANT_WRITE
:
132 con
->is_writable
= -1;
133 return 0; /* try again later */
134 case SSL_ERROR_SYSCALL
:
135 /* perhaps we have error waiting in our error-queue */
136 if (0 != (err
= ERR_get_error())) {
138 log_error_write(srv
, __FILE__
, __LINE__
, "sdds", "SSL:",
140 ERR_error_string(err
, NULL
));
141 } while((err
= ERR_get_error()));
142 } else if (r
== -1) {
143 /* no, but we have errno */
149 log_error_write(srv
, __FILE__
, __LINE__
, "sddds", "SSL:",
155 /* neither error-queue nor errno ? */
156 log_error_write(srv
, __FILE__
, __LINE__
, "sddds", "SSL (error):",
162 case SSL_ERROR_ZERO_RETURN
:
163 /* clean shutdown on the remote side */
165 if (r
== 0) return -2;
169 while((err
= ERR_get_error())) {
170 log_error_write(srv
, __FILE__
, __LINE__
, "sdds", "SSL:",
172 ERR_error_string(err
, NULL
));
179 chunkqueue_mark_written(cq
, r
);
182 if ((size_t) r
< data_len
) break; /* try again later */
187 #endif /* USE_OPENSSL */