aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r--src/microhttpd/connection.c69
1 files changed, 55 insertions, 14 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 02fc0e71..84bfc662 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -4181,6 +4181,56 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
4181 4181
4182 4182
4183/** 4183/**
4184 * Check whether connection has timed out.
4185 * @param c the connection to check
4186 * @return true if connection has timeout and needs to be closed,
4187 * false otherwise.
4188 */
4189static bool
4190connection_check_timedout (struct MHD_Connection *c)
4191{
4192 const uint64_t timeout = c->connection_timeout_ms;
4193 uint64_t now;
4194 uint64_t since_actv;
4195
4196 if (c->suspended)
4197 return false;
4198 if (0 == timeout)
4199 return false;
4200 now = MHD_monotonic_msec_counter ();
4201 since_actv = now - c->last_activity;
4202 /* Keep the next lines in sync with #connection_get_wait() to avoid
4203 * undesired side-effects like busy-waiting. */
4204 if (timeout < since_actv)
4205 {
4206 if (UINT64_MAX / 2 < since_actv)
4207 {
4208 const uint64_t jump_back = c->last_activity - now;
4209 /* Very unlikely that it is more than quarter-million years pause.
4210 * More likely that system clock jumps back. */
4211 if (5000 >= jump_back)
4212 {
4213#ifdef HAVE_MESSAGES
4214 MHD_DLOG (c->daemon,
4215 _ ("Detected system clock %u milliseconds jump back.\n"),
4216 (unsigned int) jump_back);
4217#endif
4218 return false;
4219 }
4220#ifdef HAVE_MESSAGES
4221 MHD_DLOG (c->daemon,
4222 _ ("Detected too large system clock %" PRIu64 " milliseconds "
4223 "jump back.\n"),
4224 jump_back);
4225#endif
4226 }
4227 return true;
4228 }
4229 return false;
4230}
4231
4232
4233/**
4184 * Clean up the state of the given connection and move it into the 4234 * Clean up the state of the given connection and move it into the
4185 * clean up queue for final disposal. 4235 * clean up queue for final disposal.
4186 * @remark To be called only from thread that process connection's 4236 * @remark To be called only from thread that process connection's
@@ -4799,21 +4849,12 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4799 } 4849 }
4800 break; 4850 break;
4801 } 4851 }
4802 if (! connection->suspended) 4852 if (connection_check_timedout (connection))
4803 { 4853 {
4804 uint64_t timeout; 4854 MHD_connection_close_ (connection,
4805 timeout = connection->connection_timeout_ms; 4855 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
4806 /* Keep the next lines in sync with #MHD_get_timeout() to avoid 4856 connection->in_idle = false;
4807 * undesired side-effects like busy-waiting. */ 4857 return MHD_YES;
4808 if ( (0 != timeout) &&
4809 (timeout < (MHD_monotonic_msec_counter ()
4810 - connection->last_activity)) )
4811 {
4812 MHD_connection_close_ (connection,
4813 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
4814 connection->in_idle = false;
4815 return MHD_YES;
4816 }
4817 } 4858 }
4818 MHD_connection_update_event_loop_info (connection); 4859 MHD_connection_update_event_loop_info (connection);
4819 ret = MHD_YES; 4860 ret = MHD_YES;