aboutsummaryrefslogtreecommitdiff
path: root/src/microspdy/structures.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/microspdy/structures.h')
-rw-r--r--src/microspdy/structures.h1128
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 */
38enum 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 */
129enum 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 */
172enum 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 */
189enum 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 */
201enum 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 */
219enum 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 */
295enum 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
316struct SPDYF_Stream;
317
318struct 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 */
329typedef 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 */
347typedef 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 */
357struct __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 */
370struct __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 */
382struct 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 */
464struct 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 */
497struct 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 */
570struct 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 */
784struct 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 */
897struct 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 */
1072struct SPDYF_Response_Queue *
1073SPDYF_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 */
1090void
1091SPDYF_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 */
1106int
1107SPDYF_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 */
1123ssize_t
1124SPDYF_name_value_to_stream(struct SPDY_NameValue * container[],
1125 int num_containers,
1126 void **stream);
1127
1128#endif