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_WRITE
:
129 return 0; /* try again later */
130 case SSL_ERROR_SYSCALL
:
131 /* perhaps we have error waiting in our error-queue */
132 if (0 != (err
= ERR_get_error())) {
134 log_error_write(srv
, __FILE__
, __LINE__
, "sdds", "SSL:",
136 ERR_error_string(err
, NULL
));
137 } while((err
= ERR_get_error()));
138 } else if (r
== -1) {
139 /* no, but we have errno */
145 log_error_write(srv
, __FILE__
, __LINE__
, "sddds", "SSL:",
151 /* neither error-queue nor errno ? */
152 log_error_write(srv
, __FILE__
, __LINE__
, "sddds", "SSL (error):",
158 case SSL_ERROR_ZERO_RETURN
:
159 /* clean shutdown on the remote side */
161 if (r
== 0) return -2;
165 while((err
= ERR_get_error())) {
166 log_error_write(srv
, __FILE__
, __LINE__
, "sdds", "SSL:",
168 ERR_error_string(err
, NULL
));
175 chunkqueue_mark_written(cq
, r
);
178 if ((size_t) r
< data_len
) break; /* try again later */
183 #endif /* USE_OPENSSL */