4 #include "connections.h"
11 # include <openssl/ssl.h>
12 # include <openssl/err.h>
15 const char *connection_get_state(connection_state_t state
) {
17 case CON_STATE_CONNECT
: return "connect";
18 case CON_STATE_READ
: return "read";
19 case CON_STATE_READ_POST
: return "readpost";
20 case CON_STATE_WRITE
: return "write";
21 case CON_STATE_CLOSE
: return "close";
22 case CON_STATE_ERROR
: return "error";
23 case CON_STATE_HANDLE_REQUEST
: return "handle-req";
24 case CON_STATE_REQUEST_START
: return "req-start";
25 case CON_STATE_REQUEST_END
: return "req-end";
26 case CON_STATE_RESPONSE_START
: return "resp-start";
27 case CON_STATE_RESPONSE_END
: return "resp-end";
28 default: return "(unknown)";
32 const char *connection_get_short_state(connection_state_t state
) {
34 case CON_STATE_CONNECT
: return ".";
35 case CON_STATE_READ
: return "r";
36 case CON_STATE_READ_POST
: return "R";
37 case CON_STATE_WRITE
: return "W";
38 case CON_STATE_CLOSE
: return "C";
39 case CON_STATE_ERROR
: return "E";
40 case CON_STATE_HANDLE_REQUEST
: return "h";
41 case CON_STATE_REQUEST_START
: return "q";
42 case CON_STATE_REQUEST_END
: return "Q";
43 case CON_STATE_RESPONSE_START
: return "s";
44 case CON_STATE_RESPONSE_END
: return "S";
49 int connection_set_state(server
*srv
, connection
*con
, connection_state_t state
) {
58 static void dump_packet(const unsigned char *data
, size_t len
) {
63 for (i
= 0; i
< len
; i
++) {
64 if (i
% 16 == 0) fprintf(stderr
, " ");
66 fprintf(stderr
, "%02x ", data
[i
]);
68 if ((i
+ 1) % 16 == 0) {
70 for (j
= 0; j
<= i
% 16; j
++) {
73 if (i
-15+j
>= len
) break;
77 fprintf(stderr
, "%c", c
> 32 && c
< 128 ? c
: '.');
80 fprintf(stderr
, "\n");
85 for (j
= i
% 16; j
< 16; j
++) {
90 for (j
= i
& ~0xf; j
< len
; j
++) {
94 fprintf(stderr
, "%c", c
> 32 && c
< 128 ? c
: '.');
96 fprintf(stderr
, "\n");
101 static int connection_handle_read_ssl(server
*srv
, connection
*con
) {
103 int r
, ssl_err
, len
, count
= 0;
107 if (!con
->srv_socket
->is_ssl
) return -1;
111 chunkqueue_get_memory(con
->read_queue
, &mem
, &mem_len
, 0, SSL_pending(con
->ssl
));
113 /* overwrite everything with 0 */
114 memset(mem
, 0, mem_len
);
117 len
= SSL_read(con
->ssl
, mem
, mem_len
);
118 chunkqueue_use_memory(con
->read_queue
, len
> 0 ? len
: 0);
120 if (con
->renegotiations
> 1 && con
->conf
.ssl_disable_client_renegotiation
) {
121 log_error_write(srv
, __FILE__
, __LINE__
, "s", "SSL: renegotiation initiated by client, killing connection");
122 connection_set_state(srv
, con
, CON_STATE_ERROR
);
127 con
->bytes_read
+= len
;
130 } while (len
== (ssize_t
) mem_len
&& count
< MAX_READ_LIMIT
);
135 switch ((r
= SSL_get_error(con
->ssl
, len
))) {
136 case SSL_ERROR_WANT_WRITE
:
137 con
->is_writable
= -1;
138 case SSL_ERROR_WANT_READ
:
139 con
->is_readable
= 0;
141 /* the manual says we have to call SSL_read with the same arguments next time.
142 * we ignore this restriction; no one has complained about it in 1.5 yet, so it probably works anyway.
146 case SSL_ERROR_SYSCALL
:
148 * man SSL_get_error()
151 * Some I/O error occurred. The OpenSSL error queue may contain more
152 * information on the error. If the error queue is empty (i.e.
153 * ERR_get_error() returns 0), ret can be used to find out more about
154 * the error: If ret == 0, an EOF was observed that violates the
155 * protocol. If ret == -1, the underlying BIO reported an I/O error
156 * (for socket I/O on Unix systems, consult errno for details).
159 while((ssl_err
= ERR_get_error())) {
160 /* get all errors from the error-queue */
161 log_error_write(srv
, __FILE__
, __LINE__
, "sds", "SSL:",
162 r
, ERR_error_string(ssl_err
, NULL
));
167 log_error_write(srv
, __FILE__
, __LINE__
, "sddds", "SSL:",
174 case SSL_ERROR_ZERO_RETURN
:
175 /* clean shutdown on the remote side */
183 while((ssl_err
= ERR_get_error())) {
184 switch (ERR_GET_REASON(ssl_err
)) {
185 case SSL_R_SSL_HANDSHAKE_FAILURE
:
186 #ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
187 case SSL_R_TLSV1_ALERT_UNKNOWN_CA
:
189 #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
190 case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
:
192 #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
193 case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
:
195 if (!con
->conf
.log_ssl_noise
) continue;
200 /* get all errors from the error-queue */
201 log_error_write(srv
, __FILE__
, __LINE__
, "sds", "SSL:",
202 r
, ERR_error_string(ssl_err
, NULL
));
207 connection_set_state(srv
, con
, CON_STATE_ERROR
);
210 } else if (len
== 0) {
211 con
->is_readable
= 0;
212 /* the other end close the connection -> KEEP-ALIVE */
225 /* 0: everything ok, -1: error, -2: con closed */
226 int connection_handle_read(server
*srv
, connection
*con
) {
232 if (con
->srv_socket
->is_ssl
) {
233 return connection_handle_read_ssl(srv
, con
);
236 /* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
237 * us more than 4kb is available
238 * if FIONREAD doesn't signal a big chunk we fill the previous buffer
239 * if it has >= 1kb free
242 chunkqueue_get_memory(con
->read_queue
, &mem
, &mem_len
, 0, 4096);
244 len
= recv(con
->fd
, mem
, mem_len
, 0);
246 if (ioctl(con
->fd
, FIONREAD
, &toread
) || toread
<= 4*1024) {
249 else if (toread
> MAX_READ_LIMIT
) {
250 toread
= MAX_READ_LIMIT
;
252 chunkqueue_get_memory(con
->read_queue
, &mem
, &mem_len
, 0, toread
);
254 len
= read(con
->fd
, mem
, mem_len
);
257 chunkqueue_use_memory(con
->read_queue
, len
> 0 ? len
: 0);
260 con
->is_readable
= 0;
264 int lastError
= WSAGetLastError();
269 /* we have been interrupted before we could read */
270 con
->is_readable
= 1;
273 /* suppress logging for this error, expected for keep-alive */
276 log_error_write(srv
, __FILE__
, __LINE__
, "sd", "connection closed - recv failed: ", lastError
);
285 /* we have been interrupted before we could read */
286 con
->is_readable
= 1;
289 /* suppress logging for this error, expected for keep-alive */
292 log_error_write(srv
, __FILE__
, __LINE__
, "ssd", "connection closed - read failed: ", strerror(errno
), errno
);
297 connection_set_state(srv
, con
, CON_STATE_ERROR
);
300 } else if (len
== 0) {
301 con
->is_readable
= 0;
302 /* the other end close the connection -> KEEP-ALIVE */
307 } else if (len
!= (ssize_t
) mem_len
) {
308 /* we got less then expected, wait for the next fd-event */
310 con
->is_readable
= 0;
313 con
->bytes_read
+= len
;
315 dump_packet(b
->ptr
, len
);
321 handler_t
connection_handle_read_post_state(server
*srv
, connection
*con
) {
322 chunkqueue
*cq
= con
->read_queue
;
323 chunkqueue
*dst_cq
= con
->request_content_queue
;
327 if (con
->is_readable
) {
328 con
->read_idle_ts
= srv
->cur_ts
;
330 switch(connection_handle_read(srv
, con
)) {
332 return HANDLER_ERROR
;
341 chunkqueue_remove_finished_chunks(cq
);
343 if (con
->request
.content_length
<= 64*1024) {
344 /* don't buffer request bodies <= 64k on disk */
345 chunkqueue_steal(dst_cq
, cq
, (off_t
)con
->request
.content_length
- dst_cq
->bytes_in
);
347 else if (0 != chunkqueue_steal_with_tempfiles(srv
, dst_cq
, cq
, (off_t
)con
->request
.content_length
- dst_cq
->bytes_in
)) {
348 /* writing to temp file failed */
349 con
->http_status
= 500; /* Internal Server Error */
352 chunkqueue_reset(con
->write_queue
);
354 return HANDLER_FINISHED
;
357 chunkqueue_remove_finished_chunks(cq
);
359 if (dst_cq
->bytes_in
== (off_t
)con
->request
.content_length
) {
360 /* Content is ready */
361 con
->conf
.stream_request_body
&= ~FDEVENT_STREAM_REQUEST_POLLIN
;
362 if (con
->state
== CON_STATE_READ_POST
) {
363 connection_set_state(srv
, con
, CON_STATE_HANDLE_REQUEST
);
365 return HANDLER_GO_ON
;
366 } else if (is_closed
) {
368 con
->http_status
= 400; /* Bad Request */
371 chunkqueue_reset(con
->write_queue
);
373 return HANDLER_FINISHED
;
375 return HANDLER_ERROR
;
377 con
->conf
.stream_request_body
|= FDEVENT_STREAM_REQUEST_POLLIN
;
378 return (con
->conf
.stream_request_body
& FDEVENT_STREAM_REQUEST
)
380 : HANDLER_WAIT_FOR_EVENT
;
384 void connection_response_reset(server
*srv
, connection
*con
) {
387 con
->http_status
= 0;
388 con
->is_writable
= 1;
389 con
->file_finished
= 0;
390 con
->file_started
= 0;
391 con
->got_response
= 0;
392 con
->parsed_response
= 0;
393 con
->response
.keep_alive
= 0;
394 con
->response
.content_length
= -1;
395 con
->response
.transfer_encoding
= 0;
396 buffer_reset(con
->physical
.path
);
397 array_reset(con
->response
.headers
);
398 chunkqueue_reset(con
->write_queue
);