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