• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.h
21  * @brief  TCP connection/SPDY session handling
22  * @author Andrey Uzunov
23  */
24 
25 #ifndef SESSION_H
26 #define SESSION_H
27 
28 #include "platform.h"
29 #include "structures.h"
30 
31 /**
32  * Called by the daemon when the socket for the session has available
33  * data to be read. Reads data from the TLS socket and puts it to the
34  * session's read buffer. The latte
35  *
36  * @param session SPDY_Session for which data will be read.
37  * @return SPDY_YES if something was read or session's status was
38  *         changed. It is possible that error occurred but was handled
39  *         and the status was therefore changed.
40  *         SPDY_NO if nothing happened, e.g. the subsystem wants read/
41  *         write to be called again.
42  */
43 int
44 SPDYF_session_read (struct SPDY_Session *session);
45 
46 
47 /**
48  * Called by the daemon when the socket for the session is ready for some
49  * data to be written to it. For one or more objects on the response
50  * queue tries to fill in the write buffer, based on the frame on the
51  * queue, and to write data to the TLS socket.
52  *
53  * @param session SPDY_Session for which data will be written.
54  * @param only_one_frame when true, the function will write at most one
55  *        SPDY frame to the underlying IO subsystem;
56  *        when false, the function will write up to
57  *        session->max_num_frames SPDY frames
58  * @return SPDY_YES if the session's internal writing state has changed:
59  *         something was written and/or session's status was
60  *         changed and/or response callback was called but did not provide
61  *         data. It is possible that error occurred but was handled
62  *         and the status was therefore changed.
63  *         SPDY_NO if nothing happened. However, it is possible that some
64  *         frames were discarded within the call, e.g. frames belonging
65  *         to a closed stream.
66  */
67 int
68 SPDYF_session_write (struct SPDY_Session *session,
69                      bool only_one_frame);
70 
71 
72 /**
73  * Called by the daemon on SPDY_run to handle the data in the read and write
74  * buffer of a session. Based on the state and the content of the read
75  * buffer new frames are received and interpreted, appropriate user
76  * callbacks are called and maybe something is put on the response queue
77  * ready to be handled by session_write.
78  *
79  * @param session SPDY_Session which will be handled.
80  * @return SPDY_YES if something from the read buffers was processed,
81  *         session's status was changed and/or the session was closed.
82  *         SPDY_NO if nothing happened, e.g. the session is in a state,
83  *         not allowing processing read buffers.
84  */
85 int
86 SPDYF_session_idle (struct SPDY_Session *session);
87 
88 
89 /**
90  * This function shutdowns the socket, moves the session structure to
91  * daemon's queue for sessions to be cleaned up.
92  *
93  * @param session SPDY_Session which will be handled.
94  */
95 void
96 SPDYF_session_close (struct SPDY_Session *session);
97 
98 
99 /**
100  * Called to accept new TCP connection and create SPDY session.
101  *
102  * @param daemon SPDY_Daemon whose listening socket is used.
103  * @return SPDY_NO on any kind of error while accepting new TCP connection
104  * 			and initializing new SPDY_Session.
105  *         SPDY_YES otherwise.
106  */
107 int
108 SPDYF_session_accept(struct SPDY_Daemon *daemon);
109 
110 
111 /**
112  * Puts SPDYF_Response_Queue object on the queue to be sent to the
113  * client later.
114  *
115  * @param response_to_queue linked list of objects containing SPDY
116  * 			frame and data to be added to the queue
117  * @param session SPDY session for which the response is sent
118  * @param consider_priority if SPDY_NO, the list will be added to the
119  * 			end of the queue.
120  * 			If SPDY_YES, the response will be added after
121  * 			the last previously added response with priority of the
122  * 			request grater or equal to that of the current one.
123  * 			If -1, the object will be put at the head of the queue.
124  */
125 void
126 SPDYF_queue_response (struct SPDYF_Response_Queue *response_to_queue,
127 						struct SPDY_Session *session,
128 						int consider_priority);
129 
130 
131 /**
132  * Cleans up the TSL context for the session, closes the TCP connection,
133  * cleans up any data pointed by members of the session structure
134  * (buffers, queue of responses, etc.) and frees the memory allocated by
135  * the session itself.
136  */
137 void
138 SPDYF_session_destroy(struct SPDY_Session *session);
139 
140 
141 /**
142  * Prepares GOAWAY frame to tell the client to stop creating new streams.
143  * The session should be closed soon after this call.
144  *
145  * @param session SPDY session
146  * @param status code for the GOAWAY frame
147  * @param in_front whether or not to put the frame in front of everything
148  * 			on the response queue
149  * @return SPDY_NO on error (not enough memory) or
150  * 			SPDY_YES on success
151  */
152 int
153 SPDYF_prepare_goaway (struct SPDY_Session *session,
154 					enum SPDY_GOAWAY_STATUS status,
155 					bool in_front);
156 
157 
158 /**
159  * Prepares RST_STREAM frame to terminate a stream. This frame may or
160  * not indicate an error. The frame will be put at the head of the queue.
161  * This means that frames for this stream which are still in the queue
162  * will be discarded soon.
163  *
164  * @param session SPDY session
165  * @param stream stream to terminate
166  * @param status code for the RST_STREAM frame
167  * @return SPDY_NO on memory error or
168  * 			SPDY_YES on success
169  */
170 int
171 SPDYF_prepare_rst_stream (struct SPDY_Session *session,
172 					struct SPDYF_Stream * stream,
173 					enum SPDY_RST_STREAM_STATUS status);
174 
175 
176 /**
177  * Prepares WINDOW_UPDATE frame to tell the other party that more
178  * data can be sent on the stream. The frame will be put at the head of
179  * the queue.
180  *
181  * @param session SPDY session
182  * @param stream stream to which the changed window will apply
183  * @param delta_window_size how much the window grows
184  * @return SPDY_NO on memory error or
185  * 			SPDY_YES on success
186  */
187 int
188 SPDYF_prepare_window_update (struct SPDY_Session *session,
189 					struct SPDYF_Stream * stream,
190 					int32_t delta_window_size);
191 
192 
193 /**
194  * Handler called by session_write to fill the write buffer according to
195  * the data frame waiting in the response queue.
196  * When response data is given by user callback, the lib does not know
197  * how many frames are needed. In such case this call produces
198  * another ResponseQueue object and puts it on the queue while the the
199  * user callback says that there will be more data.
200  *
201  * @return SPDY_NO on error (not enough memory or the user calback for
202  *         providing response data did something wrong). If
203  *         the error is unrecoverable the handler changes session's
204  *         status.
205  *         SPDY_YES on success
206  */
207 int
208 SPDYF_handler_write_data (struct SPDY_Session *session);
209 
210 
211 /**
212  * Handler called by session_write to fill the write buffer based on the
213  * control frame (SYN_REPLY) waiting in the response queue.
214  *
215  * @param session SPDY session
216  * @return SPDY_NO on error (zlib state is broken; the session MUST be
217  *         closed). If
218  *         the error is unrecoverable the handler changes session's
219  *         status.
220  * 			SPDY_YES on success
221  */
222 int
223 SPDYF_handler_write_syn_reply (struct SPDY_Session *session);
224 
225 
226 /**
227  * Handler called by session_write to fill the write buffer based on the
228  * control frame (GOAWAY) waiting in the response queue.
229  *
230  * @param session SPDY session
231  * @return SPDY_NO on error (not enough memory; by specification the
232  *         session must be closed
233  *         soon, thus there is no need to handle the error) or
234  * 			SPDY_YES on success
235  */
236 int
237 SPDYF_handler_write_goaway (struct SPDY_Session *session);
238 
239 
240 /**
241  * Handler called by session_write to fill the write buffer based on the
242  * control frame (RST_STREAM) waiting in the response queue.
243  *
244  * @param session SPDY session
245  * @return SPDY_NO on error (not enough memory). If
246  *         the error is unrecoverable the handler changes session's
247  *         status.
248  * 			SPDY_YES on success
249  */
250 int
251 SPDYF_handler_write_rst_stream (struct SPDY_Session *session);
252 
253 
254 /**
255  * Handler called by session_write to fill the write buffer based on the
256  * control frame (WINDOW_UPDATE) waiting in the response queue.
257  *
258  * @param session SPDY session
259  * @return SPDY_NO on error (not enough memory). If
260  *         the error is unrecoverable the handler changes session's
261  *         status.
262  * 			SPDY_YES on success
263  */
264 int
265 SPDYF_handler_write_window_update (struct SPDY_Session *session);
266 
267 
268 /**
269  * Carefully ignore the full size of frames which are not yet supported
270  * by the lib.
271  * TODO Ignoring frames containing compressed bodies means that the
272  * compress state will be corrupted on next received frame. According to
273  * the draft the lib SHOULD try to decompress data also in corrupted
274  * frames just to keep right compression state.
275  *
276  * @param session SPDY_Session whose read buffer is used.
277  */
278 void
279 SPDYF_handler_ignore_frame (struct SPDY_Session *session);
280 
281 #endif
282