diff options
Diffstat (limited to 'src/microspdy/structures.h')
-rw-r--r-- | src/microspdy/structures.h | 1128 |
1 files changed, 1128 insertions, 0 deletions
diff --git a/src/microspdy/structures.h b/src/microspdy/structures.h new file mode 100644 index 00000000..5fb91889 --- /dev/null +++ b/src/microspdy/structures.h | |||
@@ -0,0 +1,1128 @@ | |||
1 | /* | ||
2 | This file is part of libmicrospdy | ||
3 | Copyright (C) 2012 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 structures.h | ||
21 | * @brief internal and public structures -- most of the structs used by | ||
22 | * the library are defined here | ||
23 | * @author Andrey Uzunov | ||
24 | */ | ||
25 | |||
26 | #ifndef STRUCTURES_H | ||
27 | #define STRUCTURES_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "microspdy.h" | ||
31 | #include "tls.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * All possible SPDY control frame types. The number is used in the header | ||
36 | * of the control frame. | ||
37 | */ | ||
38 | enum SPDY_CONTROL_FRAME_TYPES | ||
39 | { | ||
40 | /** | ||
41 | * The SYN_STREAM control frame allows the sender to asynchronously | ||
42 | * create a stream between the endpoints. | ||
43 | */ | ||
44 | SPDY_CONTROL_FRAME_TYPES_SYN_STREAM = 1, | ||
45 | |||
46 | /** | ||
47 | * SYN_REPLY indicates the acceptance of a stream creation by | ||
48 | * the recipient of a SYN_STREAM frame. | ||
49 | */ | ||
50 | SPDY_CONTROL_FRAME_TYPES_SYN_REPLY = 2, | ||
51 | |||
52 | /** | ||
53 | * The RST_STREAM frame allows for abnormal termination of a stream. | ||
54 | * When sent by the creator of a stream, it indicates the creator | ||
55 | * wishes to cancel the stream. When sent by the recipient of a | ||
56 | * stream, it indicates an error or that the recipient did not want | ||
57 | * to accept the stream, so the stream should be closed. | ||
58 | */ | ||
59 | SPDY_CONTROL_FRAME_TYPES_RST_STREAM = 3, | ||
60 | |||
61 | /** | ||
62 | * A SETTINGS frame contains a set of id/value pairs for | ||
63 | * communicating configuration data about how the two endpoints may | ||
64 | * communicate. SETTINGS frames can be sent at any time by either | ||
65 | * endpoint, are optionally sent, and are fully asynchronous. When | ||
66 | * the server is the sender, the sender can request that | ||
67 | * configuration data be persisted by the client across SPDY | ||
68 | * sessions and returned to the server in future communications. | ||
69 | */ | ||
70 | SPDY_CONTROL_FRAME_TYPES_SETTINGS = 4, | ||
71 | |||
72 | /** | ||
73 | * The PING control frame is a mechanism for measuring a minimal | ||
74 | * round-trip time from the sender. It can be sent from the client | ||
75 | * or the server. Recipients of a PING frame should send an | ||
76 | * identical frame to the sender as soon as possible (if there is | ||
77 | * other pending data waiting to be sent, PING should take highest | ||
78 | * priority). Each ping sent by a sender should use a unique ID. | ||
79 | */ | ||
80 | SPDY_CONTROL_FRAME_TYPES_PING = 6, | ||
81 | |||
82 | /** | ||
83 | * The GOAWAY control frame is a mechanism to tell the remote side | ||
84 | * of the connection to stop creating streams on this session. It | ||
85 | * can be sent from the client or the server. | ||
86 | */ | ||
87 | SPDY_CONTROL_FRAME_TYPES_GOAWAY = 7, | ||
88 | |||
89 | /** | ||
90 | * The HEADERS frame augments a stream with additional headers. It | ||
91 | * may be optionally sent on an existing stream at any time. | ||
92 | * Specific application of the headers in this frame is | ||
93 | * application-dependent. The name/value header block within this | ||
94 | * frame is compressed. | ||
95 | */ | ||
96 | SPDY_CONTROL_FRAME_TYPES_HEADERS = 8, | ||
97 | |||
98 | /** | ||
99 | * The WINDOW_UPDATE control frame is used to implement per stream | ||
100 | * flow control in SPDY. Flow control in SPDY is per hop, that is, | ||
101 | * only between the two endpoints of a SPDY connection. If there are | ||
102 | * one or more intermediaries between the client and the origin | ||
103 | * server, flow control signals are not explicitly forwarded by the | ||
104 | * intermediaries. | ||
105 | */ | ||
106 | SPDY_CONTROL_FRAME_TYPES_WINDOW_UPDATE = 9, | ||
107 | |||
108 | /** | ||
109 | * The CREDENTIAL control frame is used by the client to send | ||
110 | * additional client certificates to the server. A SPDY client may | ||
111 | * decide to send requests for resources from different origins on | ||
112 | * the same SPDY session if it decides that that server handles both | ||
113 | * origins. For example if the IP address associated with both | ||
114 | * hostnames matches and the SSL server certificate presented in the | ||
115 | * initial handshake is valid for both hostnames. However, because | ||
116 | * the SSL connection can contain at most one client certificate, | ||
117 | * the client needs a mechanism to send additional client | ||
118 | * certificates to the server. | ||
119 | */ | ||
120 | SPDY_CONTROL_FRAME_TYPES_CREDENTIAL = 11 | ||
121 | }; | ||
122 | |||
123 | |||
124 | /** | ||
125 | * SPDY_SESSION_STATUS is used to show the current receiving state | ||
126 | * of each session, i.e. what is expected to come now, and how it should | ||
127 | * be handled. | ||
128 | */ | ||
129 | enum SPDY_SESSION_STATUS | ||
130 | { | ||
131 | /** | ||
132 | * The session is in closing state, do not read read anything from | ||
133 | * it. Do not write anything to it. | ||
134 | */ | ||
135 | SPDY_SESSION_STATUS_CLOSING = 0, | ||
136 | |||
137 | /** | ||
138 | * Wait for new SPDY frame to come. | ||
139 | */ | ||
140 | SPDY_SESSION_STATUS_WAIT_FOR_HEADER = 1, | ||
141 | |||
142 | /** | ||
143 | * The standard 8 byte header of the SPDY frame was received and | ||
144 | * handled. Wait for the specific (sub)headers according to the | ||
145 | * frame type. | ||
146 | */ | ||
147 | SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER = 2, | ||
148 | |||
149 | /** | ||
150 | * The specific (sub)headers were received and handled. Wait for the | ||
151 | * "body", i.e. wait for the name/value pairs compressed by zlib. | ||
152 | */ | ||
153 | SPDY_SESSION_STATUS_WAIT_FOR_BODY = 3, | ||
154 | |||
155 | /** | ||
156 | * Ignore all the bytes read from the socket, e.g. larger frames. | ||
157 | */ | ||
158 | SPDY_SESSION_STATUS_IGNORE_BYTES= 4, | ||
159 | |||
160 | /** | ||
161 | * The session is in pre-closing state, do not read read anything | ||
162 | * from it. In this state the output queue will be written to the | ||
163 | * socket. | ||
164 | */ | ||
165 | SPDY_SESSION_STATUS_FLUSHING = 5, | ||
166 | }; | ||
167 | |||
168 | |||
169 | /** | ||
170 | * Specific flags for the SYN_STREAM control frame. | ||
171 | */ | ||
172 | enum SPDY_SYN_STREAM_FLAG | ||
173 | { | ||
174 | /** | ||
175 | * The sender won't send any more frames on this stream. | ||
176 | */ | ||
177 | SPDY_SYN_STREAM_FLAG_FIN = 1, | ||
178 | |||
179 | /** | ||
180 | * The sender creates this stream as unidirectional. | ||
181 | */ | ||
182 | SPDY_SYN_STREAM_FLAG_UNIDIRECTIONAL = 2 | ||
183 | }; | ||
184 | |||
185 | |||
186 | /** | ||
187 | * Specific flags for the SYN_REPLY control frame. | ||
188 | */ | ||
189 | enum SPDY_SYN_REPLY_FLAG | ||
190 | { | ||
191 | /** | ||
192 | * The sender won't send any more frames on this stream. | ||
193 | */ | ||
194 | SPDY_SYN_REPLY_FLAG_FIN = 1 | ||
195 | }; | ||
196 | |||
197 | |||
198 | /** | ||
199 | * Specific flags for the data frame. | ||
200 | */ | ||
201 | enum SPDY_DATA_FLAG | ||
202 | { | ||
203 | /** | ||
204 | * The sender won't send any more frames on this stream. | ||
205 | */ | ||
206 | SPDY_DATA_FLAG_FIN = 1, | ||
207 | |||
208 | /** | ||
209 | * The data in the frame is compressed. | ||
210 | * This flag appears only in the draft on ietf.org but not on | ||
211 | * chromium.org. | ||
212 | */ | ||
213 | SPDY_DATA_FLAG_COMPRESS = 2 | ||
214 | }; | ||
215 | |||
216 | /** | ||
217 | * Status code within RST_STREAM control frame. | ||
218 | */ | ||
219 | enum SPDY_RST_STREAM_STATUS | ||
220 | { | ||
221 | /** | ||
222 | * This is a generic error, and should only be used if a more | ||
223 | * specific error is not available. | ||
224 | */ | ||
225 | SPDY_RST_STREAM_STATUS_PROTOCOL_ERROR = 1, | ||
226 | |||
227 | /** | ||
228 | * This is returned when a frame is received for a stream which is | ||
229 | * not active. | ||
230 | */ | ||
231 | SPDY_RST_STREAM_STATUS_INVALID_STREAM = 2, | ||
232 | |||
233 | /** | ||
234 | * Indicates that the stream was refused before any processing has | ||
235 | * been done on the stream. | ||
236 | */ | ||
237 | SPDY_RST_STREAM_STATUS_REFUSED_STREAM = 3, | ||
238 | |||
239 | /** | ||
240 | * Indicates that the recipient of a stream does not support the | ||
241 | * SPDY version requested. | ||
242 | */ | ||
243 | SPDY_RST_STREAM_STATUS_UNSUPPORTED_VERSION = 4, | ||
244 | |||
245 | /** | ||
246 | * Used by the creator of a stream to indicate that the stream is | ||
247 | * no longer needed. | ||
248 | */ | ||
249 | SPDY_RST_STREAM_STATUS_CANCEL = 5, | ||
250 | |||
251 | /** | ||
252 | * This is a generic error which can be used when the implementation | ||
253 | * has internally failed, not due to anything in the protocol. | ||
254 | */ | ||
255 | SPDY_RST_STREAM_STATUS_INTERNAL_ERROR = 6, | ||
256 | |||
257 | /** | ||
258 | * The endpoint detected that its peer violated the flow control | ||
259 | * protocol. | ||
260 | */ | ||
261 | SPDY_RST_STREAM_STATUS_FLOW_CONTROL_ERROR = 7, | ||
262 | |||
263 | /** | ||
264 | * The endpoint received a SYN_REPLY for a stream already open. | ||
265 | */ | ||
266 | SPDY_RST_STREAM_STATUS_STREAM_IN_USE = 8, | ||
267 | |||
268 | /** | ||
269 | * The endpoint received a data or SYN_REPLY frame for a stream | ||
270 | * which is half closed. | ||
271 | */ | ||
272 | SPDY_RST_STREAM_STATUS_STREAM_ALREADY_CLOSED = 9, | ||
273 | |||
274 | /** | ||
275 | * The server received a request for a resource whose origin does | ||
276 | * not have valid credentials in the client certificate vector. | ||
277 | */ | ||
278 | SPDY_RST_STREAM_STATUS_INVALID_CREDENTIALS = 10, | ||
279 | |||
280 | /** | ||
281 | * The endpoint received a frame which this implementation could not | ||
282 | * support. If FRAME_TOO_LARGE is sent for a SYN_STREAM, HEADERS, | ||
283 | * or SYN_REPLY frame without fully processing the compressed | ||
284 | * portion of those frames, then the compression state will be | ||
285 | * out-of-sync with the other endpoint. In this case, senders of | ||
286 | * FRAME_TOO_LARGE MUST close the session. | ||
287 | */ | ||
288 | SPDY_RST_STREAM_STATUS_FRAME_TOO_LARGE = 11 | ||
289 | }; | ||
290 | |||
291 | |||
292 | /** | ||
293 | * Status code within GOAWAY control frame. | ||
294 | */ | ||
295 | enum SPDY_GOAWAY_STATUS | ||
296 | { | ||
297 | /** | ||
298 | * This is a normal session teardown. | ||
299 | */ | ||
300 | SPDY_GOAWAY_STATUS_OK = 0, | ||
301 | |||
302 | /** | ||
303 | * This is a generic error, and should only be used if a more | ||
304 | * specific error is not available. | ||
305 | */ | ||
306 | SPDY_GOAWAY_STATUS_PROTOCOL_ERROR = 1, | ||
307 | |||
308 | /** | ||
309 | * This is a generic error which can be used when the implementation | ||
310 | * has internally failed, not due to anything in the protocol. | ||
311 | */ | ||
312 | SPDY_GOAWAY_STATUS_INTERNAL_ERROR = 11 | ||
313 | }; | ||
314 | |||
315 | |||
316 | struct SPDYF_Stream; | ||
317 | |||
318 | struct SPDYF_Response_Queue; | ||
319 | |||
320 | /** | ||
321 | * Callback for new stream. To be used in the application layer of the | ||
322 | * lib. | ||
323 | * | ||
324 | * @param cls | ||
325 | * @param stream the new stream | ||
326 | * @return SPDY_YES on success, | ||
327 | * SPDY_NO if error occurs | ||
328 | */ | ||
329 | typedef int | ||
330 | (*SPDYF_NewStreamCallback) (void *cls, | ||
331 | struct SPDYF_Stream * stream); | ||
332 | |||
333 | |||
334 | /** | ||
335 | * Callback to be called when the response queue object was handled and | ||
336 | * the data was already sent. | ||
337 | * | ||
338 | * @param cls | ||
339 | * @param response_queue the SPDYF_Response_Queue structure which will | ||
340 | * be cleaned very soon | ||
341 | * @param status shows if actually the response was sent or it was | ||
342 | * discarded by the lib for any reason (e.g., closing session, | ||
343 | * closing stream, stopping daemon, etc.). It is possible that | ||
344 | * status indicates an error but part of the response (in one | ||
345 | * or several frames) was sent to the client. | ||
346 | */ | ||
347 | typedef void | ||
348 | (*SPDYF_ResponseQueueResultCallback) (void * cls, | ||
349 | struct SPDYF_Response_Queue *response_queue, | ||
350 | enum SPDY_RESPONSE_RESULT status); | ||
351 | |||
352 | |||
353 | /** | ||
354 | * Representation of the control frame's headers, which are common for | ||
355 | * all types. | ||
356 | */ | ||
357 | struct __attribute__((__packed__)) SPDYF_Control_Frame | ||
358 | { | ||
359 | uint16_t version : 15; | ||
360 | uint16_t control_bit : 1; /* always 1 for control frames */ | ||
361 | uint16_t type; | ||
362 | uint32_t flags : 8; | ||
363 | uint32_t length : 24; | ||
364 | }; | ||
365 | |||
366 | |||
367 | /** | ||
368 | * Representation of the data frame's headers. | ||
369 | */ | ||
370 | struct __attribute__((__packed__)) SPDYF_Data_Frame | ||
371 | { | ||
372 | uint32_t stream_id : 31; | ||
373 | uint32_t control_bit : 1; /* always 0 for data frames */ | ||
374 | uint32_t flags : 8; | ||
375 | uint32_t length : 24; | ||
376 | }; | ||
377 | |||
378 | |||
379 | /** | ||
380 | * Queue of the responses, to be handled (e.g. compressed) and sent later. | ||
381 | */ | ||
382 | struct SPDYF_Response_Queue | ||
383 | { | ||
384 | /** | ||
385 | * This is a doubly-linked list. | ||
386 | */ | ||
387 | struct SPDYF_Response_Queue *next; | ||
388 | |||
389 | /** | ||
390 | * This is a doubly-linked list. | ||
391 | */ | ||
392 | struct SPDYF_Response_Queue *prev; | ||
393 | |||
394 | /** | ||
395 | * Stream (Request) for which is the response. | ||
396 | */ | ||
397 | struct SPDYF_Stream *stream; | ||
398 | |||
399 | /** | ||
400 | * Response structure with all the data (uncompressed headers) to be sent. | ||
401 | */ | ||
402 | struct SPDY_Response *response; | ||
403 | |||
404 | /** | ||
405 | * Control frame. The length field should be set after compressing | ||
406 | * the headers! | ||
407 | */ | ||
408 | struct SPDYF_Control_Frame *control_frame; | ||
409 | |||
410 | /** | ||
411 | * Data frame. The length field should be set after compressing | ||
412 | * the body! | ||
413 | */ | ||
414 | struct SPDYF_Data_Frame *data_frame; | ||
415 | |||
416 | /** | ||
417 | * Data to be sent: name/value pairs in control frames or body in data frames. | ||
418 | */ | ||
419 | void *data; | ||
420 | |||
421 | /** | ||
422 | * Specific handler for different frame types. | ||
423 | */ | ||
424 | int (* process_response_handler)(struct SPDY_Session *session); | ||
425 | |||
426 | /** | ||
427 | * Callback to be called when the last bytes from the response was sent | ||
428 | * to the client. | ||
429 | */ | ||
430 | SPDYF_ResponseQueueResultCallback frqcb; | ||
431 | |||
432 | /** | ||
433 | * Closure for frqcb. | ||
434 | */ | ||
435 | void *frqcb_cls; | ||
436 | |||
437 | /** | ||
438 | * Callback to be used by the application layer. | ||
439 | */ | ||
440 | SPDY_ResponseResultCallback rrcb; | ||
441 | |||
442 | /** | ||
443 | * Closure for rcb. | ||
444 | */ | ||
445 | void *rrcb_cls; | ||
446 | |||
447 | /** | ||
448 | * Data size. | ||
449 | */ | ||
450 | size_t data_size; | ||
451 | |||
452 | /** | ||
453 | * True if data frame should be sent. False if control frame should | ||
454 | * be sent. | ||
455 | */ | ||
456 | bool is_data; | ||
457 | }; | ||
458 | |||
459 | |||
460 | |||
461 | /** | ||
462 | * Collection of HTTP headers used in requests and responses. | ||
463 | */ | ||
464 | struct SPDY_NameValue | ||
465 | { | ||
466 | /** | ||
467 | * This is a doubly-linked list. | ||
468 | */ | ||
469 | struct SPDY_NameValue *next; | ||
470 | |||
471 | /** | ||
472 | * This is a doubly-linked list. | ||
473 | */ | ||
474 | struct SPDY_NameValue *prev; | ||
475 | |||
476 | /** | ||
477 | * Null terminated string for name. | ||
478 | */ | ||
479 | char *name; | ||
480 | |||
481 | /** | ||
482 | * Array of Null terminated strings for value. num_values is the | ||
483 | * length of the array. | ||
484 | */ | ||
485 | char **value; | ||
486 | |||
487 | /** | ||
488 | * Number of values, this is >= 0. | ||
489 | */ | ||
490 | uint num_values; | ||
491 | }; | ||
492 | |||
493 | |||
494 | /** | ||
495 | * Represents a SPDY stream | ||
496 | */ | ||
497 | struct SPDYF_Stream | ||
498 | { | ||
499 | /** | ||
500 | * This is a doubly-linked list. | ||
501 | */ | ||
502 | struct SPDYF_Stream *next; | ||
503 | |||
504 | /** | ||
505 | * This is a doubly-linked list. | ||
506 | */ | ||
507 | struct SPDYF_Stream *prev; | ||
508 | |||
509 | /** | ||
510 | * Reference to the SPDY_Session struct. | ||
511 | */ | ||
512 | struct SPDY_Session *session; | ||
513 | |||
514 | /** | ||
515 | * Name value pairs, sent within the frame which created the stream. | ||
516 | */ | ||
517 | struct SPDY_NameValue *headers; | ||
518 | |||
519 | /** | ||
520 | * This stream's ID. | ||
521 | */ | ||
522 | uint32_t stream_id; | ||
523 | |||
524 | /** | ||
525 | * Stream to which this one is associated. | ||
526 | */ | ||
527 | uint32_t assoc_stream_id; | ||
528 | |||
529 | /** | ||
530 | * Stream priority. 0 is the highest, 7 is the lowest. | ||
531 | */ | ||
532 | uint8_t priority; | ||
533 | |||
534 | /** | ||
535 | * Integer specifying the index in the server's CREDENTIAL vector of | ||
536 | * the client certificate to be used for this request The value 0 | ||
537 | * means no client certificate should be associated with this stream. | ||
538 | */ | ||
539 | uint8_t slot; | ||
540 | |||
541 | /** | ||
542 | * If initially the stream was created as unidirectional. | ||
543 | */ | ||
544 | bool flag_unidirectional; | ||
545 | |||
546 | /** | ||
547 | * If the stream won't be used for receiving frames anymore. The | ||
548 | * client has sent FLAG_FIN or the stream was terminated with | ||
549 | * RST_STREAM. | ||
550 | */ | ||
551 | bool is_in_closed; | ||
552 | |||
553 | /** | ||
554 | * If the stream won't be used for sending out frames anymore. The | ||
555 | * server has sent FLAG_FIN or the stream was terminated with | ||
556 | * RST_STREAM. | ||
557 | */ | ||
558 | bool is_out_closed; | ||
559 | |||
560 | /** | ||
561 | * Which entity (server/client) has created the stream. | ||
562 | */ | ||
563 | bool is_server_initiator; | ||
564 | }; | ||
565 | |||
566 | |||
567 | /** | ||
568 | * Represents a SPDY session which is just a TCP connection | ||
569 | */ | ||
570 | struct SPDY_Session | ||
571 | { | ||
572 | /** | ||
573 | * zlib stream for decompressing all the name/pair values from the | ||
574 | * received frames. All the received compressed data must be | ||
575 | * decompressed within one context: this stream. Thus, it should be | ||
576 | * unique for the session and initialized at its creation. | ||
577 | */ | ||
578 | z_stream zlib_recv_stream; | ||
579 | |||
580 | /** | ||
581 | * zlib stream for compressing all the name/pair values from the | ||
582 | * frames to be sent. All the sent compressed data must be | ||
583 | * compressed within one context: this stream. Thus, it should be | ||
584 | * unique for the session and initialized at its creation. | ||
585 | */ | ||
586 | z_stream zlib_send_stream; | ||
587 | |||
588 | /** | ||
589 | * This is a doubly-linked list. | ||
590 | */ | ||
591 | struct SPDY_Session *next; | ||
592 | |||
593 | /** | ||
594 | * This is a doubly-linked list. | ||
595 | */ | ||
596 | struct SPDY_Session *prev; | ||
597 | |||
598 | /** | ||
599 | * Reference to the SPDY_Daemon struct. | ||
600 | */ | ||
601 | struct SPDY_Daemon *daemon; | ||
602 | |||
603 | /** | ||
604 | * Foreign address (of length addr_len). | ||
605 | */ | ||
606 | struct sockaddr *addr; | ||
607 | |||
608 | /** | ||
609 | * Head of doubly-linked list of the SPDY streams belonging to the | ||
610 | * session. | ||
611 | */ | ||
612 | struct SPDYF_Stream *streams_head; | ||
613 | |||
614 | /** | ||
615 | * Tail of doubly-linked list of the streams. | ||
616 | */ | ||
617 | struct SPDYF_Stream *streams_tail; | ||
618 | |||
619 | /** | ||
620 | * Unique TLS context for the session. Initialized on each creation | ||
621 | * (actually when the TCP connection is established). | ||
622 | */ | ||
623 | SPDYF_TLS_SESSION_CONTEXT *tls_context; | ||
624 | |||
625 | /** | ||
626 | * Head of doubly-linked list of the responses. | ||
627 | */ | ||
628 | struct SPDYF_Response_Queue *response_queue_head; | ||
629 | |||
630 | /** | ||
631 | * Tail of doubly-linked list of the responses. | ||
632 | */ | ||
633 | struct SPDYF_Response_Queue *response_queue_tail; | ||
634 | |||
635 | /** | ||
636 | * Buffer for reading requests. | ||
637 | */ | ||
638 | void *read_buffer; | ||
639 | |||
640 | /** | ||
641 | * Buffer for writing responses. | ||
642 | */ | ||
643 | void *write_buffer; | ||
644 | |||
645 | /** | ||
646 | * Specific handler for the frame that is currently being received. | ||
647 | */ | ||
648 | void (*frame_handler) (struct SPDY_Session * session); | ||
649 | |||
650 | /** | ||
651 | * Closure for frame_handler. | ||
652 | */ | ||
653 | void *frame_handler_cls; | ||
654 | |||
655 | /** | ||
656 | * Extra field to be used by the user with set/get func for whatever | ||
657 | * purpose he wants. | ||
658 | */ | ||
659 | void *user_cls; | ||
660 | |||
661 | /** | ||
662 | * 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. | ||
664 | * This is needed, for instance, when receiving frame bigger than | ||
665 | * the buffer to avoid deadlock situations. | ||
666 | */ | ||
667 | size_t read_ignore_bytes; | ||
668 | |||
669 | /** | ||
670 | * Size of read_buffer (in bytes). This value indicates | ||
671 | * how many bytes we're willing to read into the buffer; | ||
672 | * the real buffer is one byte longer to allow for | ||
673 | * adding zero-termination (when needed). | ||
674 | */ | ||
675 | size_t read_buffer_size; | ||
676 | |||
677 | /** | ||
678 | * Position where we currently append data in | ||
679 | * read_buffer (last valid position). | ||
680 | */ | ||
681 | size_t read_buffer_offset; | ||
682 | |||
683 | /** | ||
684 | * Position until where everything was already read | ||
685 | */ | ||
686 | size_t read_buffer_beginning; | ||
687 | |||
688 | /** | ||
689 | * Size of write_buffer (in bytes). This value indicates | ||
690 | * how many bytes we're willing to prepare for writing. | ||
691 | */ | ||
692 | size_t write_buffer_size; | ||
693 | |||
694 | /** | ||
695 | * Position where we currently append data in | ||
696 | * write_buffer (last valid position). | ||
697 | */ | ||
698 | size_t write_buffer_offset; | ||
699 | |||
700 | /** | ||
701 | * Position until where everything was already written to the socket | ||
702 | */ | ||
703 | size_t write_buffer_beginning; | ||
704 | |||
705 | /** | ||
706 | * Last time this connection had any activity | ||
707 | * (reading or writing). | ||
708 | */ | ||
709 | time_t last_activity; | ||
710 | |||
711 | /** | ||
712 | * Socket for this connection. Set to -1 if | ||
713 | * this connection has died (daemon should clean | ||
714 | * up in that case). | ||
715 | */ | ||
716 | int socket_fd; | ||
717 | |||
718 | /** | ||
719 | * Length of the foreign address. | ||
720 | */ | ||
721 | socklen_t addr_len; | ||
722 | |||
723 | /** | ||
724 | * The biggest stream ID for this session for streams initiated | ||
725 | * by the client. | ||
726 | */ | ||
727 | uint32_t last_in_stream_id; | ||
728 | |||
729 | /** | ||
730 | * The biggest stream ID for this session for streams initiated | ||
731 | * by the server. | ||
732 | */ | ||
733 | uint32_t last_out_stream_id; | ||
734 | |||
735 | /** | ||
736 | * This value is updated whenever SYN_REPLY or RST_STREAM are sent | ||
737 | * and is used later in GOAWAY frame. | ||
738 | * TODO it is not clear in the draft what happens when streams are | ||
739 | * not answered in the order of their IDs. Moreover, why should we | ||
740 | * send GOAWAY with the ID of received bogus SYN_STREAM with huge ID? | ||
741 | */ | ||
742 | uint32_t last_replied_to_stream_id; | ||
743 | |||
744 | /** | ||
745 | * Shows the stream id of the currently handled frame. This value is | ||
746 | * to be used when sending RST_STREAM in answer to a problematic | ||
747 | * frame, e.g. larger than supported. | ||
748 | */ | ||
749 | uint32_t current_stream_id; | ||
750 | |||
751 | /** | ||
752 | * Shows the current receiving state the session, i.e. what is | ||
753 | * expected to come now, and how it shold be handled. | ||
754 | */ | ||
755 | enum SPDY_SESSION_STATUS status; | ||
756 | |||
757 | /** | ||
758 | * Has this socket been closed for reading (i.e. | ||
759 | * other side closed the connection)? If so, | ||
760 | * we must completely close the connection once | ||
761 | * we are done sending our response (and stop | ||
762 | * trying to read from this socket). | ||
763 | */ | ||
764 | bool read_closed; | ||
765 | |||
766 | /** | ||
767 | * If the server sends GOAWAY, it must ignore all SYN_STREAMS for | ||
768 | * this session. Normally the server will soon close the TCP session. | ||
769 | */ | ||
770 | bool is_goaway_sent; | ||
771 | |||
772 | /** | ||
773 | * If the server receives GOAWAY, it must not send new SYN_STREAMS | ||
774 | * on this session. Normally the client will soon close the TCP | ||
775 | * session. | ||
776 | */ | ||
777 | bool is_goaway_received; | ||
778 | }; | ||
779 | |||
780 | |||
781 | /** | ||
782 | * State and settings kept for each SPDY daemon. | ||
783 | */ | ||
784 | struct SPDY_Daemon | ||
785 | { | ||
786 | |||
787 | /** | ||
788 | * Tail of doubly-linked list of our current, active sessions. | ||
789 | */ | ||
790 | struct SPDY_Session *sessions_head; | ||
791 | |||
792 | /** | ||
793 | * Tail of doubly-linked list of our current, active sessions. | ||
794 | */ | ||
795 | struct SPDY_Session *sessions_tail; | ||
796 | |||
797 | /** | ||
798 | * Tail of doubly-linked list of connections to clean up. | ||
799 | */ | ||
800 | struct SPDY_Session *cleanup_head; | ||
801 | |||
802 | /** | ||
803 | * Tail of doubly-linked list of connections to clean up. | ||
804 | */ | ||
805 | struct SPDY_Session *cleanup_tail; | ||
806 | |||
807 | /** | ||
808 | * Unique TLS context for the daemon. Initialized on daemon start. | ||
809 | */ | ||
810 | SPDYF_TLS_DAEMON_CONTEXT *tls_context; | ||
811 | |||
812 | /** | ||
813 | * Certificate file of the server. File path is kept here. | ||
814 | */ | ||
815 | char *certfile; | ||
816 | |||
817 | /** | ||
818 | * Key file for the certificate of the server. File path is | ||
819 | * kept here. | ||
820 | */ | ||
821 | char *keyfile; | ||
822 | |||
823 | |||
824 | /** | ||
825 | * The address to which the listening socket is bound. | ||
826 | */ | ||
827 | struct sockaddr *address; | ||
828 | |||
829 | /** | ||
830 | * Callback called when a new SPDY session is | ||
831 | * established by a client | ||
832 | */ | ||
833 | SPDY_NewSessionCallback new_session_cb; | ||
834 | |||
835 | /** | ||
836 | * Callback called when a client closes the session | ||
837 | */ | ||
838 | SPDY_SessionClosedCallback session_closed_cb; | ||
839 | |||
840 | /** | ||
841 | * Callback called when a client sends request | ||
842 | */ | ||
843 | SPDY_NewRequestCallback new_request_cb; | ||
844 | |||
845 | /** | ||
846 | * Callback called when HTTP POST params are received | ||
847 | * after request | ||
848 | */ | ||
849 | SPDY_NewPOSTDataCallback new_post_data_cb; | ||
850 | |||
851 | /** | ||
852 | * Closure argument for all the callbacks that can be used by the client. | ||
853 | */ | ||
854 | void *cls; | ||
855 | |||
856 | /** | ||
857 | * Callback called when new stream is created. | ||
858 | */ | ||
859 | SPDYF_NewStreamCallback fnew_stream_cb; | ||
860 | |||
861 | /** | ||
862 | * Closure argument for all the callbacks defined in the framing layer. | ||
863 | */ | ||
864 | void *fcls; | ||
865 | |||
866 | /** | ||
867 | * After how many seconds of inactivity should | ||
868 | * connections time out? Zero for no timeout. | ||
869 | */ | ||
870 | time_t session_timeout; | ||
871 | |||
872 | /** | ||
873 | * Listen socket. | ||
874 | */ | ||
875 | int socket_fd; | ||
876 | |||
877 | /** | ||
878 | * Daemon's options. | ||
879 | */ | ||
880 | enum SPDY_DAEMON_OPTION options; | ||
881 | |||
882 | /** | ||
883 | * Daemon's flags. | ||
884 | */ | ||
885 | enum SPDY_DAEMON_FLAG flags; | ||
886 | |||
887 | /** | ||
888 | * Listen port. | ||
889 | */ | ||
890 | uint16_t port; | ||
891 | }; | ||
892 | |||
893 | |||
894 | /** | ||
895 | * Represents a SPDY response. | ||
896 | */ | ||
897 | struct SPDY_Response | ||
898 | { | ||
899 | /** | ||
900 | * Raw uncompressed stream of the name/value pairs in SPDY frame | ||
901 | * used for the HTTP headers. | ||
902 | */ | ||
903 | void *headers; | ||
904 | |||
905 | /** | ||
906 | * Raw stream of the data to be sent. Equivalent to the body in HTTP | ||
907 | * response. | ||
908 | */ | ||
909 | void *data; | ||
910 | |||
911 | /** | ||
912 | * Callback function to be used when the response data is provided | ||
913 | * with callbacks. In this case data must be NULL and data_size must | ||
914 | * be 0. | ||
915 | */ | ||
916 | SPDY_ResponseCallback rcb; | ||
917 | |||
918 | /** | ||
919 | * Extra argument to rcb. | ||
920 | */ | ||
921 | void *rcb_cls; | ||
922 | |||
923 | /** | ||
924 | * Length of headers. | ||
925 | */ | ||
926 | size_t headers_size; | ||
927 | |||
928 | /** | ||
929 | * Length of data. | ||
930 | */ | ||
931 | size_t data_size; | ||
932 | |||
933 | /** | ||
934 | * The callback func will be called to get that amount of bytes to | ||
935 | * put them into a DATA frame. It is either user preffered or | ||
936 | * the maximum supported by the lib value. | ||
937 | */ | ||
938 | uint32_t rcb_block_size; | ||
939 | }; | ||
940 | |||
941 | |||
942 | /* Macros for handling data and structures */ | ||
943 | |||
944 | |||
945 | /** | ||
946 | * Insert an element at the head of a DLL. Assumes that head, tail and | ||
947 | * element are structs with prev and next fields. | ||
948 | * | ||
949 | * @param head pointer to the head of the DLL (struct ? *) | ||
950 | * @param tail pointer to the tail of the DLL (struct ? *) | ||
951 | * @param element element to insert (struct ? *) | ||
952 | */ | ||
953 | #define DLL_insert(head,tail,element) do { \ | ||
954 | (element)->next = (head); \ | ||
955 | (element)->prev = NULL; \ | ||
956 | if ((tail) == NULL) \ | ||
957 | (tail) = element; \ | ||
958 | else \ | ||
959 | (head)->prev = element; \ | ||
960 | (head) = (element); } while (0) | ||
961 | |||
962 | |||
963 | /** | ||
964 | * Remove an element from a DLL. Assumes | ||
965 | * that head, tail and element are structs | ||
966 | * with prev and next fields. | ||
967 | * | ||
968 | * @param head pointer to the head of the DLL (struct ? *) | ||
969 | * @param tail pointer to the tail of the DLL (struct ? *) | ||
970 | * @param element element to remove (struct ? *) | ||
971 | */ | ||
972 | #define DLL_remove(head,tail,element) do { \ | ||
973 | if ((element)->prev == NULL) \ | ||
974 | (head) = (element)->next; \ | ||
975 | else \ | ||
976 | (element)->prev->next = (element)->next; \ | ||
977 | if ((element)->next == NULL) \ | ||
978 | (tail) = (element)->prev; \ | ||
979 | else \ | ||
980 | (element)->next->prev = (element)->prev; \ | ||
981 | (element)->next = NULL; \ | ||
982 | (element)->prev = NULL; } while (0) | ||
983 | |||
984 | |||
985 | /** | ||
986 | * Convert all integers in a SPDY control frame headers structure from | ||
987 | * host byte order to network byte order. | ||
988 | * | ||
989 | * @param frame input and output structure (struct SPDY_Control_Frame *) | ||
990 | */ | ||
991 | #if HAVE_BIG_ENDIAN | ||
992 | #define SPDYF_CONTROL_FRAME_HTON(frame) | ||
993 | #else | ||
994 | #define SPDYF_CONTROL_FRAME_HTON(frame) do { \ | ||
995 | (*((uint16_t *) frame )) = (*((uint8_t *) (frame) +1 )) | ((*((uint8_t *) frame ))<<8);\ | ||
996 | (frame)->type = htons((frame)->type); \ | ||
997 | (frame)->length = HTON24((frame)->length); \ | ||
998 | } while (0) | ||
999 | #endif | ||
1000 | |||
1001 | |||
1002 | /** | ||
1003 | * Convert all integers in a SPDY control frame headers structure from | ||
1004 | * network byte order to host byte order. | ||
1005 | * | ||
1006 | * @param frame input and output structure (struct SPDY_Control_Frame *) | ||
1007 | */ | ||
1008 | #if HAVE_BIG_ENDIAN | ||
1009 | #define SPDYF_CONTROL_FRAME_NTOH(frame) | ||
1010 | #else | ||
1011 | #define SPDYF_CONTROL_FRAME_NTOH(frame) do { \ | ||
1012 | (*((uint16_t *) frame )) = (*((uint8_t *) (frame) +1 )) | ((*((uint8_t *) frame ))<<8);\ | ||
1013 | (frame)->type = ntohs((frame)->type); \ | ||
1014 | (frame)->length = NTOH24((frame)->length); \ | ||
1015 | } while (0) | ||
1016 | #endif | ||
1017 | |||
1018 | |||
1019 | /** | ||
1020 | * Convert all integers in a SPDY data frame headers structure from | ||
1021 | * host byte order to network byte order. | ||
1022 | * | ||
1023 | * @param frame input and output structure (struct SPDY_Data_Frame *) | ||
1024 | */ | ||
1025 | #if HAVE_BIG_ENDIAN | ||
1026 | #define SPDYF_DATA_FRAME_HTON(frame) | ||
1027 | #else | ||
1028 | #define SPDYF_DATA_FRAME_HTON(frame) do { \ | ||
1029 | *((uint32_t *) frame ) = htonl(*((uint32_t *) frame ));\ | ||
1030 | (frame)->length = HTON24((frame)->length); \ | ||
1031 | } while (0) | ||
1032 | #endif | ||
1033 | |||
1034 | |||
1035 | /** | ||
1036 | * Convert all integers in a SPDY data frame headers structure from | ||
1037 | * network byte order to host byte order. | ||
1038 | * | ||
1039 | * @param frame input and output structure (struct SPDY_Data_Frame *) | ||
1040 | */ | ||
1041 | #if HAVE_BIG_ENDIAN | ||
1042 | #define SPDYF_DATA_FRAME_NTOH(frame) | ||
1043 | #else | ||
1044 | #define SPDYF_DATA_FRAME_NTOH(frame) do { \ | ||
1045 | *((uint32_t *) frame ) = ntohl(*((uint32_t *) frame ));\ | ||
1046 | (frame)->length = NTOH24((frame)->length); \ | ||
1047 | } while (0) | ||
1048 | #endif | ||
1049 | |||
1050 | |||
1051 | /** | ||
1052 | * Creates one or more new SPDYF_Response_Queue object to be put on the | ||
1053 | * response queue. | ||
1054 | * | ||
1055 | * @param is_data whether new data frame or new control frame will be | ||
1056 | * crerated | ||
1057 | * @param data the row stream which will be used as the body of the frame | ||
1058 | * @param data_size length of data | ||
1059 | * @param response object, part of which is the frame | ||
1060 | * @param stream on which data is to be sent | ||
1061 | * @param closestream TRUE if the frame must close the stream (with flag) | ||
1062 | * @param frqcb callback to notify application layer when the frame | ||
1063 | * has been sent or discarded | ||
1064 | * @param frqcb_cls closure for frqcb | ||
1065 | * @param rrcb callback used by the application layer to notify the | ||
1066 | * application when the frame has been sent or discarded. | ||
1067 | * frqcb will call it | ||
1068 | * @param rrcb_cls closure for rrcb | ||
1069 | * @return double linked list of SPDYF_Response_Queue structures: one or | ||
1070 | * more frames are returned based on the size of the data | ||
1071 | */ | ||
1072 | struct SPDYF_Response_Queue * | ||
1073 | SPDYF_response_queue_create(bool is_data, | ||
1074 | void *data, | ||
1075 | size_t data_size, | ||
1076 | struct SPDY_Response *response, | ||
1077 | struct SPDYF_Stream *stream, | ||
1078 | bool closestream, | ||
1079 | SPDYF_ResponseQueueResultCallback frqcb, | ||
1080 | void *frqcb_cls, | ||
1081 | SPDY_ResponseResultCallback rrcb, | ||
1082 | void *rrcb_cls); | ||
1083 | |||
1084 | |||
1085 | /** | ||
1086 | * Destroys SPDYF_Response_Queue structure and whatever is in it. | ||
1087 | * | ||
1088 | * @param response_queue to destroy | ||
1089 | */ | ||
1090 | void | ||
1091 | SPDYF_response_queue_destroy(struct SPDYF_Response_Queue *response_queue); | ||
1092 | |||
1093 | |||
1094 | /** | ||
1095 | * Transforms raw binary decomressed stream of headers | ||
1096 | * into SPDY_NameValue, containing all of the headers and values. | ||
1097 | * | ||
1098 | * @param stream that is to be transformed | ||
1099 | * @param size length of the stream | ||
1100 | * @param container will contain the newly created SPDY_NameValue | ||
1101 | * container. Should point to NULL. | ||
1102 | * @return SPDY_YES on success | ||
1103 | * SPDY_NO on memory error | ||
1104 | * SPDY_INPUT_ERROR if the provided stream is not valid | ||
1105 | */ | ||
1106 | int | ||
1107 | SPDYF_name_value_from_stream(void *stream, | ||
1108 | size_t size, | ||
1109 | struct SPDY_NameValue ** container); | ||
1110 | |||
1111 | |||
1112 | /** | ||
1113 | * Transforms array of objects of name/values tuples, containing HTTP | ||
1114 | * headers, into raw binary stream. The resulting stream is ready to | ||
1115 | * be compressed and sent. | ||
1116 | * | ||
1117 | * @param container one or more SPDY_NameValue objects. Each object | ||
1118 | * contains multiple number of name/value tuples. | ||
1119 | * @param num_containers length of the array | ||
1120 | * @param stream will contain the resulting stream. Should point to NULL. | ||
1121 | * @return length of stream or value less than 0 indicating error | ||
1122 | */ | ||
1123 | ssize_t | ||
1124 | SPDYF_name_value_to_stream(struct SPDY_NameValue * container[], | ||
1125 | int num_containers, | ||
1126 | void **stream); | ||
1127 | |||
1128 | #endif | ||