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