diff options
Diffstat (limited to 'src/lib/upgrade_process.c')
-rw-r--r-- | src/lib/upgrade_process.c | 491 |
1 files changed, 250 insertions, 241 deletions
diff --git a/src/lib/upgrade_process.c b/src/lib/upgrade_process.c index 75924eee..353f2753 100644 --- a/src/lib/upgrade_process.c +++ b/src/lib/upgrade_process.c | |||
@@ -41,59 +41,62 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) | |||
41 | * pointers to 'connection' and 'daemon' are not changed | 41 | * pointers to 'connection' and 'daemon' are not changed |
42 | * during this processing, so no need to chain dereference | 42 | * during this processing, so no need to chain dereference |
43 | * each time. */ | 43 | * each time. */ |
44 | struct MHD_Connection * const connection = urh->connection; | 44 | struct MHD_Connection *const connection = urh->connection; |
45 | struct MHD_Daemon * const daemon = connection->daemon; | 45 | struct MHD_Daemon *const daemon = connection->daemon; |
46 | /* Prevent data races: use same value of 'was_closed' throughout | 46 | /* Prevent data races: use same value of 'was_closed' throughout |
47 | * this function. If 'was_closed' changed externally in the middle | 47 | * this function. If 'was_closed' changed externally in the middle |
48 | * of processing - it will be processed on next iteration. */ | 48 | * of processing - it will be processed on next iteration. */ |
49 | bool was_closed; | 49 | bool was_closed; |
50 | struct MHD_TLS_Plugin *tls = daemon->tls_api; | 50 | struct MHD_TLS_Plugin *tls = daemon->tls_api; |
51 | 51 | ||
52 | if (daemon->shutdown) | 52 | if (daemon->shutdown) |
53 | { | 53 | { |
54 | /* Daemon shutting down, application will not receive any more data. */ | 54 | /* Daemon shutting down, application will not receive any more data. */ |
55 | #ifdef HAVE_MESSAGES | 55 | #ifdef HAVE_MESSAGES |
56 | if (! urh->was_closed) | 56 | if (! urh->was_closed) |
57 | { | 57 | { |
58 | MHD_DLOG (daemon, | 58 | MHD_DLOG (daemon, |
59 | MHD_SC_DAEMON_ALREADY_SHUTDOWN, | 59 | MHD_SC_DAEMON_ALREADY_SHUTDOWN, |
60 | _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | 60 | _ ( |
61 | } | 61 | "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); |
62 | #endif | ||
63 | urh->was_closed = true; | ||
64 | } | 62 | } |
63 | #endif | ||
64 | urh->was_closed = true; | ||
65 | } | ||
65 | was_closed = urh->was_closed; | 66 | was_closed = urh->was_closed; |
66 | if (was_closed) | 67 | if (was_closed) |
68 | { | ||
69 | /* Application was closed connections: no more data | ||
70 | * can be forwarded to application socket. */ | ||
71 | if (0 < urh->in_buffer_used) | ||
67 | { | 72 | { |
68 | /* Application was closed connections: no more data | ||
69 | * can be forwarded to application socket. */ | ||
70 | if (0 < urh->in_buffer_used) | ||
71 | { | ||
72 | #ifdef HAVE_MESSAGES | 73 | #ifdef HAVE_MESSAGES |
73 | MHD_DLOG (daemon, | 74 | MHD_DLOG (daemon, |
74 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, | 75 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, |
75 | _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 76 | _ ( |
76 | " bytes of data received from remote side: application shut down socket\n"), | 77 | "Failed to forward to application " |
77 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); | 78 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
79 | " bytes of data received from remote side: application shut down socket\n"), | ||
80 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); | ||
78 | #endif | 81 | #endif |
79 | 82 | ||
80 | } | ||
81 | /* If application signaled MHD about socket closure then | ||
82 | * check for any pending data even if socket is not marked | ||
83 | * as 'ready' (signal may arrive after poll()/select()). | ||
84 | * Socketpair for forwarding is always in non-blocking mode | ||
85 | * so no risk that recv() will block the thread. */ | ||
86 | if (0 != urh->out_buffer_size) | ||
87 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | ||
88 | /* Discard any data received form remote. */ | ||
89 | urh->in_buffer_used = 0; | ||
90 | /* Do not try to push data to application. */ | ||
91 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
92 | /* Reading from remote client is not required anymore. */ | ||
93 | urh->in_buffer_size = 0; | ||
94 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
95 | connection->tls_read_ready = false; | ||
96 | } | 83 | } |
84 | /* If application signaled MHD about socket closure then | ||
85 | * check for any pending data even if socket is not marked | ||
86 | * as 'ready' (signal may arrive after poll()/select()). | ||
87 | * Socketpair for forwarding is always in non-blocking mode | ||
88 | * so no risk that recv() will block the thread. */ | ||
89 | if (0 != urh->out_buffer_size) | ||
90 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | ||
91 | /* Discard any data received form remote. */ | ||
92 | urh->in_buffer_used = 0; | ||
93 | /* Do not try to push data to application. */ | ||
94 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
95 | /* Reading from remote client is not required anymore. */ | ||
96 | urh->in_buffer_size = 0; | ||
97 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
98 | connection->tls_read_ready = false; | ||
99 | } | ||
97 | 100 | ||
98 | /* On some platforms (W32, possibly Darwin) failed send() (send() will always | 101 | /* On some platforms (W32, possibly Darwin) failed send() (send() will always |
99 | * fail after remote disconnect was detected) may discard data in system | 102 | * fail after remote disconnect was detected) may discard data in system |
@@ -114,245 +117,249 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) | |||
114 | if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || | 117 | if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || |
115 | (connection->tls_read_ready) ) && | 118 | (connection->tls_read_ready) ) && |
116 | (urh->in_buffer_used < urh->in_buffer_size) ) | 119 | (urh->in_buffer_used < urh->in_buffer_size) ) |
117 | { | 120 | { |
118 | ssize_t res; | 121 | ssize_t res; |
119 | size_t buf_size; | 122 | size_t buf_size; |
120 | 123 | ||
121 | buf_size = urh->in_buffer_size - urh->in_buffer_used; | 124 | buf_size = urh->in_buffer_size - urh->in_buffer_used; |
122 | if (buf_size > SSIZE_MAX) | 125 | if (buf_size > SSIZE_MAX) |
123 | buf_size = SSIZE_MAX; | 126 | buf_size = SSIZE_MAX; |
124 | 127 | ||
125 | connection->tls_read_ready = false; | 128 | connection->tls_read_ready = false; |
126 | res = tls->recv (tls->cls, | 129 | res = tls->recv (tls->cls, |
127 | connection->tls_cs, | 130 | connection->tls_cs, |
128 | &urh->in_buffer[urh->in_buffer_used], | 131 | &urh->in_buffer[urh->in_buffer_used], |
129 | buf_size); | 132 | buf_size); |
130 | if (0 >= res) | 133 | if (0 >= res) |
131 | { | 134 | { |
132 | // FIXME: define GNUTLS-independent error codes! | 135 | // FIXME: define GNUTLS-independent error codes! |
133 | if (GNUTLS_E_INTERRUPTED != res) | 136 | if (GNUTLS_E_INTERRUPTED != res) |
134 | { | 137 | { |
135 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 138 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
136 | if (GNUTLS_E_AGAIN != res) | 139 | if (GNUTLS_E_AGAIN != res) |
137 | { | ||
138 | /* Unrecoverable error on socket was detected or | ||
139 | * socket was disconnected/shut down. */ | ||
140 | /* Stop trying to read from this TLS socket. */ | ||
141 | urh->in_buffer_size = 0; | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | else /* 0 < res */ | ||
146 | { | ||
147 | urh->in_buffer_used += res; | ||
148 | if (buf_size > (size_t)res) | ||
149 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
150 | else if (0 < tls->check_record_pending (tls->cls, | ||
151 | connection->tls_cs)) | ||
152 | connection->tls_read_ready = true; | ||
153 | } | ||
154 | if (MHD_EPOLL_STATE_ERROR == | ||
155 | ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi)) | ||
156 | { | 140 | { |
157 | /* Unrecoverable error on socket was detected and all | 141 | /* Unrecoverable error on socket was detected or |
158 | * pending data was read from system buffers. */ | 142 | * socket was disconnected/shut down. */ |
159 | /* Stop trying to read from this TLS socket. */ | 143 | /* Stop trying to read from this TLS socket. */ |
160 | urh->in_buffer_size = 0; | 144 | urh->in_buffer_size = 0; |
161 | } | 145 | } |
146 | } | ||
162 | } | 147 | } |
148 | else /* 0 < res */ | ||
149 | { | ||
150 | urh->in_buffer_used += res; | ||
151 | if (buf_size > (size_t) res) | ||
152 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
153 | else if (0 < tls->check_record_pending (tls->cls, | ||
154 | connection->tls_cs)) | ||
155 | connection->tls_read_ready = true; | ||
156 | } | ||
157 | if (MHD_EPOLL_STATE_ERROR == | ||
158 | ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi)) | ||
159 | { | ||
160 | /* Unrecoverable error on socket was detected and all | ||
161 | * pending data was read from system buffers. */ | ||
162 | /* Stop trying to read from this TLS socket. */ | ||
163 | urh->in_buffer_size = 0; | ||
164 | } | ||
165 | } | ||
163 | 166 | ||
164 | /* | 167 | /* |
165 | * handle reading from application | 168 | * handle reading from application |
166 | */ | 169 | */ |
167 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | 170 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && |
168 | (urh->out_buffer_used < urh->out_buffer_size) ) | 171 | (urh->out_buffer_used < urh->out_buffer_size) ) |
169 | { | 172 | { |
170 | ssize_t res; | 173 | ssize_t res; |
171 | size_t buf_size; | 174 | size_t buf_size; |
172 | 175 | ||
173 | buf_size = urh->out_buffer_size - urh->out_buffer_used; | 176 | buf_size = urh->out_buffer_size - urh->out_buffer_used; |
174 | if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) | 177 | if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) |
175 | buf_size = MHD_SCKT_SEND_MAX_SIZE_; | 178 | buf_size = MHD_SCKT_SEND_MAX_SIZE_; |
176 | 179 | ||
177 | res = MHD_recv_ (urh->mhd.socket, | 180 | res = MHD_recv_ (urh->mhd.socket, |
178 | &urh->out_buffer[urh->out_buffer_used], | 181 | &urh->out_buffer[urh->out_buffer_used], |
179 | buf_size); | 182 | buf_size); |
180 | if (0 >= res) | 183 | if (0 >= res) |
181 | { | 184 | { |
182 | const int err = MHD_socket_get_error_ (); | 185 | const int err = MHD_socket_get_error_ (); |
183 | if ((0 == res) || | 186 | if ((0 == res) || |
184 | ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && | 187 | ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && |
185 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)))) | 188 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)))) |
186 | { | 189 | { |
187 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 190 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
188 | if ((0 == res) || | 191 | if ((0 == res) || |
189 | (was_closed) || | 192 | (was_closed) || |
190 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | 193 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || |
191 | (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) | 194 | (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) |
192 | { | ||
193 | /* Socket disconnect/shutdown was detected; | ||
194 | * Application signaled about closure of 'upgraded' socket; | ||
195 | * or persistent / unrecoverable error. */ | ||
196 | /* Do not try to pull more data from application. */ | ||
197 | urh->out_buffer_size = 0; | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | else /* 0 < res */ | ||
202 | { | ||
203 | urh->out_buffer_used += res; | ||
204 | if (buf_size > (size_t)res) | ||
205 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
206 | } | ||
207 | if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | ||
208 | ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | ||
209 | (was_closed) ) ) | ||
210 | { | 195 | { |
211 | /* Unrecoverable error on socket was detected and all | 196 | /* Socket disconnect/shutdown was detected; |
212 | * pending data was read from system buffers. */ | 197 | * Application signaled about closure of 'upgraded' socket; |
198 | * or persistent / unrecoverable error. */ | ||
213 | /* Do not try to pull more data from application. */ | 199 | /* Do not try to pull more data from application. */ |
214 | urh->out_buffer_size = 0; | 200 | urh->out_buffer_size = 0; |
215 | } | 201 | } |
202 | } | ||
203 | } | ||
204 | else /* 0 < res */ | ||
205 | { | ||
206 | urh->out_buffer_used += res; | ||
207 | if (buf_size > (size_t) res) | ||
208 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
216 | } | 209 | } |
210 | if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | ||
211 | ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | ||
212 | (was_closed) ) ) | ||
213 | { | ||
214 | /* Unrecoverable error on socket was detected and all | ||
215 | * pending data was read from system buffers. */ | ||
216 | /* Do not try to pull more data from application. */ | ||
217 | urh->out_buffer_size = 0; | ||
218 | } | ||
219 | } | ||
217 | 220 | ||
218 | /* | 221 | /* |
219 | * handle writing to remote HTTPS client | 222 | * handle writing to remote HTTPS client |
220 | */ | 223 | */ |
221 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && | 224 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && |
222 | (urh->out_buffer_used > 0) ) | 225 | (urh->out_buffer_used > 0) ) |
223 | { | 226 | { |
224 | ssize_t res; | 227 | ssize_t res; |
225 | size_t data_size; | 228 | size_t data_size; |
226 | 229 | ||
227 | data_size = urh->out_buffer_used; | 230 | data_size = urh->out_buffer_used; |
228 | if (data_size > SSIZE_MAX) | 231 | if (data_size > SSIZE_MAX) |
229 | data_size = SSIZE_MAX; | 232 | data_size = SSIZE_MAX; |
230 | 233 | ||
231 | res = tls->send (tls->cls, | 234 | res = tls->send (tls->cls, |
232 | connection->tls_cs, | 235 | connection->tls_cs, |
233 | urh->out_buffer, | 236 | urh->out_buffer, |
234 | data_size); | 237 | data_size); |
235 | if (0 >= res) | 238 | if (0 >= res) |
239 | { | ||
240 | // FIXME: define GNUTLS-independent error codes! | ||
241 | if (GNUTLS_E_INTERRUPTED != res) | ||
242 | { | ||
243 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
244 | if (GNUTLS_E_INTERRUPTED != res) | ||
236 | { | 245 | { |
237 | // FIXME: define GNUTLS-independent error codes! | 246 | /* TLS connection shut down or |
238 | if (GNUTLS_E_INTERRUPTED != res) | 247 | * persistent / unrecoverable error. */ |
239 | { | ||
240 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
241 | if (GNUTLS_E_INTERRUPTED != res) | ||
242 | { | ||
243 | /* TLS connection shut down or | ||
244 | * persistent / unrecoverable error. */ | ||
245 | #ifdef HAVE_MESSAGES | 248 | #ifdef HAVE_MESSAGES |
246 | MHD_DLOG (daemon, | 249 | MHD_DLOG (daemon, |
247 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, | 250 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, |
248 | _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 251 | _ ( |
249 | " bytes of data received from application: %s\n"), | 252 | "Failed to forward to remote client " |
250 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, | 253 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
251 | tls->strerror (tls->cls, | 254 | " bytes of data received from application: %s\n"), |
252 | res)); | 255 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, |
256 | tls->strerror (tls->cls, | ||
257 | res)); | ||
253 | #endif | 258 | #endif |
254 | /* Discard any data unsent to remote. */ | 259 | /* Discard any data unsent to remote. */ |
255 | urh->out_buffer_used = 0; | 260 | urh->out_buffer_used = 0; |
256 | /* Do not try to pull more data from application. */ | ||
257 | urh->out_buffer_size = 0; | ||
258 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | else /* 0 < res */ | ||
263 | { | ||
264 | const size_t next_out_buffer_used = urh->out_buffer_used - res; | ||
265 | if (0 != next_out_buffer_used) | ||
266 | { | ||
267 | memmove (urh->out_buffer, | ||
268 | &urh->out_buffer[res], | ||
269 | next_out_buffer_used); | ||
270 | if (data_size > (size_t)res) | ||
271 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
272 | } | ||
273 | urh->out_buffer_used = next_out_buffer_used; | ||
274 | } | ||
275 | if ( (0 == urh->out_buffer_used) && | ||
276 | (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) | ||
277 | { | ||
278 | /* Unrecoverable error on socket was detected and all | ||
279 | * pending data was sent to remote. */ | ||
280 | /* Do not try to send to remote anymore. */ | ||
281 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
282 | /* Do not try to pull more data from application. */ | 261 | /* Do not try to pull more data from application. */ |
283 | urh->out_buffer_size = 0; | 262 | urh->out_buffer_size = 0; |
284 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 263 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
285 | } | 264 | } |
265 | } | ||
286 | } | 266 | } |
267 | else /* 0 < res */ | ||
268 | { | ||
269 | const size_t next_out_buffer_used = urh->out_buffer_used - res; | ||
270 | if (0 != next_out_buffer_used) | ||
271 | { | ||
272 | memmove (urh->out_buffer, | ||
273 | &urh->out_buffer[res], | ||
274 | next_out_buffer_used); | ||
275 | if (data_size > (size_t) res) | ||
276 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
277 | } | ||
278 | urh->out_buffer_used = next_out_buffer_used; | ||
279 | } | ||
280 | if ( (0 == urh->out_buffer_used) && | ||
281 | (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) | ||
282 | { | ||
283 | /* Unrecoverable error on socket was detected and all | ||
284 | * pending data was sent to remote. */ | ||
285 | /* Do not try to send to remote anymore. */ | ||
286 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
287 | /* Do not try to pull more data from application. */ | ||
288 | urh->out_buffer_size = 0; | ||
289 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
290 | } | ||
291 | } | ||
287 | 292 | ||
288 | /* | 293 | /* |
289 | * handle writing to application | 294 | * handle writing to application |
290 | */ | 295 | */ |
291 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && | 296 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && |
292 | (urh->in_buffer_used > 0) ) | 297 | (urh->in_buffer_used > 0) ) |
293 | { | 298 | { |
294 | ssize_t res; | 299 | ssize_t res; |
295 | size_t data_size; | 300 | size_t data_size; |
296 | 301 | ||
297 | data_size = urh->in_buffer_used; | 302 | data_size = urh->in_buffer_used; |
298 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) | 303 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) |
299 | data_size = MHD_SCKT_SEND_MAX_SIZE_; | 304 | data_size = MHD_SCKT_SEND_MAX_SIZE_; |
300 | 305 | ||
301 | res = MHD_send_ (urh->mhd.socket, | 306 | res = MHD_send_ (urh->mhd.socket, |
302 | urh->in_buffer, | 307 | urh->in_buffer, |
303 | data_size); | 308 | data_size); |
304 | if (0 >= res) | 309 | if (0 >= res) |
310 | { | ||
311 | const int err = MHD_socket_get_error_ (); | ||
312 | if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && | ||
313 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) ) | ||
314 | { | ||
315 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
316 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) | ||
305 | { | 317 | { |
306 | const int err = MHD_socket_get_error_ (); | 318 | /* Socketpair connection shut down or |
307 | if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && | 319 | * persistent / unrecoverable error. */ |
308 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)) ) | ||
309 | { | ||
310 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
311 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) | ||
312 | { | ||
313 | /* Socketpair connection shut down or | ||
314 | * persistent / unrecoverable error. */ | ||
315 | #ifdef HAVE_MESSAGES | 320 | #ifdef HAVE_MESSAGES |
316 | MHD_DLOG (daemon, | 321 | MHD_DLOG (daemon, |
317 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, | 322 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, |
318 | _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 323 | _ ( |
319 | " bytes of data received from remote side: %s\n"), | 324 | "Failed to forward to application " |
320 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, | 325 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
321 | MHD_socket_strerr_ (err)); | 326 | " bytes of data received from remote side: %s\n"), |
327 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, | ||
328 | MHD_socket_strerr_ (err)); | ||
322 | #endif | 329 | #endif |
323 | /* Discard any data received form remote. */ | 330 | /* Discard any data received form remote. */ |
324 | urh->in_buffer_used = 0; | 331 | urh->in_buffer_used = 0; |
325 | /* Reading from remote client is not required anymore. */ | ||
326 | urh->in_buffer_size = 0; | ||
327 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
328 | connection->tls_read_ready = false; | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | else /* 0 < res */ | ||
333 | { | ||
334 | const size_t next_in_buffer_used = urh->in_buffer_used - res; | ||
335 | if (0 != next_in_buffer_used) | ||
336 | { | ||
337 | memmove (urh->in_buffer, | ||
338 | &urh->in_buffer[res], | ||
339 | next_in_buffer_used); | ||
340 | if (data_size > (size_t)res) | ||
341 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
342 | } | ||
343 | urh->in_buffer_used = next_in_buffer_used; | ||
344 | } | ||
345 | if ( (0 == urh->in_buffer_used) && | ||
346 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) | ||
347 | { | ||
348 | /* Do not try to push data to application. */ | ||
349 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
350 | /* Reading from remote client is not required anymore. */ | 332 | /* Reading from remote client is not required anymore. */ |
351 | urh->in_buffer_size = 0; | 333 | urh->in_buffer_size = 0; |
352 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 334 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
353 | connection->tls_read_ready = false; | 335 | connection->tls_read_ready = false; |
354 | } | 336 | } |
337 | } | ||
338 | } | ||
339 | else /* 0 < res */ | ||
340 | { | ||
341 | const size_t next_in_buffer_used = urh->in_buffer_used - res; | ||
342 | if (0 != next_in_buffer_used) | ||
343 | { | ||
344 | memmove (urh->in_buffer, | ||
345 | &urh->in_buffer[res], | ||
346 | next_in_buffer_used); | ||
347 | if (data_size > (size_t) res) | ||
348 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
349 | } | ||
350 | urh->in_buffer_used = next_in_buffer_used; | ||
351 | } | ||
352 | if ( (0 == urh->in_buffer_used) && | ||
353 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) | ||
354 | { | ||
355 | /* Do not try to push data to application. */ | ||
356 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
357 | /* Reading from remote client is not required anymore. */ | ||
358 | urh->in_buffer_size = 0; | ||
359 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
360 | connection->tls_read_ready = false; | ||
355 | } | 361 | } |
362 | } | ||
356 | 363 | ||
357 | /* Check whether data is present in TLS buffers | 364 | /* Check whether data is present in TLS buffers |
358 | * and incoming forward buffer have some space. */ | 365 | * and incoming forward buffer have some space. */ |
@@ -364,24 +371,26 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) | |||
364 | if ( (daemon->shutdown) && | 371 | if ( (daemon->shutdown) && |
365 | ( (0 != urh->out_buffer_size) || | 372 | ( (0 != urh->out_buffer_size) || |
366 | (0 != urh->out_buffer_used) ) ) | 373 | (0 != urh->out_buffer_used) ) ) |
367 | { | 374 | { |
368 | /* Daemon shutting down, discard any remaining forward data. */ | 375 | /* Daemon shutting down, discard any remaining forward data. */ |
369 | #ifdef HAVE_MESSAGES | 376 | #ifdef HAVE_MESSAGES |
370 | if (0 < urh->out_buffer_used) | 377 | if (0 < urh->out_buffer_used) |
371 | MHD_DLOG (daemon, | 378 | MHD_DLOG (daemon, |
372 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, | 379 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, |
373 | _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 380 | _ ( |
374 | " bytes of data received from application: daemon shut down\n"), | 381 | "Failed to forward to remote client " |
375 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); | 382 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
383 | " bytes of data received from application: daemon shut down\n"), | ||
384 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); | ||
376 | #endif | 385 | #endif |
377 | /* Discard any data unsent to remote. */ | 386 | /* Discard any data unsent to remote. */ |
378 | urh->out_buffer_used = 0; | 387 | urh->out_buffer_used = 0; |
379 | /* Do not try to sent to remote anymore. */ | 388 | /* Do not try to sent to remote anymore. */ |
380 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 389 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
381 | /* Do not try to pull more data from application. */ | 390 | /* Do not try to pull more data from application. */ |
382 | urh->out_buffer_size = 0; | 391 | urh->out_buffer_size = 0; |
383 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 392 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
384 | } | 393 | } |
385 | } | 394 | } |
386 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 395 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
387 | 396 | ||