GNU libmicrohttpd  0.9.29
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
stream.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrospdy
3  Copyright (C) 2012 Andrey Uzunov
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
25 #include "platform.h"
26 #include "structures.h"
27 #include "internal.h"
28 #include "session.h"
29 
30 
31 int
32 SPDYF_stream_new (struct SPDY_Session *session)
33 {
34  uint32_t stream_id;
35  uint32_t assoc_stream_id;
36  uint8_t priority;
37  uint8_t slot;
38  size_t buffer_pos = session->read_buffer_beginning;
39  struct SPDYF_Stream *stream;
40  struct SPDYF_Control_Frame *frame;
41 
42  if((session->read_buffer_offset - session->read_buffer_beginning) < 10)
43  {
44  //not all fields are received to create new stream
45  return SPDY_NO;
46  }
47 
48  frame = (struct SPDYF_Control_Frame *)session->frame_handler_cls;
49 
50  //get stream id of the new stream
51  memcpy(&stream_id, session->read_buffer + session->read_buffer_beginning, 4);
52  stream_id = NTOH31(stream_id);
53  session->read_buffer_beginning += 4;
54  if(stream_id <= session->last_in_stream_id || 0==(stream_id % 2))
55  {
56  //wrong stream id sent by client
57  //GOAWAY with PROTOCOL_ERROR MUST be sent
58  //TODO
59 
60  //ignore frame
62  return SPDY_NO;
63  }
64  else if(session->is_goaway_sent)
65  {
66  //the client is not allowed to create new streams anymore
67  //we MUST ignore the frame
69  return SPDY_NO;
70  }
71 
72  //set highest stream id for session
73  session->last_in_stream_id = stream_id;
74 
75  //get assoc stream id of the new stream
76  //this value is used with SPDY PUSH, thus nothing to do with it here
77  memcpy(&assoc_stream_id, session->read_buffer + session->read_buffer_beginning, 4);
78  assoc_stream_id = NTOH31(assoc_stream_id);
79  session->read_buffer_beginning += 4;
80 
81  //get stream priority (3 bits)
82  //after it there are 5 bits that are not used
83  priority = *(uint8_t *)(session->read_buffer + session->read_buffer_beginning) >> 5;
84  session->read_buffer_beginning++;
85 
86  //get slot (see SPDY draft)
87  slot = *(uint8_t *)(session->read_buffer + session->read_buffer_beginning);
88  session->read_buffer_beginning++;
89 
90  if(NULL == (stream = malloc(sizeof(struct SPDYF_Stream))))
91  {
92  SPDYF_DEBUG("No memory");
93  //revert buffer state
94  session->read_buffer_beginning = buffer_pos;
95  return SPDY_NO;
96  }
97  memset(stream,0, sizeof(struct SPDYF_Stream));
98  stream->session = session;
99  stream->stream_id = stream_id;
100  stream->assoc_stream_id = assoc_stream_id;
101  stream->priority = priority;
102  stream->slot = slot;
103  stream->is_in_closed = (frame->flags & SPDY_SYN_STREAM_FLAG_FIN) != 0;
104  stream->flag_unidirectional = (frame->flags & SPDY_SYN_STREAM_FLAG_UNIDIRECTIONAL) != 0;
105  stream->is_out_closed = stream->flag_unidirectional;
106  stream->is_server_initiator = false;
108 
109  //put the stream to the list of streams for the session
110  DLL_insert(session->streams_head, session->streams_tail, stream);
111 
112  return SPDY_YES;
113 }
114 
115 
116 void
118 {
120  free(stream);
121  stream = NULL;
122 }
123 
124 
125 void
127 {
128  struct SPDYF_Stream * stream = response_queue->stream;
129 
130  if(NULL != response_queue->data_frame)
131  {
132  stream->is_out_closed = (bool)(response_queue->data_frame->flags & SPDY_DATA_FLAG_FIN);
133  }
134  else if(NULL != response_queue->control_frame)
135  {
136  switch(response_queue->control_frame->type)
137  {
139  stream->is_out_closed = (bool)(response_queue->control_frame->flags & SPDY_SYN_REPLY_FLAG_FIN);
140  break;
141 
143  if(NULL != stream)
144  {
145  stream->is_out_closed = true;
146  stream->is_in_closed = true;
147  }
148  break;
149 
150  }
151  }
152 }
153 
154 
155 //TODO add function *on_read
156 
157 
158 struct SPDYF_Stream *
160 {
161  struct SPDYF_Stream * stream = session->streams_head;
162 
163  while(NULL != stream && stream_id != stream->stream_id)
164  {
165  stream = stream->next;
166  }
167 
168  return stream;
169 }
struct SPDYF_Stream * streams_head
Definition: structures.h:644
#define NULL
Definition: reason_phrase.c:31
void * read_buffer
Definition: structures.h:670
void SPDYF_stream_destroy(struct SPDYF_Stream *stream)
Definition: stream.c:117
#define SPDY_YES
Definition: microspdy.h:93
bool is_server_initiator
Definition: structures.h:595
#define SPDYF_INITIAL_WINDOW_SIZE
Definition: internal.h:41
struct SPDYF_Control_Frame * control_frame
Definition: structures.h:430
TCP connection/SPDY session handling.
void(* frame_handler)(struct SPDY_Session *session)
Definition: structures.h:680
bool is_out_closed
Definition: structures.h:590
internal functions and macros for the framing layer
platform-specific includes for libmicrohttpd
internal and public structures – most of the structs used by the library are defined here ...
uint32_t assoc_stream_id
Definition: structures.h:554
#define SPDY_NO
Definition: microspdy.h:98
uint32_t last_in_stream_id
Definition: structures.h:794
bool is_in_closed
Definition: structures.h:583
struct SPDYF_Stream * next
Definition: structures.h:524
bool is_goaway_sent
Definition: structures.h:846
#define SPDYF_DEBUG(fmt,...)
Definition: internal.h:154
void SPDYF_stream_set_flags_on_write(struct SPDYF_Response_Queue *response_queue)
Definition: stream.c:126
uint8_t slot
Definition: structures.h:571
struct SPDYF_Data_Frame * data_frame
Definition: structures.h:436
bool flag_unidirectional
Definition: structures.h:576
size_t read_buffer_beginning
Definition: structures.h:753
_MHD_EXTERN void SPDY_name_value_destroy(struct SPDY_NameValue *container)
Definition: structures.c:218
void SPDYF_handler_ignore_frame(struct SPDY_Session *session)
Definition: session.c:828
struct SPDYF_Stream * SPDYF_stream_find(uint32_t stream_id, struct SPDY_Session *session)
Definition: stream.c:159
uint32_t window_size
Definition: structures.h:559
uint8_t priority
Definition: structures.h:564
struct SPDY_NameValue * headers
Definition: structures.h:539
#define DLL_insert(head, tail, element)
Definition: internal.h:1259
uint32_t stream_id
Definition: structures.h:549
struct SPDYF_Stream * streams_tail
Definition: structures.h:649
void * frame_handler_cls
Definition: structures.h:685
size_t read_buffer_offset
Definition: structures.h:748
#define NTOH31(n)
Definition: internal.h:125
struct SPDYF_Stream * stream
Definition: structures.h:419
int SPDYF_stream_new(struct SPDY_Session *session)
Definition: stream.c:32
struct SPDY_Session * session
Definition: structures.h:534