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 */ 43static void 44spdyf_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 */ 180static void 181spdyf_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 */ 259static void 260spdyf_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 */ 331static void 332spdyf_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 421int 422SPDYF_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 516int 517SPDYF_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 569int 570SPDYF_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 741int 742SPDYF_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 786int 787SPDYF_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 829void 830SPDYF_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 865int 866SPDYF_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 980int 981SPDYF_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 1154int 1155SPDYF_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 1359void 1360SPDYF_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 1388int 1389SPDYF_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 1493void 1494SPDYF_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 1574void 1575SPDYF_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 1616int 1617SPDYF_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 1664int 1665SPDYF_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 1720int 1721SPDYF_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