00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00026 #include "platform.h"
00027 #include "structures.h"
00028 #include "internal.h"
00029 #include "session.h"
00030 #include "compression.h"
00031 #include "stream.h"
00032 #include "io.h"
00033
00034
00043 static void
00044 spdyf_handler_read_syn_stream (struct SPDY_Session *session)
00045 {
00046 size_t name_value_strm_size = 0;
00047 unsigned int compressed_data_size;
00048 int ret;
00049 void *name_value_strm = NULL;
00050 struct SPDYF_Control_Frame *frame;
00051 struct SPDY_NameValue *headers;
00052
00053 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status
00054 || SPDY_SESSION_STATUS_WAIT_FOR_BODY == session->status,
00055 "the function is called wrong");
00056
00057 frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
00058
00059
00060 if(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status)
00061 {
00062 if(0 == frame->length)
00063 {
00064
00065
00066
00067
00068 SPDYF_DEBUG("zero long SYN_STREAM received");
00069 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
00070 free(frame);
00071 return;
00072 }
00073
00074 if(SPDY_YES != SPDYF_stream_new(session))
00075 {
00076
00077
00078
00079 return;
00080 }
00081
00082 session->current_stream_id = session->streams_head->stream_id;
00083 if(frame->length > SPDY_MAX_SUPPORTED_FRAME_SIZE)
00084 {
00085
00086 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
00087 return;
00088 }
00089 else
00090 session->status = SPDY_SESSION_STATUS_WAIT_FOR_BODY;
00091 }
00092
00093
00094
00095
00096 compressed_data_size = frame->length
00097 - 10;
00098
00099 if(session->read_buffer_offset - session->read_buffer_beginning < compressed_data_size)
00100 {
00101
00102 return;
00103 }
00104
00105 if(compressed_data_size > 0
00106 && SPDY_YES != SPDYF_zlib_inflate(&session->zlib_recv_stream,
00107 session->read_buffer + session->read_buffer_beginning,
00108 compressed_data_size,
00109 &name_value_strm,
00110 &name_value_strm_size))
00111 {
00112
00113
00114
00115
00116
00117 free(name_value_strm);
00118 free(frame);
00119
00120
00121
00122 session->status = SPDY_SESSION_STATUS_FLUSHING;
00123
00124 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_INTERNAL_ERROR, false);
00125
00126 return;
00127 }
00128
00129 if(0 == name_value_strm_size || 0 == compressed_data_size)
00130 {
00131
00132 if(SPDY_YES != SPDYF_prepare_rst_stream(session, session->streams_head,
00133 SPDY_RST_STREAM_STATUS_PROTOCOL_ERROR))
00134 {
00135
00136 return;
00137 }
00138 }
00139 else
00140 {
00141 ret = SPDYF_name_value_from_stream(name_value_strm, name_value_strm_size, &headers);
00142 if(SPDY_NO == ret)
00143 {
00144
00145 free(name_value_strm);
00146 return;
00147 }
00148
00149 session->streams_head->headers = headers;
00150
00151 if(SPDY_YES != session->daemon->fnew_stream_cb(session->daemon->fcls, session->streams_head))
00152 {
00153
00154 free(name_value_strm);
00155 return;
00156 }
00157
00158 session->read_buffer_beginning += compressed_data_size;
00159 free(name_value_strm);
00160 }
00161
00162
00163
00164
00165 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
00166 free(frame);
00167 }
00168
00169
00178 static void
00179 spdyf_handler_read_goaway (struct SPDY_Session *session)
00180 {
00181 struct SPDYF_Control_Frame *frame;
00182 uint32_t last_good_stream_id;
00183 uint32_t status_int;
00184 enum SPDY_GOAWAY_STATUS status;
00185
00186 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status,
00187 "the function is called wrong");
00188
00189 frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
00190
00191 if(frame->length > SPDY_MAX_SUPPORTED_FRAME_SIZE)
00192 {
00193
00194 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
00195 return;
00196 }
00197
00198 if(0 != frame->flags || 8 != frame->length)
00199 {
00200
00201 SPDYF_DEBUG("wrong GOAWAY received");
00202
00203 }
00204
00205 if((session->read_buffer_offset - session->read_buffer_beginning) < frame->length)
00206 {
00207
00208
00209 return;
00210 }
00211
00212
00213 session->is_goaway_received = true;
00214
00215 if(8 == frame->length)
00216 {
00217 memcpy(&last_good_stream_id, session->read_buffer + session->read_buffer_beginning, 4);
00218 last_good_stream_id = NTOH31(last_good_stream_id);
00219 session->read_buffer_beginning += 4;
00220
00221 memcpy(&status_int, session->read_buffer + session->read_buffer_beginning, 4);
00222 status = ntohl(status_int);
00223 session->read_buffer_beginning += 4;
00224
00225
00226
00227
00228
00229
00230
00231 switch(status)
00232 {
00233 case SPDY_GOAWAY_STATUS_OK:
00234 break;
00235 case SPDY_GOAWAY_STATUS_PROTOCOL_ERROR:
00236 break;
00237 case SPDY_GOAWAY_STATUS_INTERNAL_ERROR:
00238 break;
00239 }
00240
00241
00242 }
00243
00244 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
00245 free(frame);
00246 }
00247
00248
00257 static void
00258 spdyf_handler_read_rst_stream (struct SPDY_Session *session)
00259 {
00260 struct SPDYF_Control_Frame *frame;
00261 uint32_t stream_id;
00262 int32_t status_int;
00263
00264 struct SPDYF_Stream *stream;
00265
00266 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status,
00267 "the function is called wrong");
00268
00269 frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
00270
00271 if(0 != frame->flags || 8 != frame->length)
00272 {
00273
00274 SPDYF_DEBUG("wrong RST_STREAM received");
00275
00276 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
00277 return;
00278 }
00279
00280 if((session->read_buffer_offset - session->read_buffer_beginning) < frame->length)
00281 {
00282
00283
00284 return;
00285 }
00286
00287 memcpy(&stream_id, session->read_buffer + session->read_buffer_beginning, 4);
00288 stream_id = NTOH31(stream_id);
00289 session->read_buffer_beginning += 4;
00290
00291 memcpy(&status_int, session->read_buffer + session->read_buffer_beginning, 4);
00292
00293 session->read_buffer_beginning += 4;
00294
00295 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
00296 free(frame);
00297
00298
00299 stream = session->streams_head;
00300 while(NULL != stream)
00301 {
00302 if(stream_id == stream->stream_id)
00303 {
00304 stream->is_in_closed = true;
00305 stream->is_out_closed = true;
00306 break;
00307 }
00308 stream = stream->next;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 }
00321
00322
00329 static void
00330 spdyf_handler_read_data (struct SPDY_Session *session)
00331 {
00332 int ret;
00333 struct SPDYF_Data_Frame * frame;
00334 struct SPDYF_Stream * stream;
00335
00336 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status
00337 || SPDY_SESSION_STATUS_WAIT_FOR_BODY == session->status,
00338 "the function is called wrong");
00339
00340
00341
00342
00343
00344 frame = (struct SPDYF_Data_Frame *)session->frame_handler_cls;
00345
00346
00347 if(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status)
00348 {
00349 if(frame->length > SPDY_MAX_SUPPORTED_FRAME_SIZE)
00350 {
00351 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
00352 return;
00353 }
00354 else
00355 session->status = SPDY_SESSION_STATUS_WAIT_FOR_BODY;
00356 }
00357
00358
00359
00360 if(session->read_buffer_offset - session->read_buffer_beginning
00361 >= frame->length)
00362 {
00363 stream = SPDYF_stream_find(frame->stream_id, session);
00364
00365 if(NULL == stream || stream->is_in_closed || NULL == session->daemon->received_data_cb)
00366 {
00367 if(NULL == session->daemon->received_data_cb)
00368 SPDYF_DEBUG("No callback for DATA frame set; Ignoring DATA frame!");
00369
00370
00371
00372
00373 session->read_buffer_beginning += frame->length;
00374 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
00375 free(frame);
00376 return;
00377 }
00378
00379 ret = session->daemon->freceived_data_cb(session->daemon->cls,
00380 stream,
00381 session->read_buffer + session->read_buffer_beginning,
00382 frame->length,
00383 0 == (SPDY_DATA_FLAG_FIN & frame->flags));
00384
00385 session->read_buffer_beginning += frame->length;
00386
00387 stream->window_size -= frame->length;
00388
00389
00390 SPDYF_ASSERT(SPDY_YES == ret, "Cancel POST data is not yet implemented");
00391
00392 if(SPDY_DATA_FLAG_FIN & frame->flags)
00393 {
00394 stream->is_in_closed = true;
00395 }
00396 else if(stream->window_size < SPDYF_INITIAL_WINDOW_SIZE / 2)
00397 {
00398
00399
00400
00401
00402
00403 if(SPDY_YES == SPDYF_prepare_window_update(session, stream,
00404 SPDYF_INITIAL_WINDOW_SIZE - stream->window_size))
00405 {
00406 stream->window_size = SPDYF_INITIAL_WINDOW_SIZE;
00407 }
00408
00409 }
00410
00411
00412
00413 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
00414 free(frame);
00415 }
00416 }
00417
00418
00419 int
00420 SPDYF_handler_write_syn_reply (struct SPDY_Session *session)
00421 {
00422 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
00423 struct SPDYF_Stream *stream = response_queue->stream;
00424 struct SPDYF_Control_Frame control_frame;
00425 void *compressed_headers = NULL;
00426 size_t compressed_headers_size=0;
00427 size_t used_data=0;
00428 size_t total_size;
00429 uint32_t stream_id_nbo;
00430
00431 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
00432
00433 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
00434
00435 if(SPDY_YES != SPDYF_zlib_deflate(&session->zlib_send_stream,
00436 response_queue->data,
00437 response_queue->data_size,
00438 &used_data,
00439 &compressed_headers,
00440 &compressed_headers_size))
00441 {
00442
00443
00444
00445
00446
00447 session->status = SPDY_SESSION_STATUS_CLOSING;
00448
00449 free(compressed_headers);
00450
00451 return SPDY_NO;
00452 }
00453
00454
00455 SPDYF_ASSERT(used_data == response_queue->data_size, "not everything was used by zlib");
00456
00457 total_size = sizeof(struct SPDYF_Control_Frame)
00458 + 4
00459 + compressed_headers_size;
00460
00461 if(NULL == (session->write_buffer = malloc(total_size)))
00462 {
00463
00464
00465
00466
00467 session->status = SPDY_SESSION_STATUS_CLOSING;
00468
00469 free(compressed_headers);
00470
00471 return SPDY_NO;
00472 }
00473 session->write_buffer_beginning = 0;
00474 session->write_buffer_offset = 0;
00475 session->write_buffer_size = total_size;
00476
00477 control_frame.length = compressed_headers_size + 4;
00478 SPDYF_CONTROL_FRAME_HTON(&control_frame);
00479
00480
00481 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
00482 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
00483
00484
00485 stream_id_nbo = HTON31(stream->stream_id);
00486 memcpy(session->write_buffer + session->write_buffer_offset, &stream_id_nbo, 4);
00487 session->write_buffer_offset += 4;
00488
00489
00490 memcpy(session->write_buffer + session->write_buffer_offset, compressed_headers, compressed_headers_size);
00491 session->write_buffer_offset += compressed_headers_size;
00492
00493 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
00494 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 free(compressed_headers);
00505
00506 session->last_replied_to_stream_id = stream->stream_id;
00507
00508
00509
00510 return SPDY_YES;
00511 }
00512
00513
00514 int
00515 SPDYF_handler_write_goaway (struct SPDY_Session *session)
00516 {
00517 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
00518 struct SPDYF_Control_Frame control_frame;
00519 size_t total_size;
00520 int last_good_stream_id;
00521
00522 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
00523
00524 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
00525
00526 session->is_goaway_sent = true;
00527
00528 total_size = sizeof(struct SPDYF_Control_Frame)
00529 + 4
00530 + 4;
00531
00532 if(NULL == (session->write_buffer = malloc(total_size)))
00533 {
00534 return SPDY_NO;
00535 }
00536 session->write_buffer_beginning = 0;
00537 session->write_buffer_offset = 0;
00538 session->write_buffer_size = total_size;
00539
00540 control_frame.length = 8;
00541 SPDYF_CONTROL_FRAME_HTON(&control_frame);
00542
00543
00544 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
00545 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
00546
00547
00548 last_good_stream_id = HTON31(session->last_replied_to_stream_id);
00549 memcpy(session->write_buffer + session->write_buffer_offset, &last_good_stream_id, 4);
00550 session->write_buffer_offset += 4;
00551
00552
00553 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, 4);
00554 session->write_buffer_offset += 4;
00555
00556
00557
00558
00559
00560 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
00561 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
00562
00563 return SPDY_YES;
00564 }
00565
00566
00567 int
00568 SPDYF_handler_write_data (struct SPDY_Session *session)
00569 {
00570 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
00571 struct SPDYF_Response_Queue *new_response_queue;
00572 size_t total_size;
00573 struct SPDYF_Data_Frame data_frame;
00574 ssize_t ret;
00575 bool more;
00576
00577 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
00578
00579 memcpy(&data_frame, response_queue->data_frame, sizeof(data_frame));
00580
00581 if(NULL == response_queue->response->rcb)
00582 {
00583
00584 SPDYF_ASSERT(NULL != response_queue->data, "no data for the response");
00585
00586 total_size = sizeof(struct SPDYF_Data_Frame)
00587 + response_queue->data_size;
00588
00589 if(NULL == (session->write_buffer = malloc(total_size)))
00590 {
00591 return SPDY_NO;
00592 }
00593 session->write_buffer_beginning = 0;
00594 session->write_buffer_offset = 0;
00595 session->write_buffer_size = total_size;
00596
00597 data_frame.length = response_queue->data_size;
00598 SPDYF_DATA_FRAME_HTON(&data_frame);
00599
00600
00601 memcpy(session->write_buffer + session->write_buffer_offset,&data_frame,sizeof(struct SPDYF_Data_Frame));
00602 session->write_buffer_offset += sizeof(struct SPDYF_Data_Frame);
00603
00604
00605 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, response_queue->data_size);
00606 session->write_buffer_offset += response_queue->data_size;
00607 }
00608 else
00609 {
00610
00611
00612
00613
00614 total_size = sizeof(struct SPDYF_Data_Frame)
00615 + SPDY_MAX_SUPPORTED_FRAME_SIZE;
00616
00617 if(NULL == (session->write_buffer = malloc(total_size)))
00618 {
00619 return SPDY_NO;
00620 }
00621 session->write_buffer_beginning = 0;
00622 session->write_buffer_offset = 0;
00623 session->write_buffer_size = total_size;
00624
00625 ret = response_queue->response->rcb(response_queue->response->rcb_cls,
00626 session->write_buffer + sizeof(struct SPDYF_Data_Frame),
00627 response_queue->response->rcb_block_size,
00628 &more);
00629
00630 if(ret < 0 || ret > response_queue->response->rcb_block_size)
00631 {
00632 free(session->write_buffer);
00633 session->write_buffer = NULL;
00634
00635
00636 if(SPDY_YES == (ret = SPDYF_prepare_rst_stream(session,
00637 response_queue->stream,
00638 SPDY_RST_STREAM_STATUS_INTERNAL_ERROR)))
00639 {
00640 return SPDY_NO;
00641 }
00642
00643
00644
00645
00646 session->status = SPDY_SESSION_STATUS_CLOSING;
00647
00648 return SPDY_NO;
00649 }
00650 if(0 == ret && more)
00651 {
00652
00653 free(session->write_buffer);
00654 session->write_buffer = NULL;
00655 session->write_buffer_size = 0;
00656
00657 if(NULL != response_queue->next)
00658 {
00659
00660
00661 session->response_queue_head = response_queue->next;
00662 session->response_queue_head->prev = NULL;
00663 session->response_queue_tail->next = response_queue;
00664 response_queue->prev = session->response_queue_tail;
00665 response_queue->next = NULL;
00666 session->response_queue_tail = response_queue;
00667 }
00668
00669 return SPDY_YES;
00670 }
00671
00672 if(more)
00673 {
00674
00675 if(NULL == (new_response_queue = SPDYF_response_queue_create(true,
00676 NULL,
00677 0,
00678 response_queue->response,
00679 response_queue->stream,
00680 false,
00681 response_queue->frqcb,
00682 response_queue->frqcb_cls,
00683 response_queue->rrcb,
00684 response_queue->rrcb_cls)))
00685 {
00686
00687
00688 session->status = SPDY_SESSION_STATUS_CLOSING;
00689
00690 free(session->write_buffer);
00691 session->write_buffer = NULL;
00692 return SPDY_NO;
00693 }
00694
00695
00696 new_response_queue->prev = response_queue;
00697 new_response_queue->next = response_queue->next;
00698 if(NULL == response_queue->next)
00699 {
00700 session->response_queue_tail = new_response_queue;
00701 }
00702 else
00703 {
00704 response_queue->next->prev = new_response_queue;
00705 }
00706 response_queue->next = new_response_queue;
00707
00708 response_queue->frqcb = NULL;
00709 response_queue->frqcb_cls = NULL;
00710 response_queue->rrcb = NULL;
00711 response_queue->rrcb_cls = NULL;
00712 }
00713 else
00714 {
00715 data_frame.flags |= SPDY_DATA_FLAG_FIN;
00716 }
00717
00718 data_frame.length = ret;
00719 SPDYF_DATA_FRAME_HTON(&data_frame);
00720
00721
00722 memcpy(session->write_buffer + session->write_buffer_offset,
00723 &data_frame,
00724 sizeof(struct SPDYF_Data_Frame));
00725 session->write_buffer_offset += sizeof(struct SPDYF_Data_Frame);
00726 session->write_buffer_offset += ret;
00727 session->write_buffer_size = session->write_buffer_offset;
00728 }
00729
00730
00731
00732 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
00733 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
00734
00735 return SPDY_YES;
00736 }
00737
00738
00739 int
00740 SPDYF_handler_write_rst_stream (struct SPDY_Session *session)
00741 {
00742 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
00743 struct SPDYF_Control_Frame control_frame;
00744 size_t total_size;
00745
00746 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
00747
00748 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
00749
00750 total_size = sizeof(struct SPDYF_Control_Frame)
00751 + 4
00752 + 4;
00753
00754 if(NULL == (session->write_buffer = malloc(total_size)))
00755 {
00756 return SPDY_NO;
00757 }
00758 session->write_buffer_beginning = 0;
00759 session->write_buffer_offset = 0;
00760 session->write_buffer_size = total_size;
00761
00762 control_frame.length = 8;
00763 SPDYF_CONTROL_FRAME_HTON(&control_frame);
00764
00765
00766 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
00767 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
00768
00769
00770 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, 8);
00771 session->write_buffer_offset += 8;
00772
00773
00774
00775
00776
00777 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
00778 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
00779
00780 return SPDY_YES;
00781 }
00782
00783
00784 int
00785 SPDYF_handler_write_window_update (struct SPDY_Session *session)
00786 {
00787 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
00788 struct SPDYF_Control_Frame control_frame;
00789 size_t total_size;
00790
00791 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
00792
00793 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
00794
00795 total_size = sizeof(struct SPDYF_Control_Frame)
00796 + 4
00797 + 4;
00798
00799 if(NULL == (session->write_buffer = malloc(total_size)))
00800 {
00801 return SPDY_NO;
00802 }
00803 session->write_buffer_beginning = 0;
00804 session->write_buffer_offset = 0;
00805 session->write_buffer_size = total_size;
00806
00807 control_frame.length = 8;
00808 SPDYF_CONTROL_FRAME_HTON(&control_frame);
00809
00810
00811 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
00812 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
00813
00814
00815 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, 8);
00816 session->write_buffer_offset += 8;
00817
00818
00819
00820 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
00821 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
00822
00823 return SPDY_YES;
00824 }
00825
00826
00827 void
00828 SPDYF_handler_ignore_frame (struct SPDY_Session *session)
00829 {
00830 struct SPDYF_Control_Frame *frame;
00831
00832 SPDYF_ASSERT(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status
00833 || SPDY_SESSION_STATUS_WAIT_FOR_BODY == session->status,
00834 "the function is called wrong");
00835
00836
00837 frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
00838
00839
00840 if(SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER == session->status)
00841 {
00842 if(frame->length > SPDY_MAX_SUPPORTED_FRAME_SIZE)
00843 {
00844 session->status = SPDY_SESSION_STATUS_IGNORE_BYTES;
00845 return;
00846 }
00847 else
00848 session->status = SPDY_SESSION_STATUS_WAIT_FOR_BODY;
00849 }
00850
00851
00852
00853 if(session->read_buffer_offset - session->read_buffer_beginning
00854 >= frame->length)
00855 {
00856 session->read_buffer_beginning += frame->length;
00857 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
00858 free(frame);
00859 }
00860 }
00861
00862
00863 int
00864 SPDYF_session_read (struct SPDY_Session *session)
00865 {
00866 int bytes_read;
00867 bool reallocate;
00868 size_t actual_buf_size;
00869
00870 if(SPDY_SESSION_STATUS_CLOSING == session->status
00871 || SPDY_SESSION_STATUS_FLUSHING == session->status)
00872 return SPDY_NO;
00873
00874
00875 if (session->read_buffer_size == session->read_buffer_offset)
00876 {
00877
00878
00879 reallocate = false;
00880 actual_buf_size = session->read_buffer_offset
00881 - session->read_buffer_beginning;
00882 switch(session->status)
00883 {
00884 case SPDY_SESSION_STATUS_WAIT_FOR_HEADER:
00885
00886 case SPDY_SESSION_STATUS_IGNORE_BYTES:
00887
00888 if(actual_buf_size < sizeof(struct SPDYF_Control_Frame))
00889 reallocate = true;
00890 break;
00891
00892 case SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER:
00893
00894 case SPDY_SESSION_STATUS_WAIT_FOR_BODY:
00895
00896
00897 SPDYF_ASSERT(NULL != session->frame_handler_cls,
00898 "no frame for session");
00899 if(session->frame_handler != &spdyf_handler_read_data)
00900 {
00901 if(actual_buf_size
00902 < ((struct SPDYF_Control_Frame *)session->frame_handler_cls)->length)
00903 reallocate = true;
00904 }
00905 else
00906 {
00907 if(actual_buf_size
00908 < ((struct SPDYF_Data_Frame *)session->frame_handler_cls)->length)
00909 reallocate = true;
00910 }
00911 break;
00912
00913 case SPDY_SESSION_STATUS_CLOSING:
00914 case SPDY_SESSION_STATUS_FLUSHING:
00915
00916 break;
00917 }
00918
00919 if(reallocate)
00920 {
00921
00922 memmove(session->read_buffer,
00923 session->read_buffer + session->read_buffer_beginning,
00924 session->read_buffer_offset - session->read_buffer_beginning);
00925
00926 session->read_buffer_offset -= session->read_buffer_beginning;
00927 session->read_buffer_beginning = 0;
00928 }
00929 else
00930 {
00931
00932
00933 return SPDY_NO;
00934 }
00935 }
00936
00937 session->last_activity = SPDYF_monotonic_time();
00938
00939
00940 bytes_read = session->fio_recv(session,
00941 session->read_buffer + session->read_buffer_offset,
00942 session->read_buffer_size - session->read_buffer_offset);
00943
00944 switch(bytes_read)
00945 {
00946 case SPDY_IO_ERROR_CLOSED:
00947
00948
00949 shutdown (session->socket_fd, SHUT_RD);
00950 session->read_closed = true;
00951 session->status = SPDY_SESSION_STATUS_CLOSING;
00952 return SPDY_YES;
00953
00954 case SPDY_IO_ERROR_ERROR:
00955
00956
00957 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_INTERNAL_ERROR, false);
00958
00959 session->status = SPDY_SESSION_STATUS_FLUSHING;
00960 return SPDY_YES;
00961
00962 case SPDY_IO_ERROR_AGAIN:
00963
00964
00965 return SPDY_NO;
00966
00967
00968
00969
00970 }
00971
00972 session->read_buffer_offset += bytes_read;
00973
00974 return SPDY_YES;
00975 }
00976
00977
00978 int
00979 SPDYF_session_write (struct SPDY_Session *session,
00980 bool only_one_frame)
00981 {
00982 unsigned int i;
00983 int bytes_written;
00984 struct SPDYF_Response_Queue *queue_head;
00985 struct SPDYF_Response_Queue *response_queue;
00986
00987 if(SPDY_SESSION_STATUS_CLOSING == session->status)
00988 return SPDY_NO;
00989
00990 if(SPDY_NO == session->fio_before_write(session))
00991 return SPDY_NO;
00992
00993 for(i=0;
00994 only_one_frame
00995 ? i < 1
00996 : i < session->max_num_frames;
00997 ++i)
00998 {
00999
01000
01001 if(NULL == session->write_buffer)
01002 {
01003
01004 response_queue = session->response_queue_head;
01005
01006 while(NULL != response_queue)
01007 {
01008
01009
01010
01011
01012 if(NULL == response_queue->stream
01013 || !response_queue->stream->is_out_closed)
01014 break;
01015
01016 DLL_remove(session->response_queue_head,session->response_queue_tail,response_queue);
01017
01018 if(NULL != response_queue->frqcb)
01019 {
01020 response_queue->frqcb(response_queue->frqcb_cls, response_queue, SPDY_RESPONSE_RESULT_STREAM_CLOSED);
01021 }
01022
01023 SPDYF_response_queue_destroy(response_queue);
01024 response_queue = session->response_queue_head;
01025 }
01026
01027 if(NULL == session->response_queue_head)
01028 break;
01029
01030
01031
01032 if(SPDY_NO == session->response_queue_head->process_response_handler(session))
01033 {
01034
01035
01036 if(SPDY_SESSION_STATUS_CLOSING == session->status)
01037 {
01038
01039 if(session->response_queue_head->is_data
01040 || SPDY_CONTROL_FRAME_TYPES_GOAWAY
01041 != session->response_queue_head->control_frame->type)
01042 {
01043 session->status = SPDY_SESSION_STATUS_FLUSHING;
01044 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_INTERNAL_ERROR, true);
01045 SPDYF_session_write(session,true);
01046 session->status = SPDY_SESSION_STATUS_CLOSING;
01047 }
01048 return SPDY_YES;
01049 }
01050
01051
01052 ++i;
01053 break;
01054 }
01055
01056
01057
01058
01059 if(0 == session->write_buffer_size)
01060 {
01061 if(response_queue != session->response_queue_head)
01062 {
01063
01064 continue;
01065 }
01066 else
01067 {
01068
01069 ++i;
01070 break;
01071 }
01072 }
01073 }
01074
01075 session->last_activity = SPDYF_monotonic_time();
01076
01077
01078 bytes_written = session->fio_send(session,
01079 session->write_buffer + session->write_buffer_beginning,
01080 session->write_buffer_offset - session->write_buffer_beginning);
01081
01082 switch(bytes_written)
01083 {
01084 case SPDY_IO_ERROR_CLOSED:
01085
01086
01087 shutdown (session->socket_fd, SHUT_RD);
01088 session->read_closed = true;
01089 session->status = SPDY_SESSION_STATUS_CLOSING;
01090 return SPDY_YES;
01091
01092 case SPDY_IO_ERROR_ERROR:
01093
01094
01095 session->status = SPDY_SESSION_STATUS_CLOSING;
01096 return SPDY_YES;
01097
01098 case SPDY_IO_ERROR_AGAIN:
01099
01100
01101
01102 return i>0 ? SPDY_YES : SPDY_NO;
01103
01104
01105
01106
01107 }
01108
01109 session->write_buffer_beginning += bytes_written;
01110
01111
01112 if(session->write_buffer_beginning == session->write_buffer_size)
01113 {
01114
01115 free(session->write_buffer);
01116 session->write_buffer = NULL;
01117 session->write_buffer_size = 0;
01118 queue_head = session->response_queue_head;
01119 if(NULL == queue_head->next)
01120 {
01121 session->response_queue_head = NULL;
01122 session->response_queue_tail = NULL;
01123 }
01124 else
01125 {
01126 session->response_queue_head = queue_head->next;
01127 session->response_queue_head->prev = NULL;
01128 }
01129
01130
01131 SPDYF_stream_set_flags_on_write(queue_head);
01132
01133 if(NULL != queue_head->frqcb)
01134 {
01135
01136 queue_head->frqcb(queue_head->frqcb_cls, queue_head, SPDY_RESPONSE_RESULT_SUCCESS);
01137 }
01138
01139 SPDYF_response_queue_destroy(queue_head);
01140 }
01141 }
01142
01143 if(SPDY_SESSION_STATUS_FLUSHING == session->status
01144 && NULL == session->response_queue_head)
01145 session->status = SPDY_SESSION_STATUS_CLOSING;
01146
01147
01148 return session->fio_after_write(session, i>0 ? SPDY_YES : SPDY_NO);
01149 }
01150
01151
01152 int
01153 SPDYF_session_idle (struct SPDY_Session *session)
01154 {
01155 size_t read_buffer_beginning;
01156 size_t frame_length;
01157 struct SPDYF_Control_Frame* control_frame;
01158 struct SPDYF_Data_Frame *data_frame;
01159
01160
01161 if(SPDY_SESSION_STATUS_CLOSING != session->status
01162 && session->daemon->session_timeout
01163 && (session->last_activity + session->daemon->session_timeout < SPDYF_monotonic_time()))
01164 {
01165 session->status = SPDY_SESSION_STATUS_CLOSING;
01166
01167 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_OK, true);
01168 SPDYF_session_write(session,true);
01169 }
01170
01171 switch(session->status)
01172 {
01173
01174 case SPDY_SESSION_STATUS_WAIT_FOR_HEADER:
01175 session->current_stream_id = 0;
01176
01177
01178 if(session->read_buffer_offset - session->read_buffer_beginning
01179 < sizeof(struct SPDYF_Control_Frame))
01180 return SPDY_NO;
01181
01182
01183
01184 if(0x80 == *(uint8_t *)(session->read_buffer + session->read_buffer_beginning)
01185 && SPDY_VERSION == *((uint8_t *)session->read_buffer + session->read_buffer_beginning + 1))
01186 {
01187
01188 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
01189 {
01190 SPDYF_DEBUG("No memory");
01191 return SPDY_NO;
01192 }
01193
01194
01195 memcpy(control_frame,
01196 session->read_buffer + session->read_buffer_beginning,
01197 sizeof(struct SPDYF_Control_Frame));
01198 session->read_buffer_beginning += sizeof(struct SPDYF_Control_Frame);
01199 SPDYF_CONTROL_FRAME_NTOH(control_frame);
01200
01201 session->status = SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER;
01202
01203 switch(control_frame->type){
01204 case SPDY_CONTROL_FRAME_TYPES_SYN_STREAM:
01205 session->frame_handler = &spdyf_handler_read_syn_stream;
01206 break;
01207 case SPDY_CONTROL_FRAME_TYPES_GOAWAY:
01208 session->frame_handler = &spdyf_handler_read_goaway;
01209 break;
01210 case SPDY_CONTROL_FRAME_TYPES_RST_STREAM:
01211 session->frame_handler = &spdyf_handler_read_rst_stream;
01212 break;
01213 default:
01214 session->frame_handler = &SPDYF_handler_ignore_frame;
01215 }
01216 session->frame_handler_cls = control_frame;
01217
01218 }
01219 else if(0 == *(uint8_t *)(session->read_buffer + session->read_buffer_beginning))
01220 {
01221
01222
01223 if(NULL == (data_frame = malloc(sizeof(struct SPDYF_Data_Frame))))
01224 {
01225 SPDYF_DEBUG("No memory");
01226 return SPDY_NO;
01227 }
01228
01229
01230 memcpy(data_frame,
01231 session->read_buffer + session->read_buffer_beginning,
01232 sizeof(struct SPDYF_Data_Frame));
01233 session->read_buffer_beginning += sizeof(struct SPDYF_Data_Frame);
01234 SPDYF_DATA_FRAME_NTOH(data_frame);
01235
01236 session->status = SPDY_SESSION_STATUS_WAIT_FOR_BODY;
01237 session->frame_handler = &spdyf_handler_read_data;
01238 session->frame_handler_cls = data_frame;
01239
01240 }
01241 else
01242 {
01243 SPDYF_DEBUG("another protocol or version received!");
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254 session->status = SPDY_SESSION_STATUS_FLUSHING;
01255 SPDYF_prepare_goaway(session, SPDY_GOAWAY_STATUS_PROTOCOL_ERROR,false);
01256
01257
01258
01259
01260 return SPDY_YES;
01261 }
01262
01263
01264 case SPDY_SESSION_STATUS_WAIT_FOR_SUBHEADER:
01265 if(NULL!=session->frame_handler)
01266 {
01267 read_buffer_beginning = session->read_buffer_beginning;
01268
01269
01270 session->frame_handler(session);
01271
01272 if(SPDY_SESSION_STATUS_IGNORE_BYTES == session->status)
01273 {
01274
01275 if(session->frame_handler != &spdyf_handler_read_data)
01276 {
01277 frame_length = ((struct SPDYF_Control_Frame *)session->frame_handler_cls)->length;
01278 }
01279 else
01280 {
01281 frame_length = ((struct SPDYF_Data_Frame *)session->frame_handler_cls)->length;
01282 }
01283
01284
01285 {
01286 SPDYF_DEBUG("received frame with unsupported size: %zu", frame_length);
01287
01288
01289
01290
01291 session->read_ignore_bytes = frame_length
01292 + read_buffer_beginning
01293 - session->read_buffer_offset;
01294
01295 session->read_buffer_beginning = session->read_buffer_offset;
01296
01297 SPDYF_prepare_rst_stream(session,
01298 session->current_stream_id > 0 ? session->streams_head : NULL,
01299 SPDY_RST_STREAM_STATUS_FRAME_TOO_LARGE);
01300
01301
01302
01303 session->status = session->read_ignore_bytes
01304 ? SPDY_SESSION_STATUS_IGNORE_BYTES
01305 : SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
01306
01307 free(session->frame_handler_cls);
01308 }
01309 }
01310 }
01311
01312 if(SPDY_SESSION_STATUS_IGNORE_BYTES != session->status)
01313 {
01314 break;
01315 }
01316
01317
01318 case SPDY_SESSION_STATUS_IGNORE_BYTES:
01319 SPDYF_ASSERT(session->read_ignore_bytes > 0,
01320 "Session is in wrong state");
01321 if(session->read_ignore_bytes
01322 > session->read_buffer_offset - session->read_buffer_beginning)
01323 {
01324 session->read_ignore_bytes -=
01325 session->read_buffer_offset - session->read_buffer_beginning;
01326 session->read_buffer_beginning = session->read_buffer_offset;
01327 }
01328 else
01329 {
01330 session->read_buffer_beginning += session->read_ignore_bytes;
01331 session->read_ignore_bytes = 0;
01332 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
01333 }
01334 break;
01335
01336
01337 case SPDY_SESSION_STATUS_WAIT_FOR_BODY:
01338 if(NULL!=session->frame_handler)
01339 session->frame_handler(session);
01340 break;
01341
01342 case SPDY_SESSION_STATUS_FLUSHING:
01343
01344 return SPDY_NO;
01345
01346
01347 case SPDY_SESSION_STATUS_CLOSING:
01348
01349 SPDYF_session_close(session);
01350 return SPDY_YES;
01351 }
01352
01353 return SPDY_YES;
01354 }
01355
01356
01357 void
01358 SPDYF_session_close (struct SPDY_Session *session)
01359 {
01360 struct SPDY_Daemon *daemon = session->daemon;
01361 int by_client = session->read_closed ? SPDY_YES : SPDY_NO;
01362
01363
01364 session->fio_close_session(session);
01365 shutdown (session->socket_fd,
01366 session->read_closed ? SHUT_WR : SHUT_RDWR);
01367 session->read_closed = true;
01368
01369
01370 DLL_remove (daemon->sessions_head,
01371 daemon->sessions_tail,
01372 session);
01373
01374 DLL_insert (daemon->cleanup_head,
01375 daemon->cleanup_tail,
01376 session);
01377
01378
01379 if(NULL != daemon->session_closed_cb)
01380 {
01381 daemon->session_closed_cb(daemon->cls, session, by_client);
01382 }
01383 }
01384
01385
01386 int
01387 SPDYF_session_accept(struct SPDY_Daemon *daemon)
01388 {
01389 int new_socket_fd;
01390 int ret;
01391 struct SPDY_Session *session = NULL;
01392 socklen_t addr_len;
01393 struct sockaddr *addr;
01394
01395 #if HAVE_INET6
01396 struct sockaddr_in6 addr6;
01397
01398 addr = (struct sockaddr *)&addr6;
01399 addr_len = sizeof(addr6);
01400 #else
01401 struct sockaddr_in addr4;
01402
01403 addr = (struct sockaddr *)&addr4;
01404 addr_len = sizeof(addr6);
01405 #endif
01406
01407 new_socket_fd = accept (daemon->socket_fd, addr, &addr_len);
01408
01409 if(new_socket_fd < 1)
01410 return SPDY_NO;
01411
01412 if (NULL == (session = malloc (sizeof (struct SPDY_Session))))
01413 {
01414 goto free_and_fail;
01415 }
01416 memset (session, 0, sizeof (struct SPDY_Session));
01417
01418 session->daemon = daemon;
01419 session->socket_fd = new_socket_fd;
01420 session->max_num_frames = daemon->max_num_frames;
01421
01422 ret = SPDYF_io_set_session(session, daemon->io_subsystem);
01423 SPDYF_ASSERT(SPDY_YES == ret, "Somehow daemon->io_subsystem iswrong here");
01424
01425
01426 if(SPDY_YES != session->fio_new_session(session))
01427 {
01428 goto free_and_fail;
01429 }
01430
01431
01432 session->read_buffer_size = SPDYF_BUFFER_SIZE;
01433 if (NULL == (session->read_buffer = malloc (session->read_buffer_size)))
01434 {
01435 session->fio_close_session(session);
01436 goto free_and_fail;
01437 }
01438
01439
01440 if (NULL == (session->addr = malloc (addr_len)))
01441 {
01442 session->fio_close_session(session);
01443 goto free_and_fail;
01444 }
01445 memcpy (session->addr, addr, addr_len);
01446
01447 session->addr_len = addr_len;
01448 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
01449
01450
01451 if(SPDY_YES != SPDYF_zlib_deflate_init(&session->zlib_send_stream))
01452 {
01453 session->fio_close_session(session);
01454 goto free_and_fail;
01455 }
01456 if(SPDY_YES != SPDYF_zlib_inflate_init(&session->zlib_recv_stream))
01457 {
01458 session->fio_close_session(session);
01459 SPDYF_zlib_deflate_end(&session->zlib_send_stream);
01460 goto free_and_fail;
01461 }
01462
01463
01464 DLL_insert(daemon->sessions_head,daemon->sessions_tail,session);
01465
01466 session->last_activity = SPDYF_monotonic_time();
01467
01468 if(NULL != daemon->new_session_cb)
01469 daemon->new_session_cb(daemon->cls, session);
01470
01471 return SPDY_YES;
01472
01473
01474 free_and_fail:
01475
01476 shutdown (new_socket_fd, SHUT_RDWR);
01477 (void)close (new_socket_fd);
01478
01479 if(NULL != session)
01480 {
01481 if(NULL != session->addr)
01482 free (session->addr);
01483 if(NULL != session->read_buffer)
01484 free (session->read_buffer);
01485 free (session);
01486 }
01487 return SPDY_NO;
01488 }
01489
01490
01491 void
01492 SPDYF_queue_response (struct SPDYF_Response_Queue *response_to_queue,
01493 struct SPDY_Session *session,
01494 int consider_priority)
01495 {
01496 struct SPDYF_Response_Queue *pos;
01497 struct SPDYF_Response_Queue *last;
01498 uint8_t priority;
01499
01500 SPDYF_ASSERT(SPDY_YES != consider_priority || NULL != response_to_queue->stream,
01501 "called with consider_priority but no stream provided");
01502
01503 last = response_to_queue;
01504 while(NULL != last->next)
01505 {
01506 last = last->next;
01507 }
01508
01509 if(SPDY_NO == consider_priority)
01510 {
01511
01512 response_to_queue->prev = session->response_queue_tail;
01513 if (NULL == session->response_queue_head)
01514 session->response_queue_head = response_to_queue;
01515 else
01516 session->response_queue_tail->next = response_to_queue;
01517 session->response_queue_tail = last;
01518 return;
01519 }
01520 else if(-1 == consider_priority)
01521 {
01522
01523 last->next = session->response_queue_head;
01524 if (NULL == session->response_queue_tail)
01525 session->response_queue_tail = last;
01526 else
01527 session->response_queue_head->prev = response_to_queue;
01528 session->response_queue_head = response_to_queue;
01529 return;
01530 }
01531
01532 if(NULL == session->response_queue_tail)
01533 {
01534 session->response_queue_head = response_to_queue;
01535 session->response_queue_tail = last;
01536 return;
01537 }
01538
01539
01540 pos = session->response_queue_tail;
01541 priority = response_to_queue->stream->priority;
01542 while(NULL != pos
01543 && pos->stream->priority > priority)
01544 {
01545 pos = pos->prev;
01546 }
01547
01548 if(NULL == pos)
01549 {
01550
01551 session->response_queue_head->prev = last;
01552 last->next = session->response_queue_head;
01553 session->response_queue_head = response_to_queue;
01554 }
01555 else if(NULL == pos->next)
01556 {
01557
01558 response_to_queue->prev = pos;
01559 pos->next = response_to_queue;
01560 session->response_queue_tail = last;
01561 }
01562 else
01563 {
01564 response_to_queue->prev = pos;
01565 last->next = pos->next;
01566 pos->next = response_to_queue;
01567 last->next->prev = last;
01568 }
01569 }
01570
01571
01572 void
01573 SPDYF_session_destroy(struct SPDY_Session *session)
01574 {
01575 struct SPDYF_Stream *stream;
01576 struct SPDYF_Response_Queue *response_queue;
01577
01578 (void)close (session->socket_fd);
01579 SPDYF_zlib_deflate_end(&session->zlib_send_stream);
01580 SPDYF_zlib_inflate_end(&session->zlib_recv_stream);
01581
01582
01583 while (NULL != (response_queue = session->response_queue_head))
01584 {
01585 DLL_remove (session->response_queue_head,
01586 session->response_queue_tail,
01587 response_queue);
01588
01589 if(NULL != response_queue->frqcb)
01590 {
01591 response_queue->frqcb(response_queue->frqcb_cls, response_queue, SPDY_RESPONSE_RESULT_SESSION_CLOSED);
01592 }
01593
01594 SPDYF_response_queue_destroy(response_queue);
01595 }
01596
01597
01598 while (NULL != (stream = session->streams_head))
01599 {
01600 DLL_remove (session->streams_head,
01601 session->streams_tail,
01602 stream);
01603
01604 SPDYF_stream_destroy(stream);
01605 }
01606
01607 free(session->addr);
01608 free(session->read_buffer);
01609 free(session->write_buffer);
01610 free(session);
01611 }
01612
01613
01614 int
01615 SPDYF_prepare_goaway (struct SPDY_Session *session,
01616 enum SPDY_GOAWAY_STATUS status,
01617 bool in_front)
01618 {
01619 struct SPDYF_Response_Queue *response_to_queue;
01620 struct SPDYF_Control_Frame *control_frame;
01621 uint32_t *data;
01622
01623 if(NULL == (response_to_queue = malloc(sizeof(struct SPDYF_Response_Queue))))
01624 {
01625 return SPDY_NO;
01626 }
01627 memset(response_to_queue, 0, sizeof(struct SPDYF_Response_Queue));
01628
01629 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
01630 {
01631 free(response_to_queue);
01632 return SPDY_NO;
01633 }
01634 memset(control_frame, 0, sizeof(struct SPDYF_Control_Frame));
01635
01636 if(NULL == (data = malloc(4)))
01637 {
01638 free(control_frame);
01639 free(response_to_queue);
01640 return SPDY_NO;
01641 }
01642 *(data) = htonl(status);
01643
01644 control_frame->control_bit = 1;
01645 control_frame->version = SPDY_VERSION;
01646 control_frame->type = SPDY_CONTROL_FRAME_TYPES_GOAWAY;
01647 control_frame->flags = 0;
01648
01649 response_to_queue->control_frame = control_frame;
01650 response_to_queue->process_response_handler = &SPDYF_handler_write_goaway;
01651 response_to_queue->data = data;
01652 response_to_queue->data_size = 4;
01653
01654 SPDYF_queue_response (response_to_queue,
01655 session,
01656 in_front ? -1 : SPDY_NO);
01657
01658 return SPDY_YES;
01659 }
01660
01661
01662 int
01663 SPDYF_prepare_rst_stream (struct SPDY_Session *session,
01664 struct SPDYF_Stream * stream,
01665 enum SPDY_RST_STREAM_STATUS status)
01666 {
01667 struct SPDYF_Response_Queue *response_to_queue;
01668 struct SPDYF_Control_Frame *control_frame;
01669 uint32_t *data;
01670 uint32_t stream_id;
01671
01672 if(NULL == stream)
01673 stream_id = 0;
01674 else
01675 stream_id = stream->stream_id;
01676
01677 if(NULL == (response_to_queue = malloc(sizeof(struct SPDYF_Response_Queue))))
01678 {
01679 return SPDY_NO;
01680 }
01681 memset(response_to_queue, 0, sizeof(struct SPDYF_Response_Queue));
01682
01683 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
01684 {
01685 free(response_to_queue);
01686 return SPDY_NO;
01687 }
01688 memset(control_frame, 0, sizeof(struct SPDYF_Control_Frame));
01689
01690 if(NULL == (data = malloc(8)))
01691 {
01692 free(control_frame);
01693 free(response_to_queue);
01694 return SPDY_NO;
01695 }
01696 *(data) = HTON31(stream_id);
01697 *(data + 1) = htonl(status);
01698
01699 control_frame->control_bit = 1;
01700 control_frame->version = SPDY_VERSION;
01701 control_frame->type = SPDY_CONTROL_FRAME_TYPES_RST_STREAM;
01702 control_frame->flags = 0;
01703
01704 response_to_queue->control_frame = control_frame;
01705 response_to_queue->process_response_handler = &SPDYF_handler_write_rst_stream;
01706 response_to_queue->data = data;
01707 response_to_queue->data_size = 8;
01708 response_to_queue->stream = stream;
01709
01710 SPDYF_queue_response (response_to_queue,
01711 session,
01712 -1);
01713
01714 return SPDY_YES;
01715 }
01716
01717
01718 int
01719 SPDYF_prepare_window_update (struct SPDY_Session *session,
01720 struct SPDYF_Stream * stream,
01721 int32_t delta_window_size)
01722 {
01723 struct SPDYF_Response_Queue *response_to_queue;
01724 struct SPDYF_Control_Frame *control_frame;
01725 uint32_t *data;
01726
01727 SPDYF_ASSERT(NULL != stream, "stream cannot be NULL");
01728
01729 if(NULL == (response_to_queue = malloc(sizeof(struct SPDYF_Response_Queue))))
01730 {
01731 return SPDY_NO;
01732 }
01733 memset(response_to_queue, 0, sizeof(struct SPDYF_Response_Queue));
01734
01735 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
01736 {
01737 free(response_to_queue);
01738 return SPDY_NO;
01739 }
01740 memset(control_frame, 0, sizeof(struct SPDYF_Control_Frame));
01741
01742 if(NULL == (data = malloc(8)))
01743 {
01744 free(control_frame);
01745 free(response_to_queue);
01746 return SPDY_NO;
01747 }
01748 *(data) = HTON31(stream->stream_id);
01749 *(data + 1) = HTON31(delta_window_size);
01750
01751 control_frame->control_bit = 1;
01752 control_frame->version = SPDY_VERSION;
01753 control_frame->type = SPDY_CONTROL_FRAME_TYPES_WINDOW_UPDATE;
01754 control_frame->flags = 0;
01755
01756 response_to_queue->control_frame = control_frame;
01757 response_to_queue->process_response_handler = &SPDYF_handler_write_window_update;
01758 response_to_queue->data = data;
01759 response_to_queue->data_size = 8;
01760 response_to_queue->stream = stream;
01761
01762 SPDYF_queue_response (response_to_queue,
01763 session,
01764 -1);
01765
01766 return SPDY_YES;
01767 }