aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c148
1 files changed, 98 insertions, 50 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 1625078d..d111d9cd 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -809,7 +809,7 @@ recv_param_adapter (struct MHD_Connection *connection,
809 } 809 }
810 ret = RECV (connection->socket_fd, other, i, MSG_NOSIGNAL); 810 ret = RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
811#if EPOLL_SUPPORT 811#if EPOLL_SUPPORT
812 if (ret < i) 812 if (ret < (ssize_t) i)
813 { 813 {
814 /* partial read --- no longer read-ready */ 814 /* partial read --- no longer read-ready */
815 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 815 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
@@ -884,7 +884,7 @@ send_param_adapter (struct MHD_Connection *connection,
884#endif 884#endif
885 ret = SEND (connection->socket_fd, other, i, MSG_NOSIGNAL); 885 ret = SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
886#if EPOLL_SUPPORT 886#if EPOLL_SUPPORT
887 if (ret < i) 887 if (ret < (ssize_t) i)
888 { 888 {
889 /* partial write --- no longer write-ready */ 889 /* partial write --- no longer write-ready */
890 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 890 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
@@ -1121,37 +1121,43 @@ MHD_add_connection (struct MHD_Daemon *daemon,
1121 MHD_set_http_callbacks_ (connection); 1121 MHD_set_http_callbacks_ (connection);
1122 connection->recv_cls = &recv_param_adapter; 1122 connection->recv_cls = &recv_param_adapter;
1123 connection->send_cls = &send_param_adapter; 1123 connection->send_cls = &send_param_adapter;
1124 /* non-blocking sockets are required on most systems and for GNUtls; 1124
1125 however, they somehow cause serious problems on CYGWIN (#1824) */ 1125 if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
1126 {
1127 /* non-blocking sockets are required on most systems and for GNUtls;
1128 however, they somehow cause serious problems on CYGWIN (#1824);
1129 in turbo mode, we assume that non-blocking was already set
1130 by 'accept4' or whoever calls 'MHD_add_connection' */
1126#ifdef CYGWIN 1131#ifdef CYGWIN
1127 if (0 != (daemon->options & MHD_USE_SSL)) 1132 if (0 != (daemon->options & MHD_USE_SSL))
1128#endif 1133#endif
1129 { 1134 {
1130 /* make socket non-blocking */ 1135 /* make socket non-blocking */
1131#ifndef MINGW 1136#ifndef MINGW
1132 int flags = fcntl (connection->socket_fd, F_GETFL); 1137 int flags = fcntl (connection->socket_fd, F_GETFL);
1133 if ( (-1 == flags) || 1138 if ( (-1 == flags) ||
1134 (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) ) 1139 (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
1135 { 1140 {
1136#if HAVE_MESSAGES 1141#if HAVE_MESSAGES
1137 MHD_DLOG (daemon, 1142 MHD_DLOG (daemon,
1138 "Failed to make socket %d non-blocking: %s\n", 1143 "Failed to make socket %d non-blocking: %s\n",
1139 connection->socket_fd, 1144 connection->socket_fd,
1140 STRERROR (errno)); 1145 STRERROR (errno));
1141#endif 1146#endif
1142 } 1147 }
1143#else 1148#else
1144 unsigned long flags = 1; 1149 unsigned long flags = 1;
1145 if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags)) 1150 if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
1146 { 1151 {
1147#if HAVE_MESSAGES 1152#if HAVE_MESSAGES
1148 MHD_DLOG (daemon, 1153 MHD_DLOG (daemon,
1149 "Failed to make socket non-blocking: %s\n", 1154 "Failed to make socket non-blocking: %s\n",
1150 STRERROR (errno)); 1155 STRERROR (errno));
1151#endif 1156#endif
1152 } 1157 }
1153#endif 1158#endif
1154 } 1159 }
1160 }
1155 1161
1156#if HTTPS_SUPPORT 1162#if HTTPS_SUPPORT
1157 if (0 != (daemon->options & MHD_USE_SSL)) 1163 if (0 != (daemon->options & MHD_USE_SSL))
@@ -1228,25 +1234,35 @@ MHD_add_connection (struct MHD_Daemon *daemon,
1228#if EPOLL_SUPPORT 1234#if EPOLL_SUPPORT
1229 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 1235 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1230 { 1236 {
1231 struct epoll_event event; 1237 if (0 == (daemon->options & MHD_USE_EPOLL_TURBO))
1232
1233 event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1234 event.data.ptr = connection;
1235 if (0 != epoll_ctl (daemon->epoll_fd,
1236 EPOLL_CTL_ADD,
1237 client_socket,
1238 &event))
1239 { 1238 {
1239 struct epoll_event event;
1240
1241 event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1242 event.data.ptr = connection;
1243 if (0 != epoll_ctl (daemon->epoll_fd,
1244 EPOLL_CTL_ADD,
1245 client_socket,
1246 &event))
1247 {
1240#if HAVE_MESSAGES 1248#if HAVE_MESSAGES
1241 if (0 != (daemon->options & MHD_USE_DEBUG)) 1249 if (0 != (daemon->options & MHD_USE_DEBUG))
1242 MHD_DLOG (daemon, 1250 MHD_DLOG (daemon,
1243 "Call to epoll_ctl failed: %s\n", 1251 "Call to epoll_ctl failed: %s\n",
1244 STRERROR (errno)); 1252 STRERROR (errno));
1245#endif 1253#endif
1246 goto cleanup; 1254 goto cleanup;
1255 }
1256 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
1257 }
1258 else
1259 {
1260 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
1261 | MHD_EPOLL_STATE_IN_EREADY_EDLL;
1262 EDLL_insert (daemon->eready_head,
1263 daemon->eready_tail,
1264 connection);
1247 } 1265 }
1248 daemon->listen_socket_in_epoll = MHD_YES;
1249
1250 } 1266 }
1251#endif 1267#endif
1252 daemon->max_connections--; 1268 daemon->max_connections--;
@@ -1300,13 +1316,19 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1300 socklen_t addrlen; 1316 socklen_t addrlen;
1301 int s; 1317 int s;
1302 int fd; 1318 int fd;
1319 int nonblock;
1303 1320
1304 addrlen = sizeof (addrstorage); 1321 addrlen = sizeof (addrstorage);
1305 memset (addr, 0, sizeof (addrstorage)); 1322 memset (addr, 0, sizeof (addrstorage));
1306 if (-1 == (fd = daemon->socket_fd)) 1323 if (-1 == (fd = daemon->socket_fd))
1307 return MHD_NO; 1324 return MHD_NO;
1325 nonblock = SOCK_NONBLOCK;
1326#ifdef CYGWIN
1327 if (0 == (daemon->options & MHD_USE_SSL))
1328 nonblock = 0;
1329#endif
1308#if HAVE_ACCEPT4 1330#if HAVE_ACCEPT4
1309 s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC); 1331 s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock);
1310#else 1332#else
1311 s = ACCEPT (fd, addr, &addrlen); 1333 s = ACCEPT (fd, addr, &addrlen);
1312#endif 1334#endif
@@ -1329,9 +1351,19 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1329 } 1351 }
1330#if !HAVE_ACCEPT4 1352#if !HAVE_ACCEPT4
1331 { 1353 {
1332 /* make socket non-inheritable */ 1354 /* make socket non-inheritable and non-blocking */
1333#ifdef WINDOWS 1355#ifdef WINDOWS
1334 DWORD dwFlags; 1356 DWORD dwFlags;
1357 unsigned long flags = 1;
1358
1359 if (0 != ioctlsocket (s, FIONBIO, &flags))
1360 {
1361#if HAVE_MESSAGES
1362 MHD_DLOG (daemon,
1363 "Failed to make socket non-blocking: %s\n",
1364 STRERROR (errno));
1365#endif
1366 }
1335 if (!GetHandleInformation ((HANDLE) s, &dwFlags) || 1367 if (!GetHandleInformation ((HANDLE) s, &dwFlags) ||
1336 ((dwFlags != dwFlags & ~HANDLE_FLAG_INHERIT) && 1368 ((dwFlags != dwFlags & ~HANDLE_FLAG_INHERIT) &&
1337 !SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0))) 1369 !SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0)))
@@ -1342,14 +1374,19 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1342 "Failed to make socket non-inheritable: %s\n", 1374 "Failed to make socket non-inheritable: %s\n",
1343 STRERROR (errno)); 1375 STRERROR (errno));
1344#endif 1376#endif
1345 } 1377 }
1346#else 1378#else
1347 int flags; 1379 int flags;
1348 1380
1381 nonblock = O_NONBLOCK;
1382#ifdef CYGWIN
1383 if (0 == (daemon->options & MHD_USE_SSL))
1384 nonblock = 0;
1385#endif
1349 flags = fcntl (s, F_GETFD); 1386 flags = fcntl (s, F_GETFD);
1350 if ( ( (-1 == flags) || 1387 if ( ( (-1 == flags) ||
1351 ( (flags != (flags | FD_CLOEXEC)) && 1388 ( (flags != (flags | FD_CLOEXEC)) &&
1352 (0 != fcntl (s, F_SETFD, flags | FD_CLOEXEC)) ) ) ) 1389 (0 != fcntl (s, F_SETFD, flags | nonblock | FD_CLOEXEC)) ) ) )
1353 { 1390 {
1354#if HAVE_MESSAGES 1391#if HAVE_MESSAGES
1355 MHD_DLOG (daemon, 1392 MHD_DLOG (daemon,
@@ -1358,7 +1395,10 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1358#endif 1395#endif
1359 } 1396 }
1360#endif 1397#endif
1398 /* make socket non-blocking */
1399
1361 } 1400 }
1401
1362#endif 1402#endif
1363#if HAVE_MESSAGES 1403#if HAVE_MESSAGES
1364#if DEBUG_CONNECT 1404#if DEBUG_CONNECT
@@ -1406,10 +1446,13 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
1406 if (pos->tls_session != NULL) 1446 if (pos->tls_session != NULL)
1407 gnutls_deinit (pos->tls_session); 1447 gnutls_deinit (pos->tls_session);
1408#endif 1448#endif
1409 MHD_ip_limit_del (daemon, (struct sockaddr*)pos->addr, pos->addr_len); 1449 MHD_ip_limit_del (daemon,
1450 (struct sockaddr *) pos->addr,
1451 pos->addr_len);
1410#if EPOLL_SUPPORT 1452#if EPOLL_SUPPORT
1411 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 1453 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
1412 (-1 != daemon->epoll_fd) ) 1454 (-1 != daemon->epoll_fd) &&
1455 (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
1413 { 1456 {
1414 /* epoll documentation suggests that closing a FD 1457 /* epoll documentation suggests that closing a FD
1415 automatically removes it from the epoll set; however, 1458 automatically removes it from the epoll set; however,
@@ -1422,6 +1465,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
1422 pos->socket_fd, 1465 pos->socket_fd,
1423 NULL)) 1466 NULL))
1424 MHD_PANIC ("Failed to remove FD from epoll set\n"); 1467 MHD_PANIC ("Failed to remove FD from epoll set\n");
1468 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1425 } 1469 }
1426#endif 1470#endif
1427 if (NULL != pos->response) 1471 if (NULL != pos->response)
@@ -1949,10 +1993,10 @@ MHD_poll (struct MHD_Daemon *daemon,
1949 1993
1950/** 1994/**
1951 * Do 'epoll'-based processing (this function is allowed to 1995 * Do 'epoll'-based processing (this function is allowed to
1952 * block). 1996 * block if 'may_block' is set to MHD_YES).
1953 * 1997 *
1954 * @param daemon daemon to run poll loop for 1998 * @param daemon daemon to run poll loop for
1955 * @param may_block YES if blocking, NO if non-blocking 1999 * @param may_block MHD_YES if blocking, MHD_NO if non-blocking
1956 * @return MHD_NO on serious errors, MHD_YES on success 2000 * @return MHD_NO on serious errors, MHD_YES on success
1957 */ 2001 */
1958static int 2002static int
@@ -1966,7 +2010,8 @@ MHD_epoll (struct MHD_Daemon *daemon,
1966 int timeout_ms; 2010 int timeout_ms;
1967 MHD_UNSIGNED_LONG_LONG timeout_ll; 2011 MHD_UNSIGNED_LONG_LONG timeout_ll;
1968 int num_events; 2012 int num_events;
1969 unsigned int i; 2013 unsigned int i;
2014 unsigned int series_length;
1970 2015
1971 if (-1 == daemon->epoll_fd) 2016 if (-1 == daemon->epoll_fd)
1972 return MHD_NO; /* we're down! */ 2017 return MHD_NO; /* we're down! */
@@ -2082,8 +2127,11 @@ MHD_epoll (struct MHD_Daemon *daemon,
2082 { 2127 {
2083 /* run 'accept' until it fails or we are not allowed to take 2128 /* run 'accept' until it fails or we are not allowed to take
2084 on more connections */ 2129 on more connections */
2130 series_length = 0;
2085 while ( (MHD_YES == MHD_accept_connection (daemon)) && 2131 while ( (MHD_YES == MHD_accept_connection (daemon)) &&
2086 (0 != daemon->max_connections) ) ; 2132 (0 != daemon->max_connections) &&
2133 (series_length < 128) )
2134 series_length++;
2087 } 2135 }
2088 } 2136 }
2089 } 2137 }
@@ -2094,7 +2142,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
2094 EDLL_remove (daemon->eready_head, 2142 EDLL_remove (daemon->eready_head,
2095 daemon->eready_tail, 2143 daemon->eready_tail,
2096 pos); 2144 pos);
2097 pos->epoll_state -= MHD_EPOLL_STATE_IN_EREADY_EDLL; 2145 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2098 if (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) 2146 if (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info)
2099 pos->read_handler (pos); 2147 pos->read_handler (pos);
2100 if (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) 2148 if (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info)