aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r--src/daemon/daemon.c372
1 files changed, 212 insertions, 160 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index d85ed92a..2f367f25 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -121,6 +121,7 @@ MHD_get_master (struct MHD_Daemon *daemon)
121 return daemon; 121 return daemon;
122} 122}
123 123
124
124/** 125/**
125 * Maintain connection count for single address. 126 * Maintain connection count for single address.
126 */ 127 */
@@ -154,6 +155,7 @@ struct MHD_IPCount
154 unsigned int count; 155 unsigned int count;
155}; 156};
156 157
158
157/** 159/**
158 * Lock shared structure for IP connection counts and connection DLLs. 160 * Lock shared structure for IP connection counts and connection DLLs.
159 * 161 *
@@ -171,6 +173,7 @@ MHD_ip_count_lock(struct MHD_Daemon *daemon)
171 } 173 }
172} 174}
173 175
176
174/** 177/**
175 * Unlock shared structure for IP connection counts and connection DLLs. 178 * Unlock shared structure for IP connection counts and connection DLLs.
176 * 179 *
@@ -203,6 +206,7 @@ MHD_ip_addr_compare(const void *a1, const void *a2)
203 return memcmp (a1, a2, offsetof(struct MHD_IPCount, count)); 206 return memcmp (a1, a2, offsetof(struct MHD_IPCount, count));
204} 207}
205 208
209
206/** 210/**
207 * Parse address and initialize 'key' using the address. 211 * Parse address and initialize 'key' using the address.
208 * 212 *
@@ -241,6 +245,7 @@ MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen,
241 return MHD_NO; 245 return MHD_NO;
242} 246}
243 247
248
244/** 249/**
245 * Check if IP address is over its limit. 250 * Check if IP address is over its limit.
246 * 251 *
@@ -308,6 +313,7 @@ MHD_ip_limit_add(struct MHD_Daemon *daemon,
308 return result; 313 return result;
309} 314}
310 315
316
311/** 317/**
312 * Decrement connection count for IP address, removing from table 318 * Decrement connection count for IP address, removing from table
313 * count reaches 0 319 * count reaches 0
@@ -372,9 +378,11 @@ MHD_ip_limit_del(struct MHD_Daemon *daemon,
372 MHD_ip_count_unlock (daemon); 378 MHD_ip_count_unlock (daemon);
373} 379}
374 380
381
375#if HTTPS_SUPPORT 382#if HTTPS_SUPPORT
376static pthread_mutex_t MHD_gnutls_init_mutex; 383static pthread_mutex_t MHD_gnutls_init_mutex;
377 384
385
378/** 386/**
379 * Callback for receiving data from the socket. 387 * Callback for receiving data from the socket.
380 * 388 *
@@ -442,19 +450,21 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
442 gnutls_datum_t key; 450 gnutls_datum_t key;
443 gnutls_datum_t cert; 451 gnutls_datum_t cert;
444 452
445 if (daemon->https_mem_trust) { 453 if (daemon->https_mem_trust)
446 cert.data = (unsigned char *) daemon->https_mem_trust; 454 {
447 cert.size = strlen(daemon->https_mem_trust); 455 cert.data = (unsigned char *) daemon->https_mem_trust;
448 if (gnutls_certificate_set_x509_trust_mem(daemon->x509_cred, &cert, 456 cert.size = strlen (daemon->https_mem_trust);
449 GNUTLS_X509_FMT_PEM) < 0) { 457 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, &cert,
458 GNUTLS_X509_FMT_PEM) < 0)
459 {
450#if HAVE_MESSAGES 460#if HAVE_MESSAGES
451 MHD_DLOG(daemon, 461 MHD_DLOG(daemon,
452 "Bad trust certificate format\n"); 462 "Bad trust certificate format\n");
453#endif 463#endif
454 return -1; 464 return -1;
455 }
456 } 465 }
457 466 }
467
458 /* certificate & key loaded from memory */ 468 /* certificate & key loaded from memory */
459 if (daemon->https_mem_cert && daemon->https_mem_key) 469 if (daemon->https_mem_cert && daemon->https_mem_key)
460 { 470 {
@@ -473,6 +483,7 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
473 return -1; 483 return -1;
474} 484}
475 485
486
476/** 487/**
477 * Initialize security aspects of the HTTPS daemon 488 * Initialize security aspects of the HTTPS daemon
478 * 489 *
@@ -516,41 +527,44 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
516 */ 527 */
517int 528int
518MHD_get_fdset (struct MHD_Daemon *daemon, 529MHD_get_fdset (struct MHD_Daemon *daemon,
519 fd_set * read_fd_set, 530 fd_set *read_fd_set,
520 fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd) 531 fd_set *write_fd_set,
532 fd_set *except_fd_set,
533 int *max_fd)
521{ 534{
522 struct MHD_Connection *pos; 535 struct MHD_Connection *pos;
523 struct MHD_Connection *next;
524 int fd; 536 int fd;
525 537
526 if ((daemon == NULL) || (read_fd_set == NULL) || (write_fd_set == NULL) 538 if ( (NULL == daemon)
527 || (except_fd_set == NULL) || (max_fd == NULL) 539 || (NULL == read_fd_set)
528 || (-1 == (fd = daemon->socket_fd)) || (daemon->shutdown == MHD_YES) 540 || (NULL == write_fd_set)
529 || ((daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0) 541 || (NULL == except_fd_set)
530 || ((daemon->options & MHD_USE_POLL) != 0)) 542 || (NULL == max_fd)
543 || (MHD_YES == daemon->shutdown)
544 || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
545 || (0 != (daemon->options & MHD_USE_POLL)))
531 return MHD_NO; 546 return MHD_NO;
532 547 fd = daemon->socket_fd;
533 FD_SET (fd, read_fd_set); 548 if (-1 != fd)
534 /* update max file descriptor */ 549 {
535 if ((*max_fd) < fd) 550 FD_SET (fd, read_fd_set);
536 *max_fd = fd; 551 /* update max file descriptor */
537 552 if ((*max_fd) < fd)
538 next = daemon->connections_head; 553 *max_fd = fd;
539 while (NULL != (pos = next)) 554 }
540 { 555 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
541 next = pos->next; 556 if (MHD_YES != MHD_connection_get_fdset (pos,
542 if (MHD_YES != MHD_connection_get_fdset (pos, 557 read_fd_set,
543 read_fd_set, 558 write_fd_set,
544 write_fd_set, 559 except_fd_set, max_fd))
545 except_fd_set, max_fd)) 560 return MHD_NO;
546 return MHD_NO;
547 }
548#if DEBUG_CONNECT 561#if DEBUG_CONNECT
549 MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd); 562 MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd);
550#endif 563#endif
551 return MHD_YES; 564 return MHD_YES;
552} 565}
553 566
567
554/** 568/**
555 * Main function of the thread that handles an individual 569 * Main function of the thread that handles an individual
556 * connection when MHD_USE_THREAD_PER_CONNECTION is set. 570 * connection when MHD_USE_THREAD_PER_CONNECTION is set.
@@ -577,7 +591,8 @@ MHD_handle_connection (void *data)
577#endif 591#endif
578 592
579 timeout = con->daemon->connection_timeout; 593 timeout = con->daemon->connection_timeout;
580 while ( (!con->daemon->shutdown) && (con->state != MHD_CONNECTION_CLOSED) ) 594 while ( (MHD_YES != con->daemon->shutdown) &&
595 (MHD_CONNECTION_CLOSED != con->state) )
581 { 596 {
582 tvp = NULL; 597 tvp = NULL;
583 if (timeout > 0) 598 if (timeout > 0)
@@ -687,6 +702,7 @@ exit:
687 return NULL; 702 return NULL;
688} 703}
689 704
705
690/** 706/**
691 * Callback for receiving data from the socket. 707 * Callback for receiving data from the socket.
692 * 708 *
@@ -700,8 +716,8 @@ recv_param_adapter (struct MHD_Connection *connection,
700 void *other, 716 void *other,
701 size_t i) 717 size_t i)
702{ 718{
703 if ( (connection->socket_fd == -1) || 719 if ( (-1 == connection->socket_fd) ||
704 (connection->state == MHD_CONNECTION_CLOSED) ) 720 (MHD_CONNECTION_CLOSED == connection->state) )
705 { 721 {
706 errno = ENOTCONN; 722 errno = ENOTCONN;
707 return -1; 723 return -1;
@@ -711,6 +727,7 @@ recv_param_adapter (struct MHD_Connection *connection,
711 return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL); 727 return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
712} 728}
713 729
730
714/** 731/**
715 * Callback for writing data to the socket. 732 * Callback for writing data to the socket.
716 * 733 *
@@ -1342,8 +1359,9 @@ MHD_select (struct MHD_Daemon *daemon,
1342 1359
1343 /* If we're at the connection limit, no need to 1360 /* If we're at the connection limit, no need to
1344 accept new connections. */ 1361 accept new connections. */
1345 if ( (daemon->max_connections == 0) && (daemon->socket_fd != -1) ) 1362 if ( (0 == daemon->max_connections) &&
1346 FD_CLR(daemon->socket_fd, &rs); 1363 (-1 != daemon->socket_fd) )
1364 FD_CLR (daemon->socket_fd, &rs);
1347 } 1365 }
1348 else 1366 else
1349 { 1367 {
@@ -1354,14 +1372,13 @@ MHD_select (struct MHD_Daemon *daemon,
1354 FD_SET (max, &rs); 1372 FD_SET (max, &rs);
1355 } 1373 }
1356 1374
1357#ifndef HAVE_LISTEN_SHUTDOWN 1375 if (-1 != daemon->wpipe[0])
1358 if (-1 == daemon->wpipe[0]) 1376 {
1359 return MHD_NO; 1377 FD_SET (daemon->wpipe[0], &rs);
1360 FD_SET (daemon->wpipe[0], &rs); 1378 /* update max file descriptor */
1361 /* update max file descriptor */ 1379 if (max < daemon->wpipe[0])
1362 if (max < daemon->wpipe[0]) 1380 max = daemon->wpipe[0];
1363 max = daemon->wpipe[0]; 1381 }
1364#endif
1365 1382
1366 tv = NULL; 1383 tv = NULL;
1367 if (may_block == MHD_NO) 1384 if (may_block == MHD_NO)
@@ -1391,12 +1408,12 @@ MHD_select (struct MHD_Daemon *daemon,
1391#endif 1408#endif
1392 return MHD_NO; 1409 return MHD_NO;
1393 } 1410 }
1394 ds = daemon->socket_fd; 1411 if (MHD_YES == daemon->shutdown)
1395 if (ds == -1)
1396 return MHD_YES; 1412 return MHD_YES;
1397 1413
1398 /* select connection thread handling type */ 1414 /* select connection thread handling type */
1399 if (FD_ISSET (ds, &rs)) 1415 if ( (-1 != (ds = daemon->socket_fd)) &&
1416 (FD_ISSET (ds, &rs)) )
1400 MHD_accept_connection (daemon); 1417 MHD_accept_connection (daemon);
1401 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 1418 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1402 { 1419 {
@@ -1445,35 +1462,33 @@ MHD_poll_all (struct MHD_Daemon *daemon,
1445 pos = pos->next; 1462 pos = pos->next;
1446 } 1463 }
1447 { 1464 {
1448 #ifdef HAVE_LISTEN_SHUTDOWN
1449 struct pollfd p[1 + num_connections];
1450 #else
1451 struct pollfd p[2 + num_connections]; 1465 struct pollfd p[2 + num_connections];
1452 #endif
1453 struct MHD_Pollfd mp; 1466 struct MHD_Pollfd mp;
1454 unsigned MHD_LONG_LONG ltimeout; 1467 unsigned MHD_LONG_LONG ltimeout;
1455 unsigned int i; 1468 unsigned int i;
1456 int timeout; 1469 int timeout;
1457 unsigned int poll_server; 1470 unsigned int poll_server;
1471 int poll_listen;
1458 1472
1459 memset (p, 0, sizeof (p)); 1473 memset (p, 0, sizeof (p));
1460 if ( (daemon->max_connections > 0) && (daemon->socket_fd != -1) ) 1474 poll_server = 0;
1475 poll_listen = -1;
1476 if ( (-1 != daemon->socket_fd) &&
1477 (0 != daemon->max_connections) )
1461 { 1478 {
1462 p[0].fd = daemon->socket_fd; 1479 /* only listen if we are not at the connection limit */
1463 p[0].events = POLLIN; 1480 p[poll_server].fd = daemon->socket_fd;
1464 p[0].revents = 0; 1481 p[poll_server].events = POLLIN;
1465#ifdef HAVE_LISTEN_SHUTDOWN 1482 p[poll_server].revents = 0;
1466 poll_server = 1; 1483 poll_listen = (int) poll_server;
1467#else 1484 poll_server++;
1468 p[1].fd = daemon->wpipe[0];
1469 p[1].events = POLLIN;
1470 p[1].revents = 0;
1471 poll_server = 2;
1472#endif
1473 } 1485 }
1474 else 1486 if (-1 != daemon->wpipe[0])
1475 { 1487 {
1476 poll_server = 0; 1488 p[poll_server].fd = daemon->wpipe[0];
1489 p[poll_server].events = POLLIN;
1490 p[poll_server].revents = 0;
1491 poll_server++;
1477 } 1492 }
1478 if (may_block == MHD_NO) 1493 if (may_block == MHD_NO)
1479 timeout = 0; 1494 timeout = 0;
@@ -1484,8 +1499,7 @@ MHD_poll_all (struct MHD_Daemon *daemon,
1484 timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout; 1499 timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
1485 1500
1486 i = 0; 1501 i = 0;
1487 pos = daemon->connections_head; 1502 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
1488 while (pos != NULL)
1489 { 1503 {
1490 memset(&mp, 0, sizeof (struct MHD_Pollfd)); 1504 memset(&mp, 0, sizeof (struct MHD_Pollfd));
1491 MHD_connection_get_pollfd (pos, &mp); 1505 MHD_connection_get_pollfd (pos, &mp);
@@ -1495,22 +1509,19 @@ MHD_poll_all (struct MHD_Daemon *daemon,
1495 if (mp.events & MHD_POLL_ACTION_OUT) 1509 if (mp.events & MHD_POLL_ACTION_OUT)
1496 p[poll_server+i].events |= POLLOUT; 1510 p[poll_server+i].events |= POLLOUT;
1497 i++; 1511 i++;
1498 pos = pos->next;
1499 } 1512 }
1500 if (poll (p, poll_server + num_connections, timeout) < 0) 1513 if (poll (p, poll_server + num_connections, timeout) < 0)
1501 { 1514 {
1502 if (errno == EINTR) 1515 if (EINTR == errno)
1503 return MHD_YES; 1516 return MHD_YES;
1504#if HAVE_MESSAGES 1517#if HAVE_MESSAGES
1505 MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno)); 1518 MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno));
1506#endif 1519#endif
1507 return MHD_NO; 1520 return MHD_NO;
1508 } 1521 }
1509 /* handle shutdown cases */ 1522 /* handle shutdown */
1510 if (daemon->shutdown == MHD_YES) 1523 if (MHD_YES == daemon->shutdown)
1511 return MHD_NO; 1524 return MHD_NO;
1512 if (daemon->socket_fd < 0)
1513 return MHD_YES;
1514 i = 0; 1525 i = 0;
1515 next = daemon->connections_head; 1526 next = daemon->connections_head;
1516 while (NULL != (pos = next)) 1527 while (NULL != (pos = next))
@@ -1531,8 +1542,8 @@ MHD_poll_all (struct MHD_Daemon *daemon,
1531 pos->idle_handler (pos); 1542 pos->idle_handler (pos);
1532 i++; 1543 i++;
1533 } 1544 }
1534 if ( (0 != poll_server) && 1545 if ( (-1 != poll_listen) &&
1535 (0 != (p[0].revents & POLLIN)) ) 1546 (0 != (p[poll_listen].revents & POLLIN)) )
1536 MHD_accept_connection (daemon); 1547 MHD_accept_connection (daemon);
1537 } 1548 }
1538 return MHD_YES; 1549 return MHD_YES;
@@ -1550,41 +1561,47 @@ static int
1550MHD_poll_listen_socket (struct MHD_Daemon *daemon, 1561MHD_poll_listen_socket (struct MHD_Daemon *daemon,
1551 int may_block) 1562 int may_block)
1552{ 1563{
1553#ifdef HAVE_LISTEN_SHUTDOWN
1554 struct pollfd p[1];
1555#else
1556 struct pollfd p[2]; 1564 struct pollfd p[2];
1557#endif
1558 int timeout; 1565 int timeout;
1559 1566 unsigned int poll_count;
1567 int poll_listen;
1568
1560 memset (&p, 0, sizeof (p)); 1569 memset (&p, 0, sizeof (p));
1561 p[0].fd = daemon->socket_fd; 1570 poll_count = 0;
1562 p[0].events = POLLIN; 1571 poll_listen = -1;
1563 p[0].revents = 0; 1572 if (-1 != daemon->socket_fd)
1564#ifndef HAVE_LISTEN_SHUTDOWN 1573 {
1565 p[1].fd = daemon->wpipe[0]; 1574 p[poll_count].fd = daemon->socket_fd;
1566 p[1].events = POLLIN; 1575 p[poll_count].events = POLLIN;
1567 p[1].revents = 0; 1576 p[poll_count].revents = 0;
1568#endif 1577 poll_listen = poll_count;
1569 if (may_block == MHD_NO) 1578 poll_count++;
1579 }
1580 if (-1 != daemon->wpipe[0])
1581 {
1582 p[poll_count].fd = daemon->wpipe[0];
1583 p[poll_count].events = POLLIN;
1584 p[poll_count].revents = 0;
1585 poll_count++;
1586 }
1587 if (MHD_NO == may_block)
1570 timeout = 0; 1588 timeout = 0;
1571 else 1589 else
1572 timeout = -1; 1590 timeout = -1;
1573 if (poll (p, (sizeof(p)/sizeof(struct pollfd)), timeout) < 0) 1591 if (poll (p, poll_count, timeout) < 0)
1574 { 1592 {
1575 if (errno == EINTR) 1593 if (EINTR == errno)
1576 return MHD_YES; 1594 return MHD_YES;
1577#if HAVE_MESSAGES 1595#if HAVE_MESSAGES
1578 MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno)); 1596 MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno));
1579#endif 1597#endif
1580 return MHD_NO; 1598 return MHD_NO;
1581 } 1599 }
1582 /* handle shutdown cases */ 1600 /* handle shutdown */
1583 if (daemon->shutdown == MHD_YES) 1601 if (MHD_YES == daemon->shutdown)
1584 return MHD_NO; 1602 return MHD_NO;
1585 if (daemon->socket_fd < 0) 1603 if ( (-1 != poll_listen) &&
1586 return MHD_YES; 1604 (0 != (p[poll_listen].revents & POLLIN)) )
1587 if (0 != (p[0].revents & POLLIN))
1588 MHD_accept_connection (daemon); 1605 MHD_accept_connection (daemon);
1589 return MHD_YES; 1606 return MHD_YES;
1590} 1607}
@@ -1628,18 +1645,14 @@ MHD_poll (struct MHD_Daemon *daemon,
1628int 1645int
1629MHD_run (struct MHD_Daemon *daemon) 1646MHD_run (struct MHD_Daemon *daemon)
1630{ 1647{
1631 if ((daemon->shutdown != MHD_NO) || (0 != (daemon->options 1648 if ( (MHD_YES == daemon->shutdown) ||
1632 & MHD_USE_THREAD_PER_CONNECTION)) 1649 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
1633 || (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))) 1650 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
1634 return MHD_NO; 1651 return MHD_NO;
1635 if ((daemon->options & MHD_USE_POLL) == 0) 1652 if (0 == (daemon->options & MHD_USE_POLL))
1636 { 1653 MHD_select (daemon, MHD_NO);
1637 MHD_select (daemon, MHD_NO); 1654 else
1638 } 1655 MHD_poll (daemon, MHD_NO);
1639 else
1640 {
1641 MHD_poll (daemon, MHD_NO);
1642 }
1643 MHD_cleanup_connections (daemon); 1656 MHD_cleanup_connections (daemon);
1644 return MHD_YES; 1657 return MHD_YES;
1645} 1658}
@@ -1656,9 +1669,10 @@ static void *
1656MHD_select_thread (void *cls) 1669MHD_select_thread (void *cls)
1657{ 1670{
1658 struct MHD_Daemon *daemon = cls; 1671 struct MHD_Daemon *daemon = cls;
1659 while (daemon->shutdown == MHD_NO) 1672
1673 while (MHD_YES != daemon->shutdown)
1660 { 1674 {
1661 if ((daemon->options & MHD_USE_POLL) == 0) 1675 if (0 == (daemon->options & MHD_USE_POLL))
1662 MHD_select (daemon, MHD_YES); 1676 MHD_select (daemon, MHD_YES);
1663 else 1677 else
1664 MHD_poll (daemon, MHD_YES); 1678 MHD_poll (daemon, MHD_YES);
@@ -1686,17 +1700,26 @@ MHD_start_daemon (unsigned int options,
1686 void *apc_cls, 1700 void *apc_cls,
1687 MHD_AccessHandlerCallback dh, void *dh_cls, ...) 1701 MHD_AccessHandlerCallback dh, void *dh_cls, ...)
1688{ 1702{
1689 struct MHD_Daemon *ret; 1703 struct MHD_Daemon *daemon;
1690 va_list ap; 1704 va_list ap;
1691 1705
1692 va_start (ap, dh_cls); 1706 va_start (ap, dh_cls);
1693 ret = MHD_start_daemon_va (options, port, apc, apc_cls, dh, dh_cls, ap); 1707 daemon = MHD_start_daemon_va (options, port, apc, apc_cls, dh, dh_cls, ap);
1694 va_end (ap); 1708 va_end (ap);
1695 return ret; 1709 return daemon;
1696} 1710}
1697 1711
1698 1712
1699typedef void (*VfprintfFunctionPointerType)(void *, const char *, va_list); 1713/**
1714 * Signature of the MHD custom logger function.
1715 *
1716 * @param cls closure
1717 * @param format format string
1718 * @param va arguments to the format string (fprintf-style)
1719 */
1720typedef void (*VfprintfFunctionPointerType)(void *cls,
1721 const char *format,
1722 va_list va);
1700 1723
1701 1724
1702/** 1725/**
@@ -2009,7 +2032,7 @@ create_socket (int domain, int type, int protocol)
2009 2032
2010 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo 2033 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
2011 * implementations do not set ai_socktype, e.g. RHL6.2. */ 2034 * implementations do not set ai_socktype, e.g. RHL6.2. */
2012 fd = SOCKET(domain, ctype, protocol); 2035 fd = SOCKET (domain, ctype, protocol);
2013 if ( (-1 == fd) && (EINVAL == errno) && (0 != sock_cloexec) ) 2036 if ( (-1 == fd) && (EINVAL == errno) && (0 != sock_cloexec) )
2014 { 2037 {
2015 sock_cloexec = 0; 2038 sock_cloexec = 0;
@@ -2090,6 +2113,7 @@ MHD_start_daemon_va (unsigned int options,
2090 socklen_t addrlen; 2113 socklen_t addrlen;
2091 unsigned int i; 2114 unsigned int i;
2092 int res_thread_create; 2115 int res_thread_create;
2116 int use_pipe;
2093 2117
2094 if ((port == 0) || (dh == NULL)) 2118 if ((port == 0) || (dh == NULL))
2095 return NULL; 2119 return NULL;
@@ -2116,10 +2140,15 @@ MHD_start_daemon_va (unsigned int options,
2116 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 2140 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
2117 retVal->unescape_callback = &MHD_http_unescape; 2141 retVal->unescape_callback = &MHD_http_unescape;
2118 retVal->connection_timeout = 0; /* no timeout */ 2142 retVal->connection_timeout = 0; /* no timeout */
2119#ifndef HAVE_LISTEN_SHUTDOWN
2120 retVal->wpipe[0] = -1; 2143 retVal->wpipe[0] = -1;
2121 retVal->wpipe[1] = -1; 2144 retVal->wpipe[1] = -1;
2122 if (0 != PIPE (retVal->wpipe)) 2145#ifdef HAVE_LISTEN_SHUTDOWN
2146 use_pipe = (0 != (retVal->options & MHD_USE_NO_LISTEN_SOCKET));
2147#else
2148 use_pipe = 1; /* yes, must use pipe to signal shutdown */
2149#endif
2150 if ( (use_pipe) &&
2151 (0 != PIPE (retVal->wpipe)) )
2123 { 2152 {
2124#if HAVE_MESSAGES 2153#if HAVE_MESSAGES
2125 FPRINTF(stderr, 2154 FPRINTF(stderr,
@@ -2143,7 +2172,6 @@ MHD_start_daemon_va (unsigned int options,
2143 return NULL; 2172 return NULL;
2144 } 2173 }
2145#endif 2174#endif
2146#endif
2147#ifdef DAUTH_SUPPORT 2175#ifdef DAUTH_SUPPORT
2148 retVal->digest_auth_rand_size = 0; 2176 retVal->digest_auth_rand_size = 0;
2149 retVal->digest_auth_random = NULL; 2177 retVal->digest_auth_random = NULL;
@@ -2155,13 +2183,13 @@ MHD_start_daemon_va (unsigned int options,
2155 retVal->custom_error_log_cls = stderr; 2183 retVal->custom_error_log_cls = stderr;
2156#endif 2184#endif
2157#if HTTPS_SUPPORT 2185#if HTTPS_SUPPORT
2158 if (options & MHD_USE_SSL) 2186 if (0 != (options & MHD_USE_SSL))
2159 { 2187 {
2160 /* lock MHD_gnutls_global mutex since it uses reference counting */ 2188 /* lock MHD_gnutls_global mutex since it uses reference counting */
2161 if (0 != pthread_mutex_lock (&MHD_gnutls_init_mutex)) 2189 if (0 != pthread_mutex_lock (&MHD_gnutls_init_mutex))
2162 { 2190 {
2163#if HAVE_MESSAGES 2191#if HAVE_MESSAGES
2164 MHD_DLOG (retVal, "Failed to aquire gnutls mutex\n"); 2192 MHD_DLOG (retVal, "Failed to acquire gnutls mutex\n");
2165#endif 2193#endif
2166 mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); 2194 mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);
2167 } 2195 }
@@ -2258,8 +2286,10 @@ MHD_start_daemon_va (unsigned int options,
2258 goto free_and_fail; 2286 goto free_and_fail;
2259 } 2287 }
2260#endif 2288#endif
2261 if (retVal->socket_fd == -1) 2289 if ( (-1 == retVal->socket_fd) &&
2290 (0 == (retVal->options & MHD_USE_NO_LISTEN_SOCKET)) )
2262 { 2291 {
2292 /* try to open listen socket */
2263 if ((options & MHD_USE_IPv6) != 0) 2293 if ((options & MHD_USE_IPv6) != 0)
2264#if HAVE_INET6 2294#if HAVE_INET6
2265 socket_fd = create_socket (PF_INET6, SOCK_STREAM, 0); 2295 socket_fd = create_socket (PF_INET6, SOCK_STREAM, 0);
@@ -2403,7 +2433,8 @@ MHD_start_daemon_va (unsigned int options,
2403 MHD_DLOG (retVal, 2433 MHD_DLOG (retVal,
2404 "MHD failed to initialize IP connection limit mutex\n"); 2434 "MHD failed to initialize IP connection limit mutex\n");
2405#endif 2435#endif
2406 CLOSE (socket_fd); 2436 if (-1 != socket_fd)
2437 CLOSE (socket_fd);
2407 goto free_and_fail; 2438 goto free_and_fail;
2408 } 2439 }
2409 if (0 != pthread_mutex_init (&retVal->cleanup_connection_mutex, NULL)) 2440 if (0 != pthread_mutex_init (&retVal->cleanup_connection_mutex, NULL))
@@ -2413,7 +2444,8 @@ MHD_start_daemon_va (unsigned int options,
2413 "MHD failed to initialize IP connection limit mutex\n"); 2444 "MHD failed to initialize IP connection limit mutex\n");
2414#endif 2445#endif
2415 pthread_mutex_destroy (&retVal->cleanup_connection_mutex); 2446 pthread_mutex_destroy (&retVal->cleanup_connection_mutex);
2416 CLOSE (socket_fd); 2447 if (-1 != socket_fd)
2448 CLOSE (socket_fd);
2417 goto free_and_fail; 2449 goto free_and_fail;
2418 } 2450 }
2419 2451
@@ -2425,7 +2457,8 @@ MHD_start_daemon_va (unsigned int options,
2425 MHD_DLOG (retVal, 2457 MHD_DLOG (retVal,
2426 "Failed to initialize TLS support\n"); 2458 "Failed to initialize TLS support\n");
2427#endif 2459#endif
2428 CLOSE (socket_fd); 2460 if (-1 != socket_fd)
2461 CLOSE (socket_fd);
2429 pthread_mutex_destroy (&retVal->cleanup_connection_mutex); 2462 pthread_mutex_destroy (&retVal->cleanup_connection_mutex);
2430 pthread_mutex_destroy (&retVal->per_ip_connection_mutex); 2463 pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
2431 goto free_and_fail; 2464 goto free_and_fail;
@@ -2434,6 +2467,7 @@ MHD_start_daemon_va (unsigned int options,
2434 if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || 2467 if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
2435 ( (0 != (options & MHD_USE_SELECT_INTERNALLY)) && 2468 ( (0 != (options & MHD_USE_SELECT_INTERNALLY)) &&
2436 (0 == retVal->worker_pool_size)) ) && 2469 (0 == retVal->worker_pool_size)) ) &&
2470 (0 == (retVal->options & MHD_USE_NO_LISTEN_SOCKET)) &&
2437 (0 != (res_thread_create = 2471 (0 != (res_thread_create =
2438 create_thread (&retVal->pid, retVal, &MHD_select_thread, retVal)))) 2472 create_thread (&retVal->pid, retVal, &MHD_select_thread, retVal))))
2439 { 2473 {
@@ -2444,10 +2478,12 @@ MHD_start_daemon_va (unsigned int options,
2444#endif 2478#endif
2445 pthread_mutex_destroy (&retVal->cleanup_connection_mutex); 2479 pthread_mutex_destroy (&retVal->cleanup_connection_mutex);
2446 pthread_mutex_destroy (&retVal->per_ip_connection_mutex); 2480 pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
2447 CLOSE (socket_fd); 2481 if (-1 != socket_fd)
2482 CLOSE (socket_fd);
2448 goto free_and_fail; 2483 goto free_and_fail;
2449 } 2484 }
2450 if (retVal->worker_pool_size > 0) 2485 if ( (retVal->worker_pool_size > 0) &&
2486 (0 == (retVal->options & MHD_USE_NO_LISTEN_SOCKET)) )
2451 { 2487 {
2452#ifndef MINGW 2488#ifndef MINGW
2453 int sk_flags; 2489 int sk_flags;
@@ -2535,7 +2571,8 @@ thread_failed:
2535 MHD_USE_SELECT_INTERNALLY mode. */ 2571 MHD_USE_SELECT_INTERNALLY mode. */
2536 if (i == 0) 2572 if (i == 0)
2537 { 2573 {
2538 CLOSE (socket_fd); 2574 if (-1 != socket_fd)
2575 CLOSE (socket_fd);
2539 pthread_mutex_destroy (&retVal->cleanup_connection_mutex); 2576 pthread_mutex_destroy (&retVal->cleanup_connection_mutex);
2540 pthread_mutex_destroy (&retVal->per_ip_connection_mutex); 2577 pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
2541 if (NULL != retVal->worker_pool) 2578 if (NULL != retVal->worker_pool)
@@ -2653,16 +2690,25 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2653 fd = daemon->socket_fd; 2690 fd = daemon->socket_fd;
2654 daemon->socket_fd = -1; 2691 daemon->socket_fd = -1;
2655 /* Prepare workers for shutdown */ 2692 /* Prepare workers for shutdown */
2656 for (i = 0; i < daemon->worker_pool_size; ++i) 2693 if (NULL != daemon->worker_pool)
2657 { 2694 {
2658 daemon->worker_pool[i].shutdown = MHD_YES; 2695 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
2659 daemon->worker_pool[i].socket_fd = -1; 2696 for (i = 0; i < daemon->worker_pool_size; ++i)
2697 {
2698 daemon->worker_pool[i].shutdown = MHD_YES;
2699 daemon->worker_pool[i].socket_fd = -1;
2700 }
2660 } 2701 }
2661#ifdef HAVE_LISTEN_SHUTDOWN
2662 SHUTDOWN (fd, SHUT_RDWR);
2663#else
2664 if (daemon->wpipe[1] != -1) 2702 if (daemon->wpipe[1] != -1)
2665 WRITE (daemon->wpipe[1], "e", 1); 2703 {
2704 WRITE (daemon->wpipe[1], "e", 1);
2705 }
2706#ifdef HAVE_LISTEN_SHUTDOWN
2707 else
2708 {
2709 /* fd must not be -1 here, otherwise we'd have used the wpipe */
2710 SHUTDOWN (fd, SHUT_RDWR);
2711 }
2666#endif 2712#endif
2667#if DEBUG_CLOSE 2713#if DEBUG_CLOSE
2668#if HAVE_MESSAGES 2714#if HAVE_MESSAGES
@@ -2672,40 +2718,47 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2672 2718
2673 2719
2674 /* Signal workers to stop and clean them up */ 2720 /* Signal workers to stop and clean them up */
2675 for (i = 0; i < daemon->worker_pool_size; ++i) 2721 if (NULL != daemon->worker_pool)
2676 { 2722 {
2677 if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused))) 2723 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
2724 for (i = 0; i < daemon->worker_pool_size; ++i)
2678 { 2725 {
2726 if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused)))
2727 {
2679#if HAVE_MESSAGES 2728#if HAVE_MESSAGES
2680 MHD_DLOG (daemon, "Failed to join a thread: %s\n", 2729 MHD_DLOG (daemon, "Failed to join a thread: %s\n",
2681 STRERROR (rc)); 2730 STRERROR (rc));
2682#endif 2731#endif
2683 abort(); 2732 abort();
2733 }
2734 close_all_connections (&daemon->worker_pool[i]);
2684 } 2735 }
2685 close_all_connections (&daemon->worker_pool[i]); 2736 free (daemon->worker_pool);
2686 } 2737 }
2687 free (daemon->worker_pool); 2738 else
2688
2689 /* clean up master threads */
2690 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2691 ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
2692 && (0 == daemon->worker_pool_size)))
2693 { 2739 {
2694 if (0 != (rc = pthread_join (daemon->pid, &unused))) 2740 /* clean up master threads */
2741 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2742 ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
2743 && (0 == daemon->worker_pool_size)))
2695 { 2744 {
2745 if (0 != (rc = pthread_join (daemon->pid, &unused)))
2746 {
2696#if HAVE_MESSAGES 2747#if HAVE_MESSAGES
2697 MHD_DLOG (daemon, "Failed to join a thread: %s\n", 2748 MHD_DLOG (daemon, "Failed to join a thread: %s\n",
2698 STRERROR (rc)); 2749 STRERROR (rc));
2699#endif 2750#endif
2700 abort(); 2751 abort();
2752 }
2701 } 2753 }
2702 } 2754 }
2703 close_all_connections (daemon); 2755 close_all_connections (daemon);
2704 CLOSE (fd); 2756 if (-1 != fd)
2757 CLOSE (fd);
2705 2758
2706 /* TLS clean up */ 2759 /* TLS clean up */
2707#if HTTPS_SUPPORT 2760#if HTTPS_SUPPORT
2708 if (daemon->options & MHD_USE_SSL) 2761 if (0 != (daemon->options & MHD_USE_SSL))
2709 { 2762 {
2710 gnutls_priority_deinit (daemon->priority_cache); 2763 gnutls_priority_deinit (daemon->priority_cache);
2711 if (daemon->x509_cred) 2764 if (daemon->x509_cred)
@@ -2714,7 +2767,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2714 if (0 != pthread_mutex_lock (&MHD_gnutls_init_mutex)) 2767 if (0 != pthread_mutex_lock (&MHD_gnutls_init_mutex))
2715 { 2768 {
2716#if HAVE_MESSAGES 2769#if HAVE_MESSAGES
2717 MHD_DLOG (daemon, "Failed to aquire gnutls mutex\n"); 2770 MHD_DLOG (daemon, "Failed to acquire gnutls mutex\n");
2718#endif 2771#endif
2719 abort(); 2772 abort();
2720 } 2773 }
@@ -2735,8 +2788,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2735 pthread_mutex_destroy (&daemon->per_ip_connection_mutex); 2788 pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2736 pthread_mutex_destroy (&daemon->cleanup_connection_mutex); 2789 pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2737 2790
2738#ifndef HAVE_LISTEN_SHUTDOWN 2791 if (-1 != daemon->wpipe[1])
2739 if (daemon->wpipe[1] != -1)
2740 { 2792 {
2741 char c; 2793 char c;
2742 2794
@@ -2746,7 +2798,6 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2746 CLOSE (daemon->wpipe[0]); 2798 CLOSE (daemon->wpipe[0]);
2747 CLOSE (daemon->wpipe[1]); 2799 CLOSE (daemon->wpipe[1]);
2748 } 2800 }
2749#endif
2750 2801
2751 free (daemon); 2802 free (daemon);
2752} 2803}
@@ -2770,7 +2821,7 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
2770 { 2821 {
2771 case MHD_DAEMON_INFO_LISTEN_FD: 2822 case MHD_DAEMON_INFO_LISTEN_FD:
2772 return (const union MHD_DaemonInfo *) &daemon->socket_fd; 2823 return (const union MHD_DaemonInfo *) &daemon->socket_fd;
2773 default: 2824 default:
2774 return NULL; 2825 return NULL;
2775 }; 2826 };
2776} 2827}
@@ -2791,7 +2842,8 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
2791 * @param cb new error handler 2842 * @param cb new error handler
2792 * @param cls passed to error handler 2843 * @param cls passed to error handler
2793 */ 2844 */
2794void MHD_set_panic_func (MHD_PanicCallback cb, void *cls) 2845void
2846MHD_set_panic_func (MHD_PanicCallback cb, void *cls)
2795{ 2847{
2796 mhd_panic = cb; 2848 mhd_panic = cb;
2797 mhd_panic_cls = cls; 2849 mhd_panic_cls = cls;