diff options
-rw-r--r-- | src/microspdy/Makefile.am | 3 | ||||
-rw-r--r-- | src/microspdy/daemon.c | 18 | ||||
-rw-r--r-- | src/microspdy/io.h | 162 | ||||
-rw-r--r-- | src/microspdy/session.c | 27 | ||||
-rw-r--r-- | src/microspdy/structures.h | 44 | ||||
-rw-r--r-- | src/microspdy/tls.c | 52 | ||||
-rw-r--r-- | src/microspdy/tls.h | 4 |
7 files changed, 259 insertions, 51 deletions
diff --git a/src/microspdy/Makefile.am b/src/microspdy/Makefile.am index 0509134a..7d3c3d2b 100644 --- a/src/microspdy/Makefile.am +++ b/src/microspdy/Makefile.am | |||
@@ -5,7 +5,7 @@ endif | |||
5 | AM_CPPFLAGS = \ | 5 | AM_CPPFLAGS = \ |
6 | $(PLIBC_INCLUDE) \ | 6 | $(PLIBC_INCLUDE) \ |
7 | -I$(top_srcdir)/src/include \ | 7 | -I$(top_srcdir)/src/include \ |
8 | -I$(top_srcdir)/src/microspdy | 8 | -I$(top_srcdir)/src/microspdy |
9 | 9 | ||
10 | 10 | ||
11 | EXTRA_DIST = EXPORT.sym | 11 | EXTRA_DIST = EXPORT.sym |
@@ -15,6 +15,7 @@ lib_LTLIBRARIES = \ | |||
15 | libmicrospdy.la | 15 | libmicrospdy.la |
16 | 16 | ||
17 | libmicrospdy_la_SOURCES = \ | 17 | libmicrospdy_la_SOURCES = \ |
18 | io.h \ | ||
18 | tls.h tls.c \ | 19 | tls.h tls.c \ |
19 | structures.h structures.c \ | 20 | structures.h structures.c \ |
20 | internal.h internal.c \ | 21 | internal.h internal.c \ |
diff --git a/src/microspdy/daemon.c b/src/microspdy/daemon.c index d96df020..4c59c2cc 100644 --- a/src/microspdy/daemon.c +++ b/src/microspdy/daemon.c | |||
@@ -191,6 +191,8 @@ SPDYF_start_daemon_va (uint16_t port, | |||
191 | memset (daemon, 0, sizeof (struct SPDY_Daemon)); | 191 | memset (daemon, 0, sizeof (struct SPDY_Daemon)); |
192 | daemon->socket_fd = -1; | 192 | daemon->socket_fd = -1; |
193 | daemon->port = port; | 193 | daemon->port = port; |
194 | daemon->fio_init = &SPDYF_tls_init; | ||
195 | daemon->fio_deinit = &SPDYF_tls_deinit; | ||
194 | if (NULL == (daemon->certfile = strdup (certfile))) | 196 | if (NULL == (daemon->certfile = strdup (certfile))) |
195 | { | 197 | { |
196 | SPDYF_DEBUG("str"); | 198 | SPDYF_DEBUG("str"); |
@@ -229,7 +231,9 @@ SPDYF_start_daemon_va (uint16_t port, | |||
229 | SPDYF_DEBUG("SPDY_DAEMON_FLAG_ONLY_IPV6 set but IPv4 address provided"); | 231 | SPDYF_DEBUG("SPDY_DAEMON_FLAG_ONLY_IPV6 set but IPv4 address provided"); |
230 | goto free_and_fail; | 232 | goto free_and_fail; |
231 | } | 233 | } |
232 | 234 | ||
235 | addrlen = sizeof (struct sockaddr_in6); | ||
236 | |||
233 | if(NULL == daemon->address) | 237 | if(NULL == daemon->address) |
234 | { | 238 | { |
235 | if (NULL == (servaddr6 = malloc (addrlen))) | 239 | if (NULL == (servaddr6 = malloc (addrlen))) |
@@ -247,12 +251,10 @@ SPDYF_start_daemon_va (uint16_t port, | |||
247 | if(AF_INET6 == daemon->address->sa_family) | 251 | if(AF_INET6 == daemon->address->sa_family) |
248 | { | 252 | { |
249 | afamily = PF_INET6; | 253 | afamily = PF_INET6; |
250 | addrlen = sizeof (struct sockaddr_in6); | ||
251 | } | 254 | } |
252 | else | 255 | else |
253 | { | 256 | { |
254 | afamily = PF_INET; | 257 | afamily = PF_INET; |
255 | addrlen = sizeof (struct sockaddr_in); | ||
256 | } | 258 | } |
257 | #else | 259 | #else |
258 | //handling IPv4 | 260 | //handling IPv4 |
@@ -319,7 +321,7 @@ SPDYF_start_daemon_va (uint16_t port, | |||
319 | goto free_and_fail; | 321 | goto free_and_fail; |
320 | } | 322 | } |
321 | 323 | ||
322 | if(SPDY_YES != SPDYF_tls_init(daemon)) | 324 | if(SPDY_YES != daemon->fio_init(daemon)) |
323 | { | 325 | { |
324 | SPDYF_DEBUG("tls"); | 326 | SPDYF_DEBUG("tls"); |
325 | goto free_and_fail; | 327 | goto free_and_fail; |
@@ -349,7 +351,7 @@ SPDYF_start_daemon_va (uint16_t port, | |||
349 | void | 351 | void |
350 | SPDYF_stop_daemon (struct SPDY_Daemon *daemon) | 352 | SPDYF_stop_daemon (struct SPDY_Daemon *daemon) |
351 | { | 353 | { |
352 | SPDYF_tls_deinit(daemon); | 354 | daemon->fio_deinit(daemon); |
353 | 355 | ||
354 | shutdown (daemon->socket_fd, SHUT_RDWR); | 356 | shutdown (daemon->socket_fd, SHUT_RDWR); |
355 | spdyf_close_all_sessions (daemon); | 357 | spdyf_close_all_sessions (daemon); |
@@ -387,7 +389,7 @@ SPDYF_get_timeout (struct SPDY_Daemon *daemon, | |||
387 | 389 | ||
388 | have_timeout = true; | 390 | have_timeout = true; |
389 | 391 | ||
390 | if (SPDY_YES == SPDYF_tls_is_pending(pos)) | 392 | if (SPDY_YES == pos->fio_is_pending(pos)) |
391 | { | 393 | { |
392 | earliest_deadline = 0; | 394 | earliest_deadline = 0; |
393 | break; | 395 | break; |
@@ -436,7 +438,7 @@ SPDYF_get_fdset (struct SPDY_Daemon *daemon, | |||
436 | || (SPDY_SESSION_STATUS_CLOSING == pos->status) //the session is about to be closed | 438 | || (SPDY_SESSION_STATUS_CLOSING == pos->status) //the session is about to be closed |
437 | || (daemon->session_timeout //timeout passed for the session | 439 | || (daemon->session_timeout //timeout passed for the session |
438 | && (pos->last_activity + daemon->session_timeout < SPDYF_monotonic_time())) | 440 | && (pos->last_activity + daemon->session_timeout < SPDYF_monotonic_time())) |
439 | || (SPDY_YES == SPDYF_tls_is_pending(pos)) //data in TLS' read buffer pending | 441 | || (SPDY_YES == pos->fio_is_pending(pos)) //data in TLS' read buffer pending |
440 | || ((pos->read_buffer_offset - pos->read_buffer_beginning) > 0) // data in lib's read buffer pending | 442 | || ((pos->read_buffer_offset - pos->read_buffer_beginning) > 0) // data in lib's read buffer pending |
441 | ) | 443 | ) |
442 | FD_SET(fd, write_fd_set); | 444 | FD_SET(fd, write_fd_set); |
@@ -487,7 +489,7 @@ SPDYF_run (struct SPDY_Daemon *daemon) | |||
487 | if (ds != -1) | 489 | if (ds != -1) |
488 | { | 490 | { |
489 | //fill the read buffer | 491 | //fill the read buffer |
490 | if (FD_ISSET (ds, &rs) || SPDYF_tls_is_pending(pos)){ | 492 | if (FD_ISSET (ds, &rs) || pos->fio_is_pending(pos)){ |
491 | SPDYF_session_read(pos); | 493 | SPDYF_session_read(pos); |
492 | } | 494 | } |
493 | 495 | ||
diff --git a/src/microspdy/io.h b/src/microspdy/io.h new file mode 100644 index 00000000..b1be69e6 --- /dev/null +++ b/src/microspdy/io.h | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | This file is part of libmicrospdy | ||
3 | Copyright (C) 2013 Andrey Uzunov | ||
4 | |||
5 | This program is free software: you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation, either version 3 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /** | ||
20 | * @file io.h | ||
21 | * @brief Signatures for IO functions. | ||
22 | * @author Andrey Uzunov | ||
23 | */ | ||
24 | |||
25 | #ifndef IO_H | ||
26 | #define IO_H | ||
27 | |||
28 | #include "platform.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Used for return code when reading and writing to the TLS socket. | ||
33 | */ | ||
34 | enum SPDY_IO_ERROR | ||
35 | { | ||
36 | /** | ||
37 | * The connection was closed by the other party. | ||
38 | */ | ||
39 | SPDY_IO_ERROR_CLOSED = 0, | ||
40 | |||
41 | /** | ||
42 | * Any kind of error ocurred. The session has to be closed. | ||
43 | */ | ||
44 | SPDY_IO_ERROR_ERROR = -2, | ||
45 | |||
46 | /** | ||
47 | * The function had to return without processing any data. The whole | ||
48 | * cycle of events has to be called again (SPDY_run) as something | ||
49 | * either has to be written or read or the the syscall was | ||
50 | * interrupted by a signal. | ||
51 | */ | ||
52 | SPDY_IO_ERROR_AGAIN = -3, | ||
53 | }; | ||
54 | |||
55 | |||
56 | /** | ||
57 | * Global initializing. Must be called only once in the program. | ||
58 | * | ||
59 | */ | ||
60 | typedef void | ||
61 | (*SPDYF_IOGlobalInit) (); | ||
62 | |||
63 | |||
64 | /** | ||
65 | * Global deinitializing for the whole program. Should be called | ||
66 | * at the end of the program. | ||
67 | * | ||
68 | */ | ||
69 | typedef void | ||
70 | (*SPDYF_IOGlobalDeinit) (); | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Initializing of io context for a specific daemon. | ||
75 | * Must be called when the daemon starts. | ||
76 | * | ||
77 | * @param daemon SPDY_Daemon for which io will be used. Daemon's | ||
78 | * certificate and key file are used for tls. | ||
79 | * @return SPDY_YES on success or SPDY_NO on error | ||
80 | */ | ||
81 | typedef int | ||
82 | (*SPDYF_IOInit) (struct SPDY_Daemon *daemon); | ||
83 | |||
84 | |||
85 | /** | ||
86 | * Deinitializing io context for a daemon. Should be called | ||
87 | * when the deamon is stopped. | ||
88 | * | ||
89 | * @param daemon SPDY_Daemon which is being stopped | ||
90 | */ | ||
91 | typedef void | ||
92 | (*SPDYF_IODeinit) (struct SPDY_Daemon *daemon); | ||
93 | |||
94 | |||
95 | /** | ||
96 | * Initializing io for a specific connection. Must be called | ||
97 | * after the connection has been accepted. | ||
98 | * | ||
99 | * @param session SPDY_Session whose socket will be used | ||
100 | * @return SPDY_NO if some funcs inside fail. SPDY_YES otherwise | ||
101 | */ | ||
102 | typedef int | ||
103 | (*SPDYF_IONewSession) (struct SPDY_Session *session); | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Deinitializing io for a specific connection. Should be called | ||
108 | * closing session's socket. | ||
109 | * | ||
110 | * @param session SPDY_Session whose socket is used | ||
111 | */ | ||
112 | typedef void | ||
113 | (*SPDYF_IOCloseSession) (struct SPDY_Session *session); | ||
114 | |||
115 | |||
116 | /** | ||
117 | * Reading from session's socket. Reads available data and put it to the | ||
118 | * buffer. | ||
119 | * | ||
120 | * @param session for which data is received | ||
121 | * @param buffer where data from the socket will be written to | ||
122 | * @param size of the buffer | ||
123 | * @return number of bytes (at most size) read from the connection | ||
124 | * 0 if the other party has closed the connection | ||
125 | * SPDY_IO_ERROR code on error | ||
126 | */ | ||
127 | typedef int | ||
128 | (*SPDYF_IORecv) (struct SPDY_Session *session, | ||
129 | void * buffer, | ||
130 | size_t size); | ||
131 | |||
132 | |||
133 | /** | ||
134 | * Writing to session's socket. Writes the data given into the buffer to the | ||
135 | * socket. | ||
136 | * | ||
137 | * @param session whose context is used | ||
138 | * @param buffer from where data will be written to the socket | ||
139 | * @param size number of bytes to be taken from the buffer | ||
140 | * @return number of bytes (at most size) from the buffer that has been | ||
141 | * written to the connection | ||
142 | * 0 if the other party has closed the connection | ||
143 | * SPDY_IO_ERROR code on error | ||
144 | */ | ||
145 | typedef int | ||
146 | (*SPDYF_IOSend) (struct SPDY_Session *session, | ||
147 | const void * buffer, | ||
148 | size_t size); | ||
149 | |||
150 | |||
151 | /** | ||
152 | * Checks if there is data staying in the buffers of the underlying | ||
153 | * system that waits to be read. In case of TLS, this will call | ||
154 | * something like SSL_pending(). | ||
155 | * | ||
156 | * @param session which is checked | ||
157 | * @return SPDY_YES if data is pending or SPDY_NO otherwise | ||
158 | */ | ||
159 | typedef int | ||
160 | (*SPDYF_IOIsPending) (struct SPDY_Session *session); | ||
161 | |||
162 | #endif | ||
diff --git a/src/microspdy/session.c b/src/microspdy/session.c index 6057c05b..5bd68d19 100644 --- a/src/microspdy/session.c +++ b/src/microspdy/session.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include "compression.h" | 30 | #include "compression.h" |
31 | #include "tls.h" | 31 | #include "tls.h" |
32 | #include "stream.h" | 32 | #include "stream.h" |
33 | 33 | ||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Handler for reading the full SYN_STREAM frame after we know that | 36 | * Handler for reading the full SYN_STREAM frame after we know that |
@@ -820,7 +820,7 @@ SPDYF_session_read (struct SPDY_Session *session) | |||
820 | session->last_activity = SPDYF_monotonic_time(); | 820 | session->last_activity = SPDYF_monotonic_time(); |
821 | 821 | ||
822 | //actual read from the TLS socket | 822 | //actual read from the TLS socket |
823 | bytes_read = SPDYF_tls_recv(session, | 823 | bytes_read = session->fio_recv(session, |
824 | session->read_buffer + session->read_buffer_offset, | 824 | session->read_buffer + session->read_buffer_offset, |
825 | session->read_buffer_size - session->read_buffer_offset); | 825 | session->read_buffer_size - session->read_buffer_offset); |
826 | 826 | ||
@@ -952,7 +952,7 @@ SPDYF_session_write (struct SPDY_Session *session, bool only_one_frame) | |||
952 | session->last_activity = SPDYF_monotonic_time(); | 952 | session->last_activity = SPDYF_monotonic_time(); |
953 | 953 | ||
954 | //actual write to the TLS socket | 954 | //actual write to the TLS socket |
955 | bytes_written = SPDYF_tls_send(session, | 955 | bytes_written = session->fio_send(session, |
956 | session->write_buffer + session->write_buffer_beginning, | 956 | session->write_buffer + session->write_buffer_beginning, |
957 | session->write_buffer_offset - session->write_buffer_beginning); | 957 | session->write_buffer_offset - session->write_buffer_beginning); |
958 | 958 | ||
@@ -1016,11 +1016,12 @@ SPDYF_session_write (struct SPDY_Session *session, bool only_one_frame) | |||
1016 | SPDYF_response_queue_destroy(queue_head); | 1016 | SPDYF_response_queue_destroy(queue_head); |
1017 | } | 1017 | } |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | if(SPDY_SESSION_STATUS_FLUSHING == session->status | 1020 | if(SPDY_SESSION_STATUS_FLUSHING == session->status |
1021 | && NULL == session->response_queue_head) | 1021 | && NULL == session->response_queue_head) |
1022 | session->status = SPDY_SESSION_STATUS_CLOSING; | 1022 | session->status = SPDY_SESSION_STATUS_CLOSING; |
1023 | 1023 | ||
1024 | |||
1024 | return i>0 ? SPDY_YES : SPDY_NO; | 1025 | return i>0 ? SPDY_YES : SPDY_NO; |
1025 | } | 1026 | } |
1026 | 1027 | ||
@@ -1237,7 +1238,7 @@ SPDYF_session_close (struct SPDY_Session *session) | |||
1237 | int by_client = session->read_closed ? SPDY_YES : SPDY_NO; | 1238 | int by_client = session->read_closed ? SPDY_YES : SPDY_NO; |
1238 | 1239 | ||
1239 | //shutdown the tls and deinit the tls context | 1240 | //shutdown the tls and deinit the tls context |
1240 | SPDYF_tls_close_session(session); | 1241 | session->fio_close_session(session); |
1241 | shutdown (session->socket_fd, | 1242 | shutdown (session->socket_fd, |
1242 | session->read_closed ? SHUT_WR : SHUT_RDWR); | 1243 | session->read_closed ? SHUT_WR : SHUT_RDWR); |
1243 | session->read_closed = true; | 1244 | session->read_closed = true; |
@@ -1304,9 +1305,15 @@ SPDYF_session_accept(struct SPDY_Daemon *daemon) | |||
1304 | 1305 | ||
1305 | session->daemon = daemon; | 1306 | session->daemon = daemon; |
1306 | session->socket_fd = new_socket_fd; | 1307 | session->socket_fd = new_socket_fd; |
1308 | |||
1309 | session->fio_new_session = &SPDYF_tls_new_session; | ||
1310 | session->fio_close_session = &SPDYF_tls_close_session; | ||
1311 | session->fio_is_pending = &SPDYF_tls_is_pending; | ||
1312 | session->fio_recv = &SPDYF_tls_recv; | ||
1313 | session->fio_send = &SPDYF_tls_send; | ||
1307 | 1314 | ||
1308 | //init TLS context, handshake will be done | 1315 | //init TLS context, handshake will be done |
1309 | if(SPDY_YES != SPDYF_tls_new_session(session)) | 1316 | if(SPDY_YES != session->fio_new_session(session)) |
1310 | { | 1317 | { |
1311 | goto free_and_fail; | 1318 | goto free_and_fail; |
1312 | } | 1319 | } |
@@ -1315,14 +1322,14 @@ SPDYF_session_accept(struct SPDY_Daemon *daemon) | |||
1315 | session->read_buffer_size = SPDYF_BUFFER_SIZE; | 1322 | session->read_buffer_size = SPDYF_BUFFER_SIZE; |
1316 | if (NULL == (session->read_buffer = malloc (session->read_buffer_size))) | 1323 | if (NULL == (session->read_buffer = malloc (session->read_buffer_size))) |
1317 | { | 1324 | { |
1318 | SPDYF_tls_close_session(session); | 1325 | session->fio_close_session(session); |
1319 | goto free_and_fail; | 1326 | goto free_and_fail; |
1320 | } | 1327 | } |
1321 | 1328 | ||
1322 | //address of the client | 1329 | //address of the client |
1323 | if (NULL == (session->addr = malloc (addr_len))) | 1330 | if (NULL == (session->addr = malloc (addr_len))) |
1324 | { | 1331 | { |
1325 | SPDYF_tls_close_session(session); | 1332 | session->fio_close_session(session); |
1326 | goto free_and_fail; | 1333 | goto free_and_fail; |
1327 | } | 1334 | } |
1328 | memcpy (session->addr, addr, addr_len); | 1335 | memcpy (session->addr, addr, addr_len); |
@@ -1333,12 +1340,12 @@ SPDYF_session_accept(struct SPDY_Daemon *daemon) | |||
1333 | //init zlib context for the whole session | 1340 | //init zlib context for the whole session |
1334 | if(SPDY_YES != SPDYF_zlib_deflate_init(&session->zlib_send_stream)) | 1341 | if(SPDY_YES != SPDYF_zlib_deflate_init(&session->zlib_send_stream)) |
1335 | { | 1342 | { |
1336 | SPDYF_tls_close_session(session); | 1343 | session->fio_close_session(session); |
1337 | goto free_and_fail; | 1344 | goto free_and_fail; |
1338 | } | 1345 | } |
1339 | if(SPDY_YES != SPDYF_zlib_inflate_init(&session->zlib_recv_stream)) | 1346 | if(SPDY_YES != SPDYF_zlib_inflate_init(&session->zlib_recv_stream)) |
1340 | { | 1347 | { |
1341 | SPDYF_tls_close_session(session); | 1348 | session->fio_close_session(session); |
1342 | SPDYF_zlib_deflate_end(&session->zlib_send_stream); | 1349 | SPDYF_zlib_deflate_end(&session->zlib_send_stream); |
1343 | goto free_and_fail; | 1350 | goto free_and_fail; |
1344 | } | 1351 | } |
diff --git a/src/microspdy/structures.h b/src/microspdy/structures.h index 603449f1..529bc929 100644 --- a/src/microspdy/structures.h +++ b/src/microspdy/structures.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "platform.h" | 29 | #include "platform.h" |
30 | #include "microspdy.h" | 30 | #include "microspdy.h" |
31 | #include "tls.h" | 31 | #include "tls.h" |
32 | #include "io.h" | ||
32 | 33 | ||
33 | 34 | ||
34 | /** | 35 | /** |
@@ -617,10 +618,10 @@ struct SPDY_Session | |||
617 | struct SPDYF_Stream *streams_tail; | 618 | struct SPDYF_Stream *streams_tail; |
618 | 619 | ||
619 | /** | 620 | /** |
620 | * Unique TLS context for the session. Initialized on each creation | 621 | * Unique IO context for the session. Initialized on each creation |
621 | * (actually when the TCP connection is established). | 622 | * (actually when the TCP connection is established). |
622 | */ | 623 | */ |
623 | SPDYF_TLS_SESSION_CONTEXT *tls_context; | 624 | void *io_context; |
624 | 625 | ||
625 | /** | 626 | /** |
626 | * Head of doubly-linked list of the responses. | 627 | * Head of doubly-linked list of the responses. |
@@ -659,6 +660,31 @@ struct SPDY_Session | |||
659 | void *user_cls; | 660 | void *user_cls; |
660 | 661 | ||
661 | /** | 662 | /** |
663 | * Function to initialize the IO context for a new session. | ||
664 | */ | ||
665 | SPDYF_IONewSession fio_new_session; | ||
666 | |||
667 | /** | ||
668 | * Function to deinitialize the IO context for a session. | ||
669 | */ | ||
670 | SPDYF_IOCloseSession fio_close_session; | ||
671 | |||
672 | /** | ||
673 | * Function to read data from socket. | ||
674 | */ | ||
675 | SPDYF_IORecv fio_recv; | ||
676 | |||
677 | /** | ||
678 | * Function to write data to socket. | ||
679 | */ | ||
680 | SPDYF_IOSend fio_send; | ||
681 | |||
682 | /** | ||
683 | * Function to check for pending data in IO buffers. | ||
684 | */ | ||
685 | SPDYF_IOIsPending fio_is_pending; | ||
686 | |||
687 | /** | ||
662 | * Number of bytes that the lib must ignore immediately after they | 688 | * Number of bytes that the lib must ignore immediately after they |
663 | * are read from the TLS socket without adding them to the read buf. | 689 | * are read from the TLS socket without adding them to the read buf. |
664 | * This is needed, for instance, when receiving frame bigger than | 690 | * This is needed, for instance, when receiving frame bigger than |
@@ -805,9 +831,9 @@ struct SPDY_Daemon | |||
805 | struct SPDY_Session *cleanup_tail; | 831 | struct SPDY_Session *cleanup_tail; |
806 | 832 | ||
807 | /** | 833 | /** |
808 | * Unique TLS context for the daemon. Initialized on daemon start. | 834 | * Unique IO context for the daemon. Initialized on daemon start. |
809 | */ | 835 | */ |
810 | SPDYF_TLS_DAEMON_CONTEXT *tls_context; | 836 | void *io_context; |
811 | 837 | ||
812 | /** | 838 | /** |
813 | * Certificate file of the server. File path is kept here. | 839 | * Certificate file of the server. File path is kept here. |
@@ -864,6 +890,16 @@ struct SPDY_Daemon | |||
864 | void *fcls; | 890 | void *fcls; |
865 | 891 | ||
866 | /** | 892 | /** |
893 | * Function to initialize the IO context for the daemon. | ||
894 | */ | ||
895 | SPDYF_IOInit fio_init; | ||
896 | |||
897 | /** | ||
898 | * Function to deinitialize the IO context for the daemon. | ||
899 | */ | ||
900 | SPDYF_IODeinit fio_deinit; | ||
901 | |||
902 | /** | ||
867 | * After how many seconds of inactivity should | 903 | * After how many seconds of inactivity should |
868 | * connections time out? Zero for no timeout. | 904 | * connections time out? Zero for no timeout. |
869 | */ | 905 | */ |
diff --git a/src/microspdy/tls.c b/src/microspdy/tls.c index 521f8f24..57fd357d 100644 --- a/src/microspdy/tls.c +++ b/src/microspdy/tls.c | |||
@@ -78,37 +78,37 @@ int | |||
78 | SPDYF_tls_init(struct SPDY_Daemon *daemon) | 78 | SPDYF_tls_init(struct SPDY_Daemon *daemon) |
79 | { | 79 | { |
80 | //create ssl context. TLSv1 used | 80 | //create ssl context. TLSv1 used |
81 | if(NULL == (daemon->tls_context = SSL_CTX_new(TLSv1_server_method()))) | 81 | if(NULL == (daemon->io_context = SSL_CTX_new(TLSv1_server_method()))) |
82 | { | 82 | { |
83 | SPDYF_DEBUG("Couldn't create ssl context"); | 83 | SPDYF_DEBUG("Couldn't create ssl context"); |
84 | return SPDY_NO; | 84 | return SPDY_NO; |
85 | } | 85 | } |
86 | //set options for tls | 86 | //set options for tls |
87 | //TODO DH is not enabled for easier debugging | 87 | //TODO DH is not enabled for easier debugging |
88 | //SSL_CTX_set_options(daemon->tls_context, SSL_OP_SINGLE_DH_USE); | 88 | //SSL_CTX_set_options(daemon->io_context, SSL_OP_SINGLE_DH_USE); |
89 | 89 | ||
90 | //TODO here session tickets are disabled for easier debuging with | 90 | //TODO here session tickets are disabled for easier debuging with |
91 | //wireshark when using Chrome | 91 | //wireshark when using Chrome |
92 | //SSL_OP_NO_COMPRESSION disables TLS compression to avoid CRIME attack | 92 | //SSL_OP_NO_COMPRESSION disables TLS compression to avoid CRIME attack |
93 | SSL_CTX_set_options(daemon->tls_context, SSL_OP_NO_TICKET | SSL_OP_NO_COMPRESSION); | 93 | SSL_CTX_set_options(daemon->io_context, SSL_OP_NO_TICKET | SSL_OP_NO_COMPRESSION); |
94 | if(1 != SSL_CTX_use_certificate_file(daemon->tls_context, daemon->certfile , SSL_FILETYPE_PEM)) | 94 | if(1 != SSL_CTX_use_certificate_file(daemon->io_context, daemon->certfile , SSL_FILETYPE_PEM)) |
95 | { | 95 | { |
96 | SPDYF_DEBUG("Couldn't load the cert file"); | 96 | SPDYF_DEBUG("Couldn't load the cert file"); |
97 | SSL_CTX_free(daemon->tls_context); | 97 | SSL_CTX_free(daemon->io_context); |
98 | return SPDY_NO; | 98 | return SPDY_NO; |
99 | } | 99 | } |
100 | if(1 != SSL_CTX_use_PrivateKey_file(daemon->tls_context, daemon->keyfile, SSL_FILETYPE_PEM)) | 100 | if(1 != SSL_CTX_use_PrivateKey_file(daemon->io_context, daemon->keyfile, SSL_FILETYPE_PEM)) |
101 | { | 101 | { |
102 | SPDYF_DEBUG("Couldn't load the name file"); | 102 | SPDYF_DEBUG("Couldn't load the name file"); |
103 | SSL_CTX_free(daemon->tls_context); | 103 | SSL_CTX_free(daemon->io_context); |
104 | return SPDY_NO; | 104 | return SPDY_NO; |
105 | } | 105 | } |
106 | SSL_CTX_set_next_protos_advertised_cb(daemon->tls_context, &spdyf_next_protos_advertised_cb, NULL); | 106 | SSL_CTX_set_next_protos_advertised_cb(daemon->io_context, &spdyf_next_protos_advertised_cb, NULL); |
107 | //TODO only RC4-SHA is used to make it easy to debug with wireshark | 107 | //TODO only RC4-SHA is used to make it easy to debug with wireshark |
108 | if (1 != SSL_CTX_set_cipher_list(daemon->tls_context, "RC4-SHA")) | 108 | if (1 != SSL_CTX_set_cipher_list(daemon->io_context, "RC4-SHA")) |
109 | { | 109 | { |
110 | SPDYF_DEBUG("Couldn't set the desired cipher list"); | 110 | SPDYF_DEBUG("Couldn't set the desired cipher list"); |
111 | SSL_CTX_free(daemon->tls_context); | 111 | SSL_CTX_free(daemon->io_context); |
112 | return SPDY_NO; | 112 | return SPDY_NO; |
113 | } | 113 | } |
114 | 114 | ||
@@ -119,7 +119,7 @@ SPDYF_tls_init(struct SPDY_Daemon *daemon) | |||
119 | void | 119 | void |
120 | SPDYF_tls_deinit(struct SPDY_Daemon *daemon) | 120 | SPDYF_tls_deinit(struct SPDY_Daemon *daemon) |
121 | { | 121 | { |
122 | SSL_CTX_free(daemon->tls_context); | 122 | SSL_CTX_free(daemon->io_context); |
123 | } | 123 | } |
124 | 124 | ||
125 | 125 | ||
@@ -128,30 +128,30 @@ SPDYF_tls_new_session(struct SPDY_Session *session) | |||
128 | { | 128 | { |
129 | int ret; | 129 | int ret; |
130 | 130 | ||
131 | if(NULL == (session->tls_context = SSL_new(session->daemon->tls_context))) | 131 | if(NULL == (session->io_context = SSL_new(session->daemon->io_context))) |
132 | { | 132 | { |
133 | SPDYF_DEBUG("Couldn't create ssl structure"); | 133 | SPDYF_DEBUG("Couldn't create ssl structure"); |
134 | return SPDY_NO; | 134 | return SPDY_NO; |
135 | } | 135 | } |
136 | if(1 != (ret = SSL_set_fd(session->tls_context, session->socket_fd))) | 136 | if(1 != (ret = SSL_set_fd(session->io_context, session->socket_fd))) |
137 | { | 137 | { |
138 | SPDYF_DEBUG("SSL_set_fd %i",ret); | 138 | SPDYF_DEBUG("SSL_set_fd %i",ret); |
139 | SSL_free(session->tls_context); | 139 | SSL_free(session->io_context); |
140 | session->tls_context = NULL; | 140 | session->io_context = NULL; |
141 | return SPDY_NO; | 141 | return SPDY_NO; |
142 | } | 142 | } |
143 | 143 | ||
144 | //for non-blocking I/O SSL_accept may return -1 | 144 | //for non-blocking I/O SSL_accept may return -1 |
145 | //and this function won't work | 145 | //and this function won't work |
146 | if(1 != (ret = SSL_accept(session->tls_context))) | 146 | if(1 != (ret = SSL_accept(session->io_context))) |
147 | { | 147 | { |
148 | SPDYF_DEBUG("SSL_accept %i",ret); | 148 | SPDYF_DEBUG("SSL_accept %i",ret); |
149 | SSL_free(session->tls_context); | 149 | SSL_free(session->io_context); |
150 | session->tls_context = NULL; | 150 | session->io_context = NULL; |
151 | return SPDY_NO; | 151 | return SPDY_NO; |
152 | } | 152 | } |
153 | /* alternatively | 153 | /* alternatively |
154 | SSL_set_accept_state(session->tls_context); | 154 | SSL_set_accept_state(session->io_context); |
155 | * may be called and then the negotiation will be done on reading | 155 | * may be called and then the negotiation will be done on reading |
156 | */ | 156 | */ |
157 | 157 | ||
@@ -167,9 +167,9 @@ SPDYF_tls_close_session(struct SPDY_Session *session) | |||
167 | //the TLS session. The lib just sends it and will close the socket | 167 | //the TLS session. The lib just sends it and will close the socket |
168 | //after that because the browsers don't seem to care much about | 168 | //after that because the browsers don't seem to care much about |
169 | //"close notify" | 169 | //"close notify" |
170 | SSL_shutdown(session->tls_context); | 170 | SSL_shutdown(session->io_context); |
171 | 171 | ||
172 | SSL_free(session->tls_context); | 172 | SSL_free(session->io_context); |
173 | } | 173 | } |
174 | 174 | ||
175 | 175 | ||
@@ -179,13 +179,13 @@ SPDYF_tls_recv(struct SPDY_Session *session, | |||
179 | size_t size) | 179 | size_t size) |
180 | { | 180 | { |
181 | int ret; | 181 | int ret; |
182 | int n = SSL_read(session->tls_context, | 182 | int n = SSL_read(session->io_context, |
183 | buffer, | 183 | buffer, |
184 | size); | 184 | size); |
185 | //if(n > 0) SPDYF_DEBUG("recvd: %i",n); | 185 | //if(n > 0) SPDYF_DEBUG("recvd: %i",n); |
186 | if (n <= 0) | 186 | if (n <= 0) |
187 | { | 187 | { |
188 | ret = SSL_get_error(session->tls_context, n); | 188 | ret = SSL_get_error(session->io_context, n); |
189 | switch(ret) | 189 | switch(ret) |
190 | { | 190 | { |
191 | case SSL_ERROR_ZERO_RETURN: | 191 | case SSL_ERROR_ZERO_RETURN: |
@@ -215,13 +215,13 @@ SPDYF_tls_send(struct SPDY_Session *session, | |||
215 | { | 215 | { |
216 | int ret; | 216 | int ret; |
217 | 217 | ||
218 | int n = SSL_write(session->tls_context, | 218 | int n = SSL_write(session->io_context, |
219 | buffer, | 219 | buffer, |
220 | size); | 220 | size); |
221 | //if(n > 0) SPDYF_DEBUG("sent: %i",n); | 221 | //if(n > 0) SPDYF_DEBUG("sent: %i",n); |
222 | if (n <= 0) | 222 | if (n <= 0) |
223 | { | 223 | { |
224 | ret = SSL_get_error(session->tls_context, n); | 224 | ret = SSL_get_error(session->io_context, n); |
225 | switch(ret) | 225 | switch(ret) |
226 | { | 226 | { |
227 | case SSL_ERROR_ZERO_RETURN: | 227 | case SSL_ERROR_ZERO_RETURN: |
@@ -251,5 +251,5 @@ SPDYF_tls_is_pending(struct SPDY_Session *session) | |||
251 | * BUGS | 251 | * BUGS |
252 | SSL_pending() takes into account only bytes from the TLS/SSL record that is currently being processed (if any). If the SSL object's read_ahead flag is set, additional protocol bytes may have been read containing more TLS/SSL records; these are ignored by SSL_pending(). | 252 | SSL_pending() takes into account only bytes from the TLS/SSL record that is currently being processed (if any). If the SSL object's read_ahead flag is set, additional protocol bytes may have been read containing more TLS/SSL records; these are ignored by SSL_pending(). |
253 | */ | 253 | */ |
254 | return SSL_pending(session->tls_context) > 0 ? SPDY_YES : SPDY_NO; | 254 | return SSL_pending(session->io_context) > 0 ? SPDY_YES : SPDY_NO; |
255 | } | 255 | } |
diff --git a/src/microspdy/tls.h b/src/microspdy/tls.h index 5fb4371a..932d93b9 100644 --- a/src/microspdy/tls.h +++ b/src/microspdy/tls.h | |||
@@ -34,8 +34,8 @@ | |||
34 | 34 | ||
35 | /* macros used in other files instead of types. | 35 | /* macros used in other files instead of types. |
36 | * useful in case of changing openssl to something else */ | 36 | * useful in case of changing openssl to something else */ |
37 | #define SPDYF_TLS_SESSION_CONTEXT SSL | 37 | //#define SPDYF_TLS_SESSION_CONTEXT SSL |
38 | #define SPDYF_TLS_DAEMON_CONTEXT SSL_CTX | 38 | //#define SPDYF_TLS_DAEMON_CONTEXT SSL_CTX |
39 | 39 | ||
40 | 40 | ||
41 | /** | 41 | /** |