1: #include "first.h"
2:
3: #include "base.h"
4: #include "connections.h"
5: #include "joblist.h"
6: #include "log.h"
7:
8: #include <errno.h>
9:
10: #ifdef USE_OPENSSL
11: # include <openssl/ssl.h>
12: # include <openssl/err.h>
13: #endif
14:
15: const char *connection_get_state(connection_state_t state) {
16: switch (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)";
29: }
30: }
31:
32: const char *connection_get_short_state(connection_state_t state) {
33: switch (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";
45: default: return "x";
46: }
47: }
48:
49: int connection_set_state(server *srv, connection *con, connection_state_t state) {
50: UNUSED(srv);
51:
52: con->state = state;
53:
54: return 0;
55: }
56:
57: #if 0
58: static void dump_packet(const unsigned char *data, size_t len) {
59: size_t i, j;
60:
61: if (len == 0) return;
62:
63: for (i = 0; i < len; i++) {
64: if (i % 16 == 0) fprintf(stderr, " ");
65:
66: fprintf(stderr, "%02x ", data[i]);
67:
68: if ((i + 1) % 16 == 0) {
69: fprintf(stderr, " ");
70: for (j = 0; j <= i % 16; j++) {
71: unsigned char c;
72:
73: if (i-15+j >= len) break;
74:
75: c = data[i-15+j];
76:
77: fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
78: }
79:
80: fprintf(stderr, "\n");
81: }
82: }
83:
84: if (len % 16 != 0) {
85: for (j = i % 16; j < 16; j++) {
86: fprintf(stderr, " ");
87: }
88:
89: fprintf(stderr, " ");
90: for (j = i & ~0xf; j < len; j++) {
91: unsigned char c;
92:
93: c = data[j];
94: fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
95: }
96: fprintf(stderr, "\n");
97: }
98: }
99: #endif
100:
101: static int connection_handle_read_ssl(server *srv, connection *con) {
102: #ifdef USE_OPENSSL
103: int r, ssl_err, len;
104: char *mem = NULL;
105: size_t mem_len = 0;
106:
107: if (!con->srv_socket->is_ssl) return -1;
108:
109: ERR_clear_error();
110: do {
111: chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, SSL_pending(con->ssl));
112: #if 0
113: /* overwrite everything with 0 */
114: memset(mem, 0, mem_len);
115: #endif
116:
117: len = SSL_read(con->ssl, mem, mem_len);
118: if (len > 0) {
119: chunkqueue_use_memory(con->read_queue, len);
120: con->bytes_read += len;
121: } else {
122: chunkqueue_use_memory(con->read_queue, 0);
123: }
124:
125: if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) {
126: log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client, killing connection");
127: connection_set_state(srv, con, CON_STATE_ERROR);
128: return -1;
129: }
130: } while (len > 0);
131:
132: if (len < 0) {
133: int oerrno = errno;
134: switch ((r = SSL_get_error(con->ssl, len))) {
135: case SSL_ERROR_WANT_WRITE:
136: con->is_writable = -1;
137: case SSL_ERROR_WANT_READ:
138: con->is_readable = 0;
139:
140: /* the manual says we have to call SSL_read with the same arguments next time.
141: * we ignore this restriction; no one has complained about it in 1.5 yet, so it probably works anyway.
142: */
143:
144: return 0;
145: case SSL_ERROR_SYSCALL:
146: /**
147: * man SSL_get_error()
148: *
149: * SSL_ERROR_SYSCALL
150: * Some I/O error occurred. The OpenSSL error queue may contain more
151: * information on the error. If the error queue is empty (i.e.
152: * ERR_get_error() returns 0), ret can be used to find out more about
153: * the error: If ret == 0, an EOF was observed that violates the
154: * protocol. If ret == -1, the underlying BIO reported an I/O error
155: * (for socket I/O on Unix systems, consult errno for details).
156: *
157: */
158: while((ssl_err = ERR_get_error())) {
159: /* get all errors from the error-queue */
160: log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
161: r, ERR_error_string(ssl_err, NULL));
162: }
163:
164: switch(oerrno) {
165: default:
166: log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
167: len, r, oerrno,
168: strerror(oerrno));
169: break;
170: }
171:
172: break;
173: case SSL_ERROR_ZERO_RETURN:
174: /* clean shutdown on the remote side */
175:
176: if (r == 0) {
177: /* FIXME: later */
178: }
179:
180: /* fall thourgh */
181: default:
182: while((ssl_err = ERR_get_error())) {
183: switch (ERR_GET_REASON(ssl_err)) {
184: case SSL_R_SSL_HANDSHAKE_FAILURE:
185: #ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
186: case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
187: #endif
188: #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
189: case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
190: #endif
191: #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
192: case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
193: #endif
194: if (!con->conf.log_ssl_noise) continue;
195: break;
196: default:
197: break;
198: }
199: /* get all errors from the error-queue */
200: log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
201: r, ERR_error_string(ssl_err, NULL));
202: }
203: break;
204: }
205:
206: connection_set_state(srv, con, CON_STATE_ERROR);
207:
208: return -1;
209: } else if (len == 0) {
210: con->is_readable = 0;
211: /* the other end close the connection -> KEEP-ALIVE */
212:
213: return -2;
214: } else {
215: return 0;
216: }
217: #else
218: UNUSED(srv);
219: UNUSED(con);
220: return -1;
221: #endif
222: }
223:
224: /* 0: everything ok, -1: error, -2: con closed */
225: int connection_handle_read(server *srv, connection *con) {
226: int len;
227: char *mem = NULL;
228: size_t mem_len = 0;
229: int toread;
230:
231: if (con->srv_socket->is_ssl) {
232: return connection_handle_read_ssl(srv, con);
233: }
234:
235: /* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
236: * us more than 4kb is available
237: * if FIONREAD doesn't signal a big chunk we fill the previous buffer
238: * if it has >= 1kb free
239: */
240: #if defined(__WIN32)
241: chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, 4096);
242:
243: len = recv(con->fd, mem, mem_len, 0);
244: #else /* __WIN32 */
245: if (ioctl(con->fd, FIONREAD, &toread) || toread <= 4*1024) {
246: toread = 4096;
247: }
248: else if (toread > MAX_READ_LIMIT) {
249: toread = MAX_READ_LIMIT;
250: }
251: chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, toread);
252:
253: len = read(con->fd, mem, mem_len);
254: #endif /* __WIN32 */
255:
256: chunkqueue_use_memory(con->read_queue, len > 0 ? len : 0);
257:
258: if (len < 0) {
259: con->is_readable = 0;
260:
261: #if defined(__WIN32)
262: {
263: int lastError = WSAGetLastError();
264: switch (lastError) {
265: case EAGAIN:
266: return 0;
267: case EINTR:
268: /* we have been interrupted before we could read */
269: con->is_readable = 1;
270: return 0;
271: case ECONNRESET:
272: /* suppress logging for this error, expected for keep-alive */
273: break;
274: default:
275: log_error_write(srv, __FILE__, __LINE__, "sd", "connection closed - recv failed: ", lastError);
276: break;
277: }
278: }
279: #else /* __WIN32 */
280: switch (errno) {
281: case EAGAIN:
282: return 0;
283: case EINTR:
284: /* we have been interrupted before we could read */
285: con->is_readable = 1;
286: return 0;
287: case ECONNRESET:
288: /* suppress logging for this error, expected for keep-alive */
289: break;
290: default:
291: log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
292: break;
293: }
294: #endif /* __WIN32 */
295:
296: connection_set_state(srv, con, CON_STATE_ERROR);
297:
298: return -1;
299: } else if (len == 0) {
300: con->is_readable = 0;
301: /* the other end close the connection -> KEEP-ALIVE */
302:
303: /* pipelining */
304:
305: return -2;
306: } else if (len != (ssize_t) mem_len) {
307: /* we got less then expected, wait for the next fd-event */
308:
309: con->is_readable = 0;
310: }
311:
312: con->bytes_read += len;
313: #if 0
314: dump_packet(b->ptr, len);
315: #endif
316:
317: return 0;
318: }
319:
320: handler_t connection_handle_read_post_state(server *srv, connection *con) {
321: chunkqueue *cq = con->read_queue;
322: chunkqueue *dst_cq = con->request_content_queue;
323:
324: int is_closed = 0;
325:
326: if (con->is_readable) {
327: con->read_idle_ts = srv->cur_ts;
328:
329: switch(connection_handle_read(srv, con)) {
330: case -1:
331: return HANDLER_ERROR;
332: case -2:
333: is_closed = 1;
334: break;
335: default:
336: break;
337: }
338: }
339:
340: chunkqueue_remove_finished_chunks(cq);
341:
342: if (con->request.content_length <= 64*1024) {
343: /* don't buffer request bodies <= 64k on disk */
344: chunkqueue_steal(dst_cq, cq, (off_t)con->request.content_length - dst_cq->bytes_in);
345: }
346: else if (0 != chunkqueue_steal_with_tempfiles(srv, dst_cq, cq, (off_t)con->request.content_length - dst_cq->bytes_in)) {
347: /* writing to temp file failed */
348: con->http_status = 500; /* Internal Server Error */
349: con->keep_alive = 0;
350: con->mode = DIRECT;
351: chunkqueue_reset(con->write_queue);
352:
353: return HANDLER_FINISHED;
354: }
355:
356: chunkqueue_remove_finished_chunks(cq);
357:
358: if (dst_cq->bytes_in == (off_t)con->request.content_length) {
359: /* Content is ready */
360: con->conf.stream_request_body &= ~FDEVENT_STREAM_REQUEST_POLLIN;
361: if (con->state == CON_STATE_READ_POST) {
362: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
363: }
364: return HANDLER_GO_ON;
365: } else if (is_closed) {
366: #if 0
367: con->http_status = 400; /* Bad Request */
368: con->keep_alive = 0;
369: con->mode = DIRECT;
370: chunkqueue_reset(con->write_queue);
371:
372: return HANDLER_FINISHED;
373: #endif
374: return HANDLER_ERROR;
375: } else {
376: con->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLIN;
377: return (con->conf.stream_request_body & FDEVENT_STREAM_REQUEST)
378: ? HANDLER_GO_ON
379: : HANDLER_WAIT_FOR_EVENT;
380: }
381: }
382:
383: void connection_response_reset(server *srv, connection *con) {
384: UNUSED(srv);
385:
386: con->http_status = 0;
387: con->is_writable = 1;
388: con->file_finished = 0;
389: con->file_started = 0;
390: con->got_response = 0;
391: con->parsed_response = 0;
392: con->response.keep_alive = 0;
393: con->response.content_length = -1;
394: con->response.transfer_encoding = 0;
395: buffer_reset(con->physical.path);
396: array_reset(con->response.headers);
397: chunkqueue_reset(con->write_queue);
398: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>