1 /*
2 This file is part of libmicrospdy
3 Copyright 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 session.c
21 * @brief TCP connection/SPDY session handling. So far most of the
22 * functions for handling SPDY framing layer are here.
23 * @author Andrey Uzunov
24 */
25
26 #include "platform.h"
27 #include "structures.h"
28 #include "internal.h"
29 #include "session.h"
30 #include "compression.h"
31 #include "stream.h"
32 #include "io.h"
33
34
35 /**
36 * Handler for reading the full SYN_STREAM frame after we know that
37 * the frame is such.
38 * The function waits for the full frame and then changes status
39 * of the session. New stream is created.
40 *
41 * @param session SPDY_Session whose read buffer is used.
42 */
43 static void
spdyf_handler_read_syn_stream(struct SPDY_Session * session)44 spdyf_handler_read_syn_stream (struct SPDY_Session *session)
45 {
46 size_t name_value_strm_size = 0;
47 unsigned int compressed_data_size;
48 int ret;
49 void *name_value_strm = NULL;
50 struct SPDYF_Control_Frame *frame;
51 struct SPDY_NameValue *headers;
52
53 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status
54 || SPDY_SESSION_STATUS_WAIT_FOR_BODY == session->status,
55 "the function is called wrong");
56
57 frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
58
59 //handle subheaders
60 if(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status)
61 {
62 if(0 == frame->length)
63 {
64 //protocol error: incomplete frame
65 //we just ignore it since there is no stream id for which to
66 //send RST_STREAM
67 //TODO maybe GOAWAY and closing session is appropriate
68 SPDYF_DEBUG("zero long SYN_STREAM received");
69 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
70 free(frame);
71 return;
72 }
73
74 if(SPDY_YES != SPDYF_stream_new(session))
75 {
76 /* waiting for some more fields to create new stream
77 or something went wrong, SPDYF_stream_new has handled the
78 situation */
79 return;
80 }
81
82 session->current_stream_id = session->streams_head->stream_id;
83 if(frame->length > SPDY_MAX_SUPPORTED_FRAME_SIZE)
84 {
85 //TODO no need to create stream if this happens
86 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
87 return;
88 }
89 else
90 session->status = SPDY_SESSION_STATUS_WAIT_FOR_BODY;
91 }
92
93 //handle body
94
95 //start reading the compressed name/value pairs (http headers)
96 compressed_data_size = frame->length //everything after length field
97 - 10;//4B stream id, 4B assoc strem id, 2B priority, unused and slot
98
99 if(session->read_buffer_offset - session->read_buffer_beginning < compressed_data_size)
100 {
101 // the full frame is not yet here, try later
102 return;
103 }
104
105 if ( (compressed_data_size > 0) &&
106 (SPDY_YES !=
107 SPDYF_zlib_inflate(&session->zlib_recv_stream,
108 session->read_buffer + session->read_buffer_beginning,
109 compressed_data_size,
110 &name_value_strm,
111 &name_value_strm_size)) )
112 {
113 /* something went wrong on inflating,
114 * the state of the stream for decompression is unknown
115 * and we may not be able to read anything more received on
116 * this session,
117 * so it is better to close the session */
118 free(name_value_strm);
119 free(frame);
120
121 /* mark the session for closing and close it, when
122 * everything on the output queue is already written */
123 session->status = SPDY_SESSION_STATUS_FLUSHING;
124
125 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_INTERNAL_ERROR, false);
126
127 return;
128 }
129
130 if(0 == name_value_strm_size || 0 == compressed_data_size)
131 {
132 //Protocol error: send RST_STREAM
133 if(SPDY_YES != SPDYF_prepare_rst_stream(session, session->streams_head,
134 SPDY_RST_STREAM_STATUS_PROTOCOL_ERROR))
135 {
136 //no memory, try later to send RST
137 free(name_value_strm);
138 return;
139 }
140 }
141 else
142 {
143 ret = SPDYF_name_value_from_stream(name_value_strm, name_value_strm_size, &headers);
144 if(SPDY_NO == ret)
145 {
146 //memory error, try later
147 free(name_value_strm);
148 return;
149 }
150
151 session->streams_head->headers = headers;
152 //inform the application layer for the new stream received
153 if(SPDY_YES != session->daemon->fnew_stream_cb(session->daemon->fcls, session->streams_head))
154 {
155 //memory error, try later
156 free(name_value_strm);
157 return;
158 }
159
160 session->read_buffer_beginning += compressed_data_size;
161 }
162
163 //SPDYF_DEBUG("syn_stream received: id %i", session->current_stream_id);
164
165 //change state to wait for new frame
166 free(name_value_strm);
167 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
168 free(frame);
169 }
170
171
172 /**
173 * Handler for reading the GOAWAY frame after we know that
174 * the frame is such.
175 * The function waits for the full frame and then changes status
176 * of the session.
177 *
178 * @param session SPDY_Session whose read buffer is used.
179 */
180 static void
spdyf_handler_read_goaway(struct SPDY_Session * session)181 spdyf_handler_read_goaway (struct SPDY_Session *session)
182 {
183 struct SPDYF_Control_Frame *frame;
184 uint32_t last_good_stream_id;
185 uint32_t status_int;
186 enum SPDY_GOAWAY_STATUS status;
187
188 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status,
189 "the function is called wrong");
190
191 frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
192
193 if(frame->length > SPDY_MAX_SUPPORTED_FRAME_SIZE)
194 {
195 //this is a protocol error/attack
196 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
197 return;
198 }
199
200 if(0 != frame->flags || 8 != frame->length)
201 {
202 //this is a protocol error
203 SPDYF_DEBUG("wrong GOAWAY received");
204 //anyway, it will be handled
205 }
206
207 if((session->read_buffer_offset - session->read_buffer_beginning) < frame->length)
208 {
209 //not all fields are received
210 //try later
211 return;
212 }
213
214 //mark that the session is almost closed
215 session->is_goaway_received = true;
216
217 if(8 == frame->length)
218 {
219 memcpy(&last_good_stream_id, session->read_buffer + session->read_buffer_beginning, 4);
220 last_good_stream_id = NTOH31(last_good_stream_id);
221 session->read_buffer_beginning += 4;
222
223 memcpy(&status_int, session->read_buffer + session->read_buffer_beginning, 4);
224 status = ntohl(status_int);
225 session->read_buffer_beginning += 4;
226
227 //TODO do something with last_good
228
229 //SPDYF_DEBUG("Received GOAWAY; status=%i; lastgood=%i",status,last_good_stream_id);
230
231 //do something according to the status
232 //TODO
233 switch(status)
234 {
235 case SPDY_GOAWAY_STATUS_OK:
236 break;
237 case SPDY_GOAWAY_STATUS_PROTOCOL_ERROR:
238 break;
239 case SPDY_GOAWAY_STATUS_INTERNAL_ERROR:
240 break;
241 }
242
243 //SPDYF_DEBUG("goaway received: status %i", status);
244 }
245
246 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
247 free(frame);
248 }
249
250
251 /**
252 * Handler for reading RST_STREAM frames. After receiving the frame
253 * the stream moves into closed state and status
254 * of the session is changed. Frames, belonging to this stream, which
255 * are still at the output queue, will be ignored later.
256 *
257 * @param session SPDY_Session whose read buffer is used.
258 */
259 static void
spdyf_handler_read_rst_stream(struct SPDY_Session * session)260 spdyf_handler_read_rst_stream (struct SPDY_Session *session)
261 {
262 struct SPDYF_Control_Frame *frame;
263 uint32_t stream_id;
264 int32_t status_int;
265 //enum SPDY_RST_STREAM_STATUS status; //for debug
266 struct SPDYF_Stream *stream;
267
268 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status,
269 "the function is called wrong");
270
271 frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
272
273 if(0 != frame->flags || 8 != frame->length)
274 {
275 //this is a protocol error
276 SPDYF_DEBUG("wrong RST_STREAM received");
277 //ignore as a large frame
278 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
279 return;
280 }
281
282 if((session->read_buffer_offset - session->read_buffer_beginning) < frame->length)
283 {
284 //not all fields are received
285 //try later
286 return;
287 }
288
289 memcpy(&stream_id, session->read_buffer + session->read_buffer_beginning, 4);
290 stream_id = NTOH31(stream_id);
291 session->read_buffer_beginning += 4;
292
293 memcpy(&status_int, session->read_buffer + session->read_buffer_beginning, 4);
294 //status = ntohl(status_int); //for debug
295 session->read_buffer_beginning += 4;
296
297 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
298 free(frame);
299
300 //mark the stream as closed
301 stream = session->streams_head;
302 while(NULL != stream)
303 {
304 if(stream_id == stream->stream_id)
305 {
306 stream->is_in_closed = true;
307 stream->is_out_closed = true;
308 break;
309 }
310 stream = stream->next;
311 }
312
313 //SPDYF_DEBUG("Received RST_STREAM; status=%i; id=%i",status,stream_id);
314
315 //do something according to the status
316 //TODO
317 /*switch(status)
318 {
319 case SPDY_RST_STREAM_STATUS_PROTOCOL_ERROR:
320 break;
321 }*/
322 }
323
324
325 /**
326 * Handler for reading DATA frames. In requests they are used for POST
327 * arguments.
328 *
329 * @param session SPDY_Session whose read buffer is used.
330 */
331 static void
spdyf_handler_read_data(struct SPDY_Session * session)332 spdyf_handler_read_data (struct SPDY_Session *session)
333 {
334 int ret;
335 struct SPDYF_Data_Frame * frame;
336 struct SPDYF_Stream * stream;
337
338 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status
339 || SPDY_SESSION_STATUS_WAIT_FOR_BODY == session->status,
340 "the function is called wrong");
341
342 //SPDYF_DEBUG("DATA frame received (POST?). Ignoring");
343
344 //SPDYF_SIGINT("");
345
346 frame = (struct SPDYF_Data_Frame *)session->frame_handler_cls;
347
348 //handle subheaders
349 if(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status)
350 {
351 if(frame->length > SPDY_MAX_SUPPORTED_FRAME_SIZE)
352 {
353 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
354 return;
355 }
356 else
357 session->status = SPDY_SESSION_STATUS_WAIT_FOR_BODY;
358 }
359
360 //handle body
361
362 if(session->read_buffer_offset - session->read_buffer_beginning
363 >= frame->length)
364 {
365 stream = SPDYF_stream_find(frame->stream_id, session);
366
367 if(NULL == stream || stream->is_in_closed || NULL == session->daemon->received_data_cb)
368 {
369 if(NULL == session->daemon->received_data_cb)
370 SPDYF_DEBUG("No callback for DATA frame set; Ignoring DATA frame!");
371
372 //TODO send error?
373
374 //TODO for now ignore frame
375 session->read_buffer_beginning += frame->length;
376 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
377 free(frame);
378 return;
379 }
380
381 ret = session->daemon->freceived_data_cb(session->daemon->cls,
382 stream,
383 session->read_buffer + session->read_buffer_beginning,
384 frame->length,
385 0 == (SPDY_DATA_FLAG_FIN & frame->flags));
386
387 session->read_buffer_beginning += frame->length;
388
389 stream->window_size -= frame->length;
390
391 //TODO close in and send rst maybe
392 SPDYF_ASSERT(SPDY_YES == ret, "Cancel POST data is not yet implemented");
393
394 if(SPDY_DATA_FLAG_FIN & frame->flags)
395 {
396 stream->is_in_closed = true;
397 }
398 else if(stream->window_size < SPDYF_INITIAL_WINDOW_SIZE / 2)
399 {
400 //very simple implementation of flow control
401 //when the window's size is under the half of the initial value,
402 //increase it again up to the initial value
403
404 //prepare WINDOW_UPDATE
405 if(SPDY_YES == SPDYF_prepare_window_update(session, stream,
406 SPDYF_INITIAL_WINDOW_SIZE - stream->window_size))
407 {
408 stream->window_size = SPDYF_INITIAL_WINDOW_SIZE;
409 }
410 //else: do it later
411 }
412
413 //SPDYF_DEBUG("data received: id %i", frame->stream_id);
414
415 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
416 free(frame);
417 }
418 }
419
420
421 int
SPDYF_handler_write_syn_reply(struct SPDY_Session * session)422 SPDYF_handler_write_syn_reply (struct SPDY_Session *session)
423 {
424 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
425 struct SPDYF_Stream *stream = response_queue->stream;
426 struct SPDYF_Control_Frame control_frame;
427 void *compressed_headers = NULL;
428 size_t compressed_headers_size=0;
429 size_t used_data=0;
430 size_t total_size;
431 uint32_t stream_id_nbo;
432
433 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
434
435 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
436
437 if(SPDY_YES != SPDYF_zlib_deflate(&session->zlib_send_stream,
438 response_queue->data,
439 response_queue->data_size,
440 &used_data,
441 &compressed_headers,
442 &compressed_headers_size))
443 {
444 /* something went wrong on compressing,
445 * the state of the stream for compression is unknown
446 * and we may not be able to send anything more on
447 * this session,
448 * so it is better to close the session right now */
449 session->status = SPDY_SESSION_STATUS_CLOSING;
450
451 free(compressed_headers);
452
453 return SPDY_NO;
454 }
455
456 //TODO do we need this used_Data
457 SPDYF_ASSERT(used_data == response_queue->data_size, "not everything was used by zlib");
458
459 total_size = sizeof(struct SPDYF_Control_Frame) //SPDY header
460 + 4 // stream id as "subheader"
461 + compressed_headers_size;
462
463 if(NULL == (session->write_buffer = malloc(total_size)))
464 {
465 /* no memory
466 * since we do not save the compressed data anywhere and
467 * the sending zlib stream is already in new state, we must
468 * close the session */
469 session->status = SPDY_SESSION_STATUS_CLOSING;
470
471 free(compressed_headers);
472
473 return SPDY_NO;
474 }
475 session->write_buffer_beginning = 0;
476 session->write_buffer_offset = 0;
477 session->write_buffer_size = total_size;
478
479 control_frame.length = compressed_headers_size + 4; // compressed data + stream_id
480 SPDYF_CONTROL_FRAME_HTON(&control_frame);
481
482 //put frame headers to write buffer
483 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
484 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
485
486 //put stream id to write buffer
487 stream_id_nbo = HTON31(stream->stream_id);
488 memcpy(session->write_buffer + session->write_buffer_offset, &stream_id_nbo, 4);
489 session->write_buffer_offset += 4;
490
491 //put compressed name/value pairs to write buffer
492 memcpy(session->write_buffer + session->write_buffer_offset, compressed_headers, compressed_headers_size);
493 session->write_buffer_offset += compressed_headers_size;
494
495 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
496 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
497
498 //DEBUG CODE, break compression state to see what happens
499 /* SPDYF_zlib_deflate(&session->zlib_send_stream,
500 "1234567890",
501 10,
502 &used_data,
503 &compressed_headers,
504 &compressed_headers_size);
505 */
506 free(compressed_headers);
507
508 session->last_replied_to_stream_id = stream->stream_id;
509
510 //SPDYF_DEBUG("syn_reply sent: id %i", stream->stream_id);
511
512 return SPDY_YES;
513 }
514
515
516 int
SPDYF_handler_write_goaway(struct SPDY_Session * session)517 SPDYF_handler_write_goaway (struct SPDY_Session *session)
518 {
519 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
520 struct SPDYF_Control_Frame control_frame;
521 size_t total_size;
522 int last_good_stream_id;
523
524 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
525
526 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
527
528 session->is_goaway_sent = true;
529
530 total_size = sizeof(struct SPDYF_Control_Frame) //SPDY header
531 + 4 // last good stream id as "subheader"
532 + 4; // status code as "subheader"
533
534 if(NULL == (session->write_buffer = malloc(total_size)))
535 {
536 return SPDY_NO;
537 }
538 session->write_buffer_beginning = 0;
539 session->write_buffer_offset = 0;
540 session->write_buffer_size = total_size;
541
542 control_frame.length = 8; // always for GOAWAY
543 SPDYF_CONTROL_FRAME_HTON(&control_frame);
544
545 //put frame headers to write buffer
546 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
547 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
548
549 //put last good stream id to write buffer
550 last_good_stream_id = HTON31(session->last_replied_to_stream_id);
551 memcpy(session->write_buffer + session->write_buffer_offset, &last_good_stream_id, 4);
552 session->write_buffer_offset += 4;
553
554 //put "data" to write buffer. This is the status
555 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, 4);
556 session->write_buffer_offset += 4;
557 //data is not freed by the destroy function so:
558 //free(response_queue->data);
559
560 //SPDYF_DEBUG("goaway sent: status %i", NTOH31(*(uint32_t*)(response_queue->data)));
561
562 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
563 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
564
565 return SPDY_YES;
566 }
567
568
569 int
SPDYF_handler_write_data(struct SPDY_Session * session)570 SPDYF_handler_write_data (struct SPDY_Session *session)
571 {
572 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
573 struct SPDYF_Response_Queue *new_response_queue;
574 size_t total_size;
575 struct SPDYF_Data_Frame data_frame;
576 ssize_t ret;
577 bool more;
578
579 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
580
581 memcpy(&data_frame, response_queue->data_frame, sizeof(data_frame));
582
583 if(NULL == response_queue->response->rcb)
584 {
585 //standard response with data into the struct
586 SPDYF_ASSERT(NULL != response_queue->data, "no data for the response");
587
588 total_size = sizeof(struct SPDYF_Data_Frame) //SPDY header
589 + response_queue->data_size;
590
591 if(NULL == (session->write_buffer = malloc(total_size)))
592 {
593 return SPDY_NO;
594 }
595 session->write_buffer_beginning = 0;
596 session->write_buffer_offset = 0;
597 session->write_buffer_size = total_size;
598
599 data_frame.length = response_queue->data_size;
600 SPDYF_DATA_FRAME_HTON(&data_frame);
601
602 //put SPDY headers to the writing buffer
603 memcpy(session->write_buffer + session->write_buffer_offset,&data_frame,sizeof(struct SPDYF_Data_Frame));
604 session->write_buffer_offset += sizeof(struct SPDYF_Data_Frame);
605
606 //put data to the writing buffer
607 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, response_queue->data_size);
608 session->write_buffer_offset += response_queue->data_size;
609 }
610 else
611 {
612 /* response with callbacks. The lib will produce more than 1
613 * data frames
614 */
615
616 total_size = sizeof(struct SPDYF_Data_Frame) //SPDY header
617 + SPDY_MAX_SUPPORTED_FRAME_SIZE; //max possible size
618
619 if(NULL == (session->write_buffer = malloc(total_size)))
620 {
621 return SPDY_NO;
622 }
623 session->write_buffer_beginning = 0;
624 session->write_buffer_offset = 0;
625 session->write_buffer_size = total_size;
626
627 ret = response_queue->response->rcb(response_queue->response->rcb_cls,
628 session->write_buffer + sizeof(struct SPDYF_Data_Frame),
629 response_queue->response->rcb_block_size,
630 &more);
631
632 if(ret < 0 || ret > response_queue->response->rcb_block_size)
633 {
634 free(session->write_buffer);
635 session->write_buffer = NULL;
636
637 //send RST_STREAM
638 if(SPDY_YES == (ret = SPDYF_prepare_rst_stream(session,
639 response_queue->stream,
640 SPDY_RST_STREAM_STATUS_INTERNAL_ERROR)))
641 {
642 return SPDY_NO;
643 }
644
645 //else no memory
646 //for now close session
647 //TODO what?
648 session->status = SPDY_SESSION_STATUS_CLOSING;
649
650 return SPDY_NO;
651 }
652 if(0 == ret && more)
653 {
654 //the app couldn't write anything to buf but later will
655 free(session->write_buffer);
656 session->write_buffer = NULL;
657 session->write_buffer_size = 0;
658
659 if(NULL != response_queue->next)
660 {
661 //put the frame at the end of the queue
662 //otherwise - head of line blocking
663 session->response_queue_head = response_queue->next;
664 session->response_queue_head->prev = NULL;
665 session->response_queue_tail->next = response_queue;
666 response_queue->prev = session->response_queue_tail;
667 response_queue->next = NULL;
668 session->response_queue_tail = response_queue;
669 }
670
671 return SPDY_YES;
672 }
673
674 if(more)
675 {
676 //create another response queue object to call the user cb again
677 if(NULL == (new_response_queue = SPDYF_response_queue_create(true,
678 NULL,
679 0,
680 response_queue->response,
681 response_queue->stream,
682 false,
683 response_queue->frqcb,
684 response_queue->frqcb_cls,
685 response_queue->rrcb,
686 response_queue->rrcb_cls)))
687 {
688 //TODO send RST_STREAM
689 //for now close session
690 session->status = SPDY_SESSION_STATUS_CLOSING;
691
692 free(session->write_buffer);
693 session->write_buffer = NULL;
694 return SPDY_NO;
695 }
696
697 //put it at second position on the queue
698 new_response_queue->prev = response_queue;
699 new_response_queue->next = response_queue->next;
700 if(NULL == response_queue->next)
701 {
702 session->response_queue_tail = new_response_queue;
703 }
704 else
705 {
706 response_queue->next->prev = new_response_queue;
707 }
708 response_queue->next = new_response_queue;
709
710 response_queue->frqcb = NULL;
711 response_queue->frqcb_cls = NULL;
712 response_queue->rrcb = NULL;
713 response_queue->rrcb_cls = NULL;
714 }
715 else
716 {
717 data_frame.flags |= SPDY_DATA_FLAG_FIN;
718 }
719
720 data_frame.length = ret;
721 SPDYF_DATA_FRAME_HTON(&data_frame);
722
723 //put SPDY headers to the writing buffer
724 memcpy(session->write_buffer + session->write_buffer_offset,
725 &data_frame,
726 sizeof(struct SPDYF_Data_Frame));
727 session->write_buffer_offset += sizeof(struct SPDYF_Data_Frame);
728 session->write_buffer_offset += ret;
729 session->write_buffer_size = session->write_buffer_offset;
730 }
731
732 //SPDYF_DEBUG("data sent: id %i", NTOH31(data_frame.stream_id));
733
734 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
735 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
736
737 return SPDY_YES;
738 }
739
740
741 int
SPDYF_handler_write_rst_stream(struct SPDY_Session * session)742 SPDYF_handler_write_rst_stream (struct SPDY_Session *session)
743 {
744 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
745 struct SPDYF_Control_Frame control_frame;
746 size_t total_size;
747
748 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
749
750 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
751
752 total_size = sizeof(struct SPDYF_Control_Frame) //SPDY header
753 + 4 // stream id as "subheader"
754 + 4; // status code as "subheader"
755
756 if(NULL == (session->write_buffer = malloc(total_size)))
757 {
758 return SPDY_NO;
759 }
760 session->write_buffer_beginning = 0;
761 session->write_buffer_offset = 0;
762 session->write_buffer_size = total_size;
763
764 control_frame.length = 8; // always for RST_STREAM
765 SPDYF_CONTROL_FRAME_HTON(&control_frame);
766
767 //put frame headers to write buffer
768 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
769 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
770
771 //put stream id to write buffer. This is the status
772 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, 8);
773 session->write_buffer_offset += 8;
774 //data is not freed by the destroy function so:
775 //free(response_queue->data);
776
777 //SPDYF_DEBUG("rst_stream sent: id %i", NTOH31((((uint64_t)response_queue->data) & 0xFFFF0000) >> 32));
778
779 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
780 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
781
782 return SPDY_YES;
783 }
784
785
786 int
SPDYF_handler_write_window_update(struct SPDY_Session * session)787 SPDYF_handler_write_window_update (struct SPDY_Session *session)
788 {
789 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
790 struct SPDYF_Control_Frame control_frame;
791 size_t total_size;
792
793 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
794
795 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
796
797 total_size = sizeof(struct SPDYF_Control_Frame) //SPDY header
798 + 4 // stream id as "subheader"
799 + 4; // delta-window-size as "subheader"
800
801 if(NULL == (session->write_buffer = malloc(total_size)))
802 {
803 return SPDY_NO;
804 }
805 session->write_buffer_beginning = 0;
806 session->write_buffer_offset = 0;
807 session->write_buffer_size = total_size;
808
809 control_frame.length = 8; // always for WINDOW_UPDATE
810 SPDYF_CONTROL_FRAME_HTON(&control_frame);
811
812 //put frame headers to write buffer
813 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
814 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
815
816 //put stream id and delta-window-size to write buffer
817 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, 8);
818 session->write_buffer_offset += 8;
819
820 //SPDYF_DEBUG("window_update sent: id %i", NTOH31((((uint64_t)response_queue->data) & 0xFFFF0000) >> 32));
821
822 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
823 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
824
825 return SPDY_YES;
826 }
827
828
829 void
SPDYF_handler_ignore_frame(struct SPDY_Session * session)830 SPDYF_handler_ignore_frame (struct SPDY_Session *session)
831 {
832 struct SPDYF_Control_Frame *frame;
833
834 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status
835 || SPDY_SESSION_STATUS_WAIT_FOR_BODY == session->status,
836 "the function is called wrong");
837
838
839 frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
840
841 //handle subheaders
842 if(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status)
843 {
844 if(frame->length > SPDY_MAX_SUPPORTED_FRAME_SIZE)
845 {
846 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
847 return;
848 }
849 else
850 session->status = SPDY_SESSION_STATUS_WAIT_FOR_BODY;
851 }
852
853 //handle body
854
855 if(session->read_buffer_offset - session->read_buffer_beginning
856 >= frame->length)
857 {
858 session->read_buffer_beginning += frame->length;
859 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
860 free(frame);
861 }
862 }
863
864
865 int
SPDYF_session_read(struct SPDY_Session * session)866 SPDYF_session_read (struct SPDY_Session *session)
867 {
868 int bytes_read;
869 bool reallocate;
870 size_t actual_buf_size;
871
872 if(SPDY_SESSION_STATUS_CLOSING == session->status
873 || SPDY_SESSION_STATUS_FLUSHING == session->status)
874 return SPDY_NO;
875
876 //if the read buffer is full to the end, we need to reallocate space
877 if (session->read_buffer_size == session->read_buffer_offset)
878 {
879 //but only if the state of the session requires it
880 //i.e. no further proceeding is possible without reallocation
881 reallocate = false;
882 actual_buf_size = session->read_buffer_offset
883 - session->read_buffer_beginning;
884 switch(session->status)
885 {
886 case SPDY_SESSION_STATUS_WAIT_FOR_HEADER:
887
888 case SPDY_SESSION_STATUS_IGNORE_BYTES:
889 //we need space for a whole control frame header
890 if(actual_buf_size < sizeof(struct SPDYF_Control_Frame))
891 reallocate = true;
892 break;
893
894 case SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER:
895
896 case SPDY_SESSION_STATUS_WAIT_FOR_BODY:
897 //we need as many bytes as set in length field of the
898 //header
899 SPDYF_ASSERT(NULL != session->frame_handler_cls,
900 "no frame for session");
901 if(session->frame_handler != &spdyf_handler_read_data)
902 {
903 if(actual_buf_size
904 < ((struct SPDYF_Control_Frame *)session->frame_handler_cls)->length)
905 reallocate = true;
906 }
907 else
908 {
909 if(actual_buf_size
910 < ((struct SPDYF_Data_Frame *)session->frame_handler_cls)->length)
911 reallocate = true;
912 }
913 break;
914
915 case SPDY_SESSION_STATUS_CLOSING:
916 case SPDY_SESSION_STATUS_FLUSHING:
917 //nothing needed
918 break;
919 }
920
921 if(reallocate)
922 {
923 //reuse the space in the buffer that was already read by the lib
924 memmove(session->read_buffer,
925 session->read_buffer + session->read_buffer_beginning,
926 session->read_buffer_offset - session->read_buffer_beginning);
927
928 session->read_buffer_offset -= session->read_buffer_beginning;
929 session->read_buffer_beginning = 0;
930 }
931 else
932 {
933 //will read next time
934 //TODO optimize it, memmove more often?
935 return SPDY_NO;
936 }
937 }
938
939 session->last_activity = SPDYF_monotonic_time();
940
941 //actual read from the TLS socket
942 bytes_read = session->fio_recv(session,
943 session->read_buffer + session->read_buffer_offset,
944 session->read_buffer_size - session->read_buffer_offset);
945
946 switch(bytes_read)
947 {
948 case SPDY_IO_ERROR_CLOSED:
949 //The TLS connection was closed by the other party, clean
950 //or not
951 shutdown (session->socket_fd, SHUT_RD);
952 session->read_closed = true;
953 session->status = SPDY_SESSION_STATUS_CLOSING;
954 return SPDY_YES;
955
956 case SPDY_IO_ERROR_ERROR:
957 //any kind of error in the TLS subsystem
958 //try to prepare GOAWAY frame
959 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_INTERNAL_ERROR, false);
960 //try to flush the queue when write is called
961 session->status = SPDY_SESSION_STATUS_FLUSHING;
962 return SPDY_YES;
963
964 case SPDY_IO_ERROR_AGAIN:
965 //read or write should be called again; leave it for the
966 //next time
967 return SPDY_NO;
968
969 //default:
970 //something was really read from the TLS subsystem
971 //just continue
972 }
973
974 session->read_buffer_offset += bytes_read;
975
976 return SPDY_YES;
977 }
978
979
980 int
SPDYF_session_write(struct SPDY_Session * session,bool only_one_frame)981 SPDYF_session_write (struct SPDY_Session *session,
982 bool only_one_frame)
983 {
984 unsigned int i;
985 int bytes_written;
986 struct SPDYF_Response_Queue *queue_head;
987 struct SPDYF_Response_Queue *response_queue;
988
989 if(SPDY_SESSION_STATUS_CLOSING == session->status)
990 return SPDY_NO;
991
992 if(SPDY_NO == session->fio_before_write(session))
993 return SPDY_NO;
994
995 for(i=0;
996 only_one_frame
997 ? i < 1
998 : i < session->max_num_frames;
999 ++i)
1000 {
1001 //if the buffer is not null, part of the last frame is still
1002 //pending to be sent
1003 if(NULL == session->write_buffer)
1004 {
1005 //discard frames on closed streams
1006 response_queue = session->response_queue_head;
1007
1008 while(NULL != response_queue)
1009 {
1010 //if stream is closed, remove not yet sent frames
1011 //associated with it
1012 //GOAWAY frames are not associated to streams
1013 //and still need to be sent
1014 if(NULL == response_queue->stream
1015 || !response_queue->stream->is_out_closed)
1016 break;
1017
1018 DLL_remove(session->response_queue_head,session->response_queue_tail,response_queue);
1019
1020 if(NULL != response_queue->frqcb)
1021 {
1022 response_queue->frqcb(response_queue->frqcb_cls, response_queue, SPDY_RESPONSE_RESULT_STREAM_CLOSED);
1023 }
1024
1025 SPDYF_response_queue_destroy(response_queue);
1026 response_queue = session->response_queue_head;
1027 }
1028
1029 if(NULL == session->response_queue_head)
1030 break;//nothing on the queue
1031
1032 //get next data from queue and put it to the write buffer
1033 // to send it
1034 if(SPDY_NO == session->response_queue_head->process_response_handler(session))
1035 {
1036 //error occured and the handler changed or not the
1037 //session's status appropriately
1038 if(SPDY_SESSION_STATUS_CLOSING == session->status)
1039 {
1040 //try to send GOAWAY first if the current frame is different
1041 if(session->response_queue_head->is_data
1042 || SPDY_CONTROL_FRAME_TYPES_GOAWAY
1043 != session->response_queue_head->control_frame->type)
1044 {
1045 session->status = SPDY_SESSION_STATUS_FLUSHING;
1046 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_INTERNAL_ERROR, true);
1047 SPDYF_session_write(session,true);
1048 session->status = SPDY_SESSION_STATUS_CLOSING;
1049 }
1050 return SPDY_YES;
1051 }
1052
1053 //just return from the loop to return from this function
1054 ++i;
1055 break;
1056 }
1057
1058 //check if something was prepared for writing
1059 //on respones with callbacks it is possible that their is no
1060 //data available
1061 if(0 == session->write_buffer_size)//nothing to write
1062 {
1063 if(response_queue != session->response_queue_head)
1064 {
1065 //the handler modified the queue
1066 continue;
1067 }
1068 else
1069 {
1070 //no need to try the same frame again
1071 ++i;
1072 break;
1073 }
1074 }
1075 }
1076
1077 session->last_activity = SPDYF_monotonic_time();
1078
1079 //actual write to the IO
1080 bytes_written = session->fio_send(session,
1081 session->write_buffer + session->write_buffer_beginning,
1082 session->write_buffer_offset - session->write_buffer_beginning);
1083
1084 switch(bytes_written)
1085 {
1086 case SPDY_IO_ERROR_CLOSED:
1087 //The TLS connection was closed by the other party, clean
1088 //or not
1089 shutdown (session->socket_fd, SHUT_RD);
1090 session->read_closed = true;
1091 session->status = SPDY_SESSION_STATUS_CLOSING;
1092 return SPDY_YES;
1093
1094 case SPDY_IO_ERROR_ERROR:
1095 //any kind of error in the TLS subsystem
1096 //forbid more writing
1097 session->status = SPDY_SESSION_STATUS_CLOSING;
1098 return SPDY_YES;
1099
1100 case SPDY_IO_ERROR_AGAIN:
1101 //read or write should be called again; leave it for the
1102 //next time; return from the function as we do not now
1103 //whether reading or writing is needed
1104 return i>0 ? SPDY_YES : SPDY_NO;
1105
1106 //default:
1107 //something was really read from the TLS subsystem
1108 //just continue
1109 }
1110
1111 session->write_buffer_beginning += bytes_written;
1112
1113 //check if the full buffer was written
1114 if(session->write_buffer_beginning == session->write_buffer_size)
1115 {
1116 //that response is handled, remove it from queue
1117 free(session->write_buffer);
1118 session->write_buffer = NULL;
1119 session->write_buffer_size = 0;
1120 queue_head = session->response_queue_head;
1121 if(NULL == queue_head->next)
1122 {
1123 session->response_queue_head = NULL;
1124 session->response_queue_tail = NULL;
1125 }
1126 else
1127 {
1128 session->response_queue_head = queue_head->next;
1129 session->response_queue_head->prev = NULL;
1130 }
1131
1132 //set stream to closed if the frame's fin flag is set
1133 SPDYF_stream_set_flags_on_write(queue_head);
1134
1135 if(NULL != queue_head->frqcb)
1136 {
1137 //application layer callback to notify sending of the response
1138 queue_head->frqcb(queue_head->frqcb_cls, queue_head, SPDY_RESPONSE_RESULT_SUCCESS);
1139 }
1140
1141 SPDYF_response_queue_destroy(queue_head);
1142 }
1143 }
1144
1145 if(SPDY_SESSION_STATUS_FLUSHING == session->status
1146 && NULL == session->response_queue_head)
1147 session->status = SPDY_SESSION_STATUS_CLOSING;
1148
1149 //return i>0 ? SPDY_YES : SPDY_NO;
1150 return session->fio_after_write(session, i>0 ? SPDY_YES : SPDY_NO);
1151 }
1152
1153
1154 int
SPDYF_session_idle(struct SPDY_Session * session)1155 SPDYF_session_idle (struct SPDY_Session *session)
1156 {
1157 size_t read_buffer_beginning;
1158 size_t frame_length;
1159 struct SPDYF_Control_Frame* control_frame;
1160 struct SPDYF_Data_Frame *data_frame;
1161
1162 //prepare session for closing if timeout is used and already passed
1163 if(SPDY_SESSION_STATUS_CLOSING != session->status
1164 && session->daemon->session_timeout
1165 && (session->last_activity + session->daemon->session_timeout < SPDYF_monotonic_time()))
1166 {
1167 session->status = SPDY_SESSION_STATUS_CLOSING;
1168 //best effort for sending GOAWAY
1169 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_OK, true);
1170 SPDYF_session_write(session,true);
1171 }
1172
1173 switch(session->status)
1174 {
1175 //expect new frame to arrive
1176 case SPDY_SESSION_STATUS_WAIT_FOR_HEADER:
1177 session->current_stream_id = 0;
1178 //check if the whole frame header is already here
1179 //both frame types have the same length
1180 if(session->read_buffer_offset - session->read_buffer_beginning
1181 < sizeof(struct SPDYF_Control_Frame))
1182 return SPDY_NO;
1183
1184 /* check the first bit to see if it is data or control frame
1185 * and also if the version is supported */
1186 if(0x80 == *(uint8_t *)(session->read_buffer + session->read_buffer_beginning)
1187 && SPDY_VERSION == *((uint8_t *)session->read_buffer + session->read_buffer_beginning + 1))
1188 {
1189 //control frame
1190 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
1191 {
1192 SPDYF_DEBUG("No memory");
1193 return SPDY_NO;
1194 }
1195
1196 //get frame headers
1197 memcpy(control_frame,
1198 session->read_buffer + session->read_buffer_beginning,
1199 sizeof(struct SPDYF_Control_Frame));
1200 session->read_buffer_beginning += sizeof(struct SPDYF_Control_Frame);
1201 SPDYF_CONTROL_FRAME_NTOH(control_frame);
1202
1203 session->status = SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER;
1204 //assign different frame handler according to frame type
1205 switch(control_frame->type){
1206 case SPDY_CONTROL_FRAME_TYPES_SYN_STREAM:
1207 session->frame_handler = &spdyf_handler_read_syn_stream;
1208 break;
1209 case SPDY_CONTROL_FRAME_TYPES_GOAWAY:
1210 session->frame_handler = &spdyf_handler_read_goaway;
1211 break;
1212 case SPDY_CONTROL_FRAME_TYPES_RST_STREAM:
1213 session->frame_handler = &spdyf_handler_read_rst_stream;
1214 break;
1215 default:
1216 session->frame_handler = &SPDYF_handler_ignore_frame;
1217 }
1218 session->frame_handler_cls = control_frame;
1219 //DO NOT break the outer case
1220 }
1221 else if(0 == *(uint8_t *)(session->read_buffer + session->read_buffer_beginning))
1222 {
1223 //needed for POST
1224 //data frame
1225 if(NULL == (data_frame = malloc(sizeof(struct SPDYF_Data_Frame))))
1226 {
1227 SPDYF_DEBUG("No memory");
1228 return SPDY_NO;
1229 }
1230
1231 //get frame headers
1232 memcpy(data_frame,
1233 session->read_buffer + session->read_buffer_beginning,
1234 sizeof(struct SPDYF_Data_Frame));
1235 session->read_buffer_beginning += sizeof(struct SPDYF_Data_Frame);
1236 SPDYF_DATA_FRAME_NTOH(data_frame);
1237
1238 session->status = SPDY_SESSION_STATUS_WAIT_FOR_BODY;
1239 session->frame_handler = &spdyf_handler_read_data;
1240 session->frame_handler_cls = data_frame;
1241 //DO NOT brake the outer case
1242 }
1243 else
1244 {
1245 SPDYF_DEBUG("another protocol or version received!");
1246
1247 /* According to the draft the lib should send here
1248 * RST_STREAM with status UNSUPPORTED_VERSION. I don't
1249 * see any sense of keeping the session open since
1250 * we don't know how many bytes is the bogus "frame".
1251 * And the latter normally will be HTTP request.
1252 *
1253 */
1254
1255 //shutdown(session->socket_fd, SHUT_RD);
1256 session->status = SPDY_SESSION_STATUS_FLUSHING;
1257 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_PROTOCOL_ERROR,false);
1258 //SPDYF_session_write(session,false);
1259 /* close connection since the client expects another
1260 protocol from us */
1261 //SPDYF_session_close(session);
1262 return SPDY_YES;
1263 }
1264
1265 //expect specific header fields after the standard header
1266 case SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER:
1267 if(NULL!=session->frame_handler)
1268 {
1269 read_buffer_beginning = session->read_buffer_beginning;
1270 //if everything is ok, the "body" will also be processed
1271 //by the handler
1272 session->frame_handler(session);
1273
1274 if(SPDY_SESSION_STATUS_IGNORE_BYTES == session->status)
1275 {
1276 //check for larger than max supported frame
1277 if(session->frame_handler != &spdyf_handler_read_data)
1278 {
1279 frame_length = ((struct SPDYF_Control_Frame *)session->frame_handler_cls)->length;
1280 }
1281 else
1282 {
1283 frame_length = ((struct SPDYF_Data_Frame *)session->frame_handler_cls)->length;
1284 }
1285
1286 //if(SPDY_MAX_SUPPORTED_FRAME_SIZE < frame_length)
1287 {
1288 SPDYF_DEBUG("received frame with unsupported size: %zu", frame_length);
1289 //the data being received must be ignored and
1290 //RST_STREAM sent
1291
1292 //ignore bytes that will arive later
1293 session->read_ignore_bytes = frame_length
1294 + read_buffer_beginning
1295 - session->read_buffer_offset;
1296 //ignore what is already in read buffer
1297 session->read_buffer_beginning = session->read_buffer_offset;
1298
1299 SPDYF_prepare_rst_stream(session,
1300 session->current_stream_id > 0 ? session->streams_head : NULL, //may be 0 here which is not good
1301 SPDY_RST_STREAM_STATUS_FRAME_TOO_LARGE);
1302
1303 //actually the read buffer can be bigger than the
1304 //max supported size
1305 session->status = session->read_ignore_bytes
1306 ? SPDY_SESSION_STATUS_IGNORE_BYTES
1307 : SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
1308
1309 free(session->frame_handler_cls);
1310 }
1311 }
1312 }
1313
1314 if(SPDY_SESSION_STATUS_IGNORE_BYTES != session->status)
1315 {
1316 break;
1317 }
1318
1319 //ignoring data in read buffer
1320 case SPDY_SESSION_STATUS_IGNORE_BYTES:
1321 SPDYF_ASSERT(session->read_ignore_bytes > 0,
1322 "Session is in wrong state");
1323 if(session->read_ignore_bytes
1324 > session->read_buffer_offset - session->read_buffer_beginning)
1325 {
1326 session->read_ignore_bytes -=
1327 session->read_buffer_offset - session->read_buffer_beginning;
1328 session->read_buffer_beginning = session->read_buffer_offset;
1329 }
1330 else
1331 {
1332 session->read_buffer_beginning += session->read_ignore_bytes;
1333 session->read_ignore_bytes = 0;
1334 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
1335 }
1336 break;
1337
1338 //expect frame body (name/value pairs)
1339 case SPDY_SESSION_STATUS_WAIT_FOR_BODY:
1340 if(NULL!=session->frame_handler)
1341 session->frame_handler(session);
1342 break;
1343
1344 case SPDY_SESSION_STATUS_FLUSHING:
1345
1346 return SPDY_NO;
1347
1348 //because of error the session needs to be closed
1349 case SPDY_SESSION_STATUS_CLOSING:
1350 //error should be already sent to the client
1351 SPDYF_session_close(session);
1352 return SPDY_YES;
1353 }
1354
1355 return SPDY_YES;
1356 }
1357
1358
1359 void
SPDYF_session_close(struct SPDY_Session * session)1360 SPDYF_session_close (struct SPDY_Session *session)
1361 {
1362 struct SPDY_Daemon *daemon = session->daemon;
1363 int by_client = session->read_closed ? SPDY_YES : SPDY_NO;
1364
1365 //shutdown the tls and deinit the tls context
1366 session->fio_close_session(session);
1367 shutdown (session->socket_fd,
1368 session->read_closed ? SHUT_WR : SHUT_RDWR);
1369 session->read_closed = true;
1370
1371 //remove session from the list
1372 DLL_remove (daemon->sessions_head,
1373 daemon->sessions_tail,
1374 session);
1375 //add the session for the list for cleaning up
1376 DLL_insert (daemon->cleanup_head,
1377 daemon->cleanup_tail,
1378 session);
1379
1380 //call callback for closed session
1381 if(NULL != daemon->session_closed_cb)
1382 {
1383 daemon->session_closed_cb(daemon->cls, session, by_client);
1384 }
1385 }
1386
1387
1388 int
SPDYF_session_accept(struct SPDY_Daemon * daemon)1389 SPDYF_session_accept(struct SPDY_Daemon *daemon)
1390 {
1391 int new_socket_fd;
1392 int ret;
1393 struct SPDY_Session *session = NULL;
1394 socklen_t addr_len;
1395 struct sockaddr *addr;
1396
1397 #if HAVE_INET6
1398 struct sockaddr_in6 addr6;
1399
1400 addr = (struct sockaddr *)&addr6;
1401 addr_len = sizeof(addr6);
1402 #else
1403 struct sockaddr_in addr4;
1404
1405 addr = (struct sockaddr *)&addr4;
1406 addr_len = sizeof(addr6);
1407 #endif
1408
1409 new_socket_fd = accept (daemon->socket_fd, addr, &addr_len);
1410
1411 if(new_socket_fd < 1)
1412 return SPDY_NO;
1413
1414 if (NULL == (session = malloc (sizeof (struct SPDY_Session))))
1415 {
1416 goto free_and_fail;
1417 }
1418 memset (session, 0, sizeof (struct SPDY_Session));
1419
1420 session->daemon = daemon;
1421 session->socket_fd = new_socket_fd;
1422 session->max_num_frames = daemon->max_num_frames;
1423
1424 ret = SPDYF_io_set_session(session, daemon->io_subsystem);
1425 SPDYF_ASSERT(SPDY_YES == ret, "Somehow daemon->io_subsystem iswrong here");
1426
1427 //init TLS context, handshake will be done
1428 if(SPDY_YES != session->fio_new_session(session))
1429 {
1430 goto free_and_fail;
1431 }
1432
1433 //read buffer
1434 session->read_buffer_size = SPDYF_BUFFER_SIZE;
1435 if (NULL == (session->read_buffer = malloc (session->read_buffer_size)))
1436 {
1437 session->fio_close_session(session);
1438 goto free_and_fail;
1439 }
1440
1441 //address of the client
1442 if (NULL == (session->addr = malloc (addr_len)))
1443 {
1444 session->fio_close_session(session);
1445 goto free_and_fail;
1446 }
1447 memcpy (session->addr, addr, addr_len);
1448
1449 session->addr_len = addr_len;
1450 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
1451
1452 //init zlib context for the whole session
1453 if(SPDY_YES != SPDYF_zlib_deflate_init(&session->zlib_send_stream))
1454 {
1455 session->fio_close_session(session);
1456 goto free_and_fail;
1457 }
1458 if(SPDY_YES != SPDYF_zlib_inflate_init(&session->zlib_recv_stream))
1459 {
1460 session->fio_close_session(session);
1461 SPDYF_zlib_deflate_end(&session->zlib_send_stream);
1462 goto free_and_fail;
1463 }
1464
1465 //add it to daemon's list
1466 DLL_insert(daemon->sessions_head,daemon->sessions_tail,session);
1467
1468 session->last_activity = SPDYF_monotonic_time();
1469
1470 if(NULL != daemon->new_session_cb)
1471 daemon->new_session_cb(daemon->cls, session);
1472
1473 return SPDY_YES;
1474
1475 //for GOTO
1476 free_and_fail:
1477 /* something failed, so shutdown, close and free memory */
1478 shutdown (new_socket_fd, SHUT_RDWR);
1479 (void)close (new_socket_fd);
1480
1481 if(NULL != session)
1482 {
1483 if(NULL != session->addr)
1484 free (session->addr);
1485 if(NULL != session->read_buffer)
1486 free (session->read_buffer);
1487 free (session);
1488 }
1489 return SPDY_NO;
1490 }
1491
1492
1493 void
SPDYF_queue_response(struct SPDYF_Response_Queue * response_to_queue,struct SPDY_Session * session,int consider_priority)1494 SPDYF_queue_response (struct SPDYF_Response_Queue *response_to_queue,
1495 struct SPDY_Session *session,
1496 int consider_priority)
1497 {
1498 struct SPDYF_Response_Queue *pos;
1499 struct SPDYF_Response_Queue *last;
1500 uint8_t priority;
1501
1502 SPDYF_ASSERT(SPDY_YES != consider_priority || NULL != response_to_queue->stream,
1503 "called with consider_priority but no stream provided");
1504
1505 last = response_to_queue;
1506 while(NULL != last->next)
1507 {
1508 last = last->next;
1509 }
1510
1511 if(SPDY_NO == consider_priority)
1512 {
1513 //put it at the end of the queue
1514 response_to_queue->prev = session->response_queue_tail;
1515 if (NULL == session->response_queue_head)
1516 session->response_queue_head = response_to_queue;
1517 else
1518 session->response_queue_tail->next = response_to_queue;
1519 session->response_queue_tail = last;
1520 return;
1521 }
1522 else if(-1 == consider_priority)
1523 {
1524 //put it at the head of the queue
1525 last->next = session->response_queue_head;
1526 if (NULL == session->response_queue_tail)
1527 session->response_queue_tail = last;
1528 else
1529 session->response_queue_head->prev = response_to_queue;
1530 session->response_queue_head = response_to_queue;
1531 return;
1532 }
1533
1534 if(NULL == session->response_queue_tail)
1535 {
1536 session->response_queue_head = response_to_queue;
1537 session->response_queue_tail = last;
1538 return;
1539 }
1540
1541 //search for the right position to put it
1542 pos = session->response_queue_tail;
1543 priority = response_to_queue->stream->priority;
1544 while(NULL != pos
1545 && pos->stream->priority > priority)
1546 {
1547 pos = pos->prev;
1548 }
1549
1550 if(NULL == pos)
1551 {
1552 //put it on the head
1553 session->response_queue_head->prev = last;
1554 last->next = session->response_queue_head;
1555 session->response_queue_head = response_to_queue;
1556 }
1557 else if(NULL == pos->next)
1558 {
1559 //put it at the end
1560 response_to_queue->prev = pos;
1561 pos->next = response_to_queue;
1562 session->response_queue_tail = last;
1563 }
1564 else
1565 {
1566 response_to_queue->prev = pos;
1567 last->next = pos->next;
1568 pos->next = response_to_queue;
1569 last->next->prev = last;
1570 }
1571 }
1572
1573
1574 void
SPDYF_session_destroy(struct SPDY_Session * session)1575 SPDYF_session_destroy(struct SPDY_Session *session)
1576 {
1577 struct SPDYF_Stream *stream;
1578 struct SPDYF_Response_Queue *response_queue;
1579
1580 (void)close (session->socket_fd);
1581 SPDYF_zlib_deflate_end(&session->zlib_send_stream);
1582 SPDYF_zlib_inflate_end(&session->zlib_recv_stream);
1583
1584 //clean up unsent data in the output queue
1585 while (NULL != (response_queue = session->response_queue_head))
1586 {
1587 DLL_remove (session->response_queue_head,
1588 session->response_queue_tail,
1589 response_queue);
1590
1591 if(NULL != response_queue->frqcb)
1592 {
1593 response_queue->frqcb(response_queue->frqcb_cls, response_queue, SPDY_RESPONSE_RESULT_SESSION_CLOSED);
1594 }
1595
1596 SPDYF_response_queue_destroy(response_queue);
1597 }
1598
1599 //clean up the streams belonging to this session
1600 while (NULL != (stream = session->streams_head))
1601 {
1602 DLL_remove (session->streams_head,
1603 session->streams_tail,
1604 stream);
1605
1606 SPDYF_stream_destroy(stream);
1607 }
1608
1609 free(session->addr);
1610 free(session->read_buffer);
1611 free(session->write_buffer);
1612 free(session);
1613 }
1614
1615
1616 int
SPDYF_prepare_goaway(struct SPDY_Session * session,enum SPDY_GOAWAY_STATUS status,bool in_front)1617 SPDYF_prepare_goaway (struct SPDY_Session *session,
1618 enum SPDY_GOAWAY_STATUS status,
1619 bool in_front)
1620 {
1621 struct SPDYF_Response_Queue *response_to_queue;
1622 struct SPDYF_Control_Frame *control_frame;
1623 uint32_t *data;
1624
1625 if(NULL == (response_to_queue = malloc(sizeof(struct SPDYF_Response_Queue))))
1626 {
1627 return SPDY_NO;
1628 }
1629 memset(response_to_queue, 0, sizeof(struct SPDYF_Response_Queue));
1630
1631 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
1632 {
1633 free(response_to_queue);
1634 return SPDY_NO;
1635 }
1636 memset(control_frame, 0, sizeof(struct SPDYF_Control_Frame));
1637
1638 if(NULL == (data = malloc(4)))
1639 {
1640 free(control_frame);
1641 free(response_to_queue);
1642 return SPDY_NO;
1643 }
1644 *(data) = htonl(status);
1645
1646 control_frame->control_bit = 1;
1647 control_frame->version = SPDY_VERSION;
1648 control_frame->type = SPDY_CONTROL_FRAME_TYPES_GOAWAY;
1649 control_frame->flags = 0;
1650
1651 response_to_queue->control_frame = control_frame;
1652 response_to_queue->process_response_handler = &SPDYF_handler_write_goaway;
1653 response_to_queue->data = data;
1654 response_to_queue->data_size = 4;
1655
1656 SPDYF_queue_response (response_to_queue,
1657 session,
1658 in_front ? -1 : SPDY_NO);
1659
1660 return SPDY_YES;
1661 }
1662
1663
1664 int
SPDYF_prepare_rst_stream(struct SPDY_Session * session,struct SPDYF_Stream * stream,enum SPDY_RST_STREAM_STATUS status)1665 SPDYF_prepare_rst_stream (struct SPDY_Session *session,
1666 struct SPDYF_Stream * stream,
1667 enum SPDY_RST_STREAM_STATUS status)
1668 {
1669 struct SPDYF_Response_Queue *response_to_queue;
1670 struct SPDYF_Control_Frame *control_frame;
1671 uint32_t *data;
1672 uint32_t stream_id;
1673
1674 if(NULL == stream)
1675 stream_id = 0;
1676 else
1677 stream_id = stream->stream_id;
1678
1679 if(NULL == (response_to_queue = malloc(sizeof(struct SPDYF_Response_Queue))))
1680 {
1681 return SPDY_NO;
1682 }
1683 memset(response_to_queue, 0, sizeof(struct SPDYF_Response_Queue));
1684
1685 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
1686 {
1687 free(response_to_queue);
1688 return SPDY_NO;
1689 }
1690 memset(control_frame, 0, sizeof(struct SPDYF_Control_Frame));
1691
1692 if(NULL == (data = malloc(8)))
1693 {
1694 free(control_frame);
1695 free(response_to_queue);
1696 return SPDY_NO;
1697 }
1698 *(data) = HTON31(stream_id);
1699 *(data + 1) = htonl(status);
1700
1701 control_frame->control_bit = 1;
1702 control_frame->version = SPDY_VERSION;
1703 control_frame->type = SPDY_CONTROL_FRAME_TYPES_RST_STREAM;
1704 control_frame->flags = 0;
1705
1706 response_to_queue->control_frame = control_frame;
1707 response_to_queue->process_response_handler = &SPDYF_handler_write_rst_stream;
1708 response_to_queue->data = data;
1709 response_to_queue->data_size = 8;
1710 response_to_queue->stream = stream;
1711
1712 SPDYF_queue_response (response_to_queue,
1713 session,
1714 -1);
1715
1716 return SPDY_YES;
1717 }
1718
1719
1720 int
SPDYF_prepare_window_update(struct SPDY_Session * session,struct SPDYF_Stream * stream,int32_t delta_window_size)1721 SPDYF_prepare_window_update (struct SPDY_Session *session,
1722 struct SPDYF_Stream * stream,
1723 int32_t delta_window_size)
1724 {
1725 struct SPDYF_Response_Queue *response_to_queue;
1726 struct SPDYF_Control_Frame *control_frame;
1727 uint32_t *data;
1728
1729 SPDYF_ASSERT(NULL != stream, "stream cannot be NULL");
1730
1731 if(NULL == (response_to_queue = malloc(sizeof(struct SPDYF_Response_Queue))))
1732 {
1733 return SPDY_NO;
1734 }
1735 memset(response_to_queue, 0, sizeof(struct SPDYF_Response_Queue));
1736
1737 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
1738 {
1739 free(response_to_queue);
1740 return SPDY_NO;
1741 }
1742 memset(control_frame, 0, sizeof(struct SPDYF_Control_Frame));
1743
1744 if(NULL == (data = malloc(8)))
1745 {
1746 free(control_frame);
1747 free(response_to_queue);
1748 return SPDY_NO;
1749 }
1750 *(data) = HTON31(stream->stream_id);
1751 *(data + 1) = HTON31(delta_window_size);
1752
1753 control_frame->control_bit = 1;
1754 control_frame->version = SPDY_VERSION;
1755 control_frame->type = SPDY_CONTROL_FRAME_TYPES_WINDOW_UPDATE;
1756 control_frame->flags = 0;
1757
1758 response_to_queue->control_frame = control_frame;
1759 response_to_queue->process_response_handler = &SPDYF_handler_write_window_update;
1760 response_to_queue->data = data;
1761 response_to_queue->data_size = 8;
1762 response_to_queue->stream = stream;
1763
1764 SPDYF_queue_response (response_to_queue,
1765 session,
1766 -1);
1767
1768 return SPDY_YES;
1769 }
1770