aboutsummaryrefslogtreecommitdiff
path: root/src/lib/daemon_start.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/daemon_start.c')
-rw-r--r--src/lib/daemon_start.c237
1 files changed, 131 insertions, 106 deletions
diff --git a/src/lib/daemon_start.c b/src/lib/daemon_start.c
index 98126c68..ab4a6dd9 100644
--- a/src/lib/daemon_start.c
+++ b/src/lib/daemon_start.c
@@ -48,40 +48,17 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
48 48
49 /* Apply the socket options according to 49 /* Apply the socket options according to
50 listening_address_reuse. */ 50 listening_address_reuse. */
51 /* FIXME: used to be -1/0/1, now defined as a bool! 51 if (daemon->allow_address_reuse)
52 MISMATCH! */
53 if (0 == daemon->listening_address_reuse)
54 {
55#ifndef MHD_WINSOCK_SOCKETS
56 /* No user requirement, use "traditional" default SO_REUSEADDR
57 * on non-W32 platforms, and do not fail if it doesn't work.
58 * Don't use it on W32, because on W32 it will allow multiple
59 * bind to the same address:port, like SO_REUSEPORT on others. */
60 if (0 > setsockopt (listen_fd,
61 SOL_SOCKET,
62 SO_REUSEADDR,
63 (void*) &on, sizeof (on)))
64 {
65#ifdef HAVE_MESSAGES
66 MHD_DLOG (daemon,
67 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
68 _("setsockopt failed: %s\n"),
69 MHD_socket_last_strerr_ ());
70#endif
71 }
72#endif /* ! MHD_WINSOCK_SOCKETS */
73 return MHD_SC_OK;
74 }
75 if (daemon->listening_address_reuse > 0)
76 { 52 {
77 /* User requested to allow reusing listening address:port. */ 53 /* User requested to allow reusing listening address:port. */
78#ifndef MHD_WINSOCK_SOCKETS 54#ifndef MHD_WINSOCK_SOCKETS
79 /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if 55 /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
80 * it doesn't work. */ 56 * it doesn't work. */
81 if (0 > setsockopt (listen_fd, 57 if (0 > setsockopt (daemon->listen_socket,
82 SOL_SOCKET, 58 SOL_SOCKET,
83 SO_REUSEADDR, 59 SO_REUSEADDR,
84 (void*)&on, sizeof (on))) 60 (void *) &on,
61 sizeof (on)))
85 { 62 {
86#ifdef HAVE_MESSAGES 63#ifdef HAVE_MESSAGES
87 MHD_DLOG (daemon, 64 MHD_DLOG (daemon,
@@ -91,6 +68,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
91#endif 68#endif
92 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; 69 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
93 } 70 }
71 return MHD_SC_OK;
94#endif /* ! MHD_WINSOCK_SOCKETS */ 72#endif /* ! MHD_WINSOCK_SOCKETS */
95 /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. 73 /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
96 * Fail if SO_REUSEPORT is not defined or setsockopt fails. 74 * Fail if SO_REUSEPORT is not defined or setsockopt fails.
@@ -98,7 +76,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
98 /* SO_REUSEADDR on W32 has the same semantics 76 /* SO_REUSEADDR on W32 has the same semantics
99 as SO_REUSEPORT on BSD/Linux */ 77 as SO_REUSEPORT on BSD/Linux */
100#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 78#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
101 if (0 > setsockopt (listen_fd, 79 if (0 > setsockopt (daemon->listen_socket,
102 SOL_SOCKET, 80 SOL_SOCKET,
103#ifndef MHD_WINSOCK_SOCKETS 81#ifndef MHD_WINSOCK_SOCKETS
104 SO_REUSEPORT, 82 SO_REUSEPORT,
@@ -116,6 +94,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
116#endif 94#endif
117 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; 95 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
118 } 96 }
97 return MHD_SC_OK;
119#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 98#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
120 /* we're supposed to allow address:port re-use, but 99 /* we're supposed to allow address:port re-use, but
121 on this platform we cannot; fail hard */ 100 on this platform we cannot; fail hard */
@@ -128,7 +107,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
128#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 107#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
129 } 108 }
130 109
131 /* if (daemon->listening_address_reuse < 0) */ 110 /* if (! daemon->allow_address_reuse) */
132 /* User requested to disallow reusing listening address:port. 111 /* User requested to disallow reusing listening address:port.
133 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE 112 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
134 * is used and Solaris with SO_EXCLBIND. 113 * is used and Solaris with SO_EXCLBIND.
@@ -155,6 +134,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
155#endif 134#endif
156 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED; 135 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED;
157 } 136 }
137 return MHD_SC_OK;
158#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ 138#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
159#ifdef HAVE_MESSAGES 139#ifdef HAVE_MESSAGES
160 MHD_DLOG (daemon, 140 MHD_DLOG (daemon,
@@ -163,6 +143,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
163#endif 143#endif
164 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED; 144 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED;
165#endif /* MHD_WINSOCK_SOCKETS */ 145#endif /* MHD_WINSOCK_SOCKETS */
146 /* Not on WINSOCK, simply doing nothing will do */
166 return MHD_SC_OK; 147 return MHD_SC_OK;
167} 148}
168 149
@@ -183,81 +164,75 @@ open_listen_socket (struct MHD_Daemon *daemon)
183 int pf; 164 int pf;
184 bool use_v6; 165 bool use_v6;
185 166
186 if (MHD_INVALID_SOCKET != daemon->listen_fd) 167 if (MHD_INVALID_SOCKET != daemon->listen_socket)
187 return MHD_SC_OK; /* application opened it for us! */ 168 return MHD_SC_OK; /* application opened it for us! */
188 169
189 /* Determine address family */ 170 /* Determine address family */
190 if (MHD_AF_NONE != daemon->address_family) 171 switch (daemon->listen_af)
191 { 172 {
192 switch (daemon->address_family) 173 case MHD_AF_NONE:
174 if (0 == daemon->listen_sa_len)
193 { 175 {
194 case MHD_AF_NONE: 176 /* no listening desired, that's OK */
195 abort (); 177 return MHD_SC_OK;
196 case MHD_AF_AUTO: 178 }
197#if HAVE_INET6 179 /* we have a listen address, get AF from there! */
198 pf = PF_INET6; 180 switch (daemon->listen_sa.ss_family)
199 use_v6 = true; 181 {
200#else 182 case AF_INET:
201 pf = PF_INET; 183 pf = PF_INET;
202 use_v6 = false; 184 use_v6 = false;
203#endif
204 break;
205 case MHD_AF_INET:
206 use_v6 = false;
207 pf = PF_INET;
208 break; 185 break;
209 case MHD_AF_INET6: 186#ifdef AF_INET6
210 case MHD_AF_DUAL: 187 case AF_INET6:
211#if HAVE_INET6
212 pf = PF_INET6; 188 pf = PF_INET6;
213 use_v6 = true; 189 use_v6 = true;
214 break; 190 break;
215#else
216#ifdef HAVE_MESSAGES
217 MHD_DLOG (daemon,
218 MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
219 _("IPv6 not supported by this build\n"));
220#endif 191#endif
221 return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD; 192#ifdef AF_UNIX
193 case AF_UNIX:
194 pf = PF_UNIX;
195 use_v6 = false;
196 break;
222#endif 197#endif
223 } 198 default:
224 } 199 return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
225 else if (0 != daemon->listen_sa_len) 200 } /* switch on ss_family */
226 { 201 break; /* MHD_AF_NONE */
227 202 case MHD_AF_AUTO:
228 /* we have a listen address, get AF from there! */ 203#if HAVE_INET6
229 switch (daemon->listen_sa.ss_family) 204 pf = PF_INET6;
230 { 205 use_v6 = true;
231 case AF_INET: 206#else
232 pf = PF_INET; 207 pf = PF_INET;
233 use_v6 = false; 208 use_v6 = false;
234 break;
235#ifdef AF_INET6
236 case AF_INET6:
237 pf = PF_INET6;
238 use_v6 = true;
239 break;
240#endif 209#endif
241#ifdef AF_UNIX 210 break;
242 case AF_UNIX: 211 case MHD_AF_INET4:
243 pf = PF_UNIX; 212 use_v6 = false;
244 use_v6 = false; 213 pf = PF_INET;
214 break;
215 case MHD_AF_INET6:
216 case MHD_AF_DUAL:
217#if HAVE_INET6
218 pf = PF_INET6;
219 use_v6 = true;
220 break;
221#else
222#ifdef HAVE_MESSAGES
223 MHD_DLOG (daemon,
224 MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
225 _("IPv6 not supported by this build\n"));
226#endif
227 return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD;
245#endif 228#endif
246 default:
247 return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
248 }
249 }
250 else
251 {
252 /* no listening desired, that's OK */
253 return MHD_SC_OK;
254 } 229 }
255 230
256 /* try to open listen socket */ 231 /* try to open listen socket */
257 try_open_listen_socket: 232 try_open_listen_socket:
258 daemon->listen_socket = MHD_socket_create_listen_(pf); 233 daemon->listen_socket = MHD_socket_create_listen_(pf);
259 if ( (MHD_INVALID_SOCKET == daemon->listen_socket) && 234 if ( (MHD_INVALID_SOCKET == daemon->listen_socket) &&
260 (MHD_AF_AUTO == daemon->address_family) && 235 (MHD_AF_AUTO == daemon->listen_af) &&
261 (use_v6) ) 236 (use_v6) )
262 { 237 {
263 use_v6 = false; 238 use_v6 = false;
@@ -288,8 +263,8 @@ open_listen_socket (struct MHD_Daemon *daemon)
288 and may also be missing on older POSIX systems; good luck if you have any of those, 263 and may also be missing on older POSIX systems; good luck if you have any of those,
289 your IPv6 socket may then also bind against IPv4 anyway... */ 264 your IPv6 socket may then also bind against IPv4 anyway... */
290 const MHD_SCKT_OPT_BOOL_ v6_only = 265 const MHD_SCKT_OPT_BOOL_ v6_only =
291 (MHD_AF_INET6 == daemon->address_family); 266 (MHD_AF_INET6 == daemon->listen_af);
292 if (0 > setsockopt (listen_fd, 267 if (0 > setsockopt (daemon->listen_socket,
293 IPPROTO_IPV6, 268 IPPROTO_IPV6,
294 IPV6_V6ONLY, 269 IPV6_V6ONLY,
295 (const void *) &v6_only, 270 (const void *) &v6_only,
@@ -315,7 +290,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
315 if (0 != daemon->listen_sa_len) 290 if (0 != daemon->listen_sa_len)
316 { 291 {
317 /* Bind address explicitly given */ 292 /* Bind address explicitly given */
318 sa = daemon->listen_sa; 293 sa = (const struct sockaddr *) &daemon->listen_sa;
319 addrlen = daemon->listen_sa_len; 294 addrlen = daemon->listen_sa_len;
320 } 295 }
321 else 296 else
@@ -359,7 +334,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
359 sin4->sin_len = sizeof (struct sockaddr_in); 334 sin4->sin_len = sizeof (struct sockaddr_in);
360#endif 335#endif
361 } 336 }
362 sa = (const struct sockaddr *) ss; 337 sa = (const struct sockaddr *) &ss;
363 } 338 }
364 339
365 /* actually do the bind() */ 340 /* actually do the bind() */
@@ -374,13 +349,13 @@ open_listen_socket (struct MHD_Daemon *daemon)
374 { 349 {
375 case AF_INET: 350 case AF_INET:
376 if (addrlen == sizeof (struct sockaddr_in)) 351 if (addrlen == sizeof (struct sockaddr_in))
377 port = ntohs (((const struct sockaddr_in*)sa)->sin_port); 352 port = ntohs (((const struct sockaddr_in *) sa)->sin_port);
378 else 353 else
379 port = UINT16_MAX + 1; /* indicate size error */ 354 port = UINT16_MAX + 1; /* indicate size error */
380 break; 355 break;
381 case AF_INET6: 356 case AF_INET6:
382 if (addrlen == sizeof (struct sockaddr_in6)) 357 if (addrlen == sizeof (struct sockaddr_in6))
383 port = ntohs (((const struct sockaddr_in6*)sa)->sin_port); 358 port = ntohs (((const struct sockaddr_in6 *) sa)->sin6_port);
384 else 359 else
385 port = UINT16_MAX + 1; /* indicate size error */ 360 port = UINT16_MAX + 1; /* indicate size error */
386 break; 361 break;
@@ -404,8 +379,8 @@ open_listen_socket (struct MHD_Daemon *daemon)
404 if (0 != setsockopt (daemon->listen_socket, 379 if (0 != setsockopt (daemon->listen_socket,
405 IPPROTO_TCP, 380 IPPROTO_TCP,
406 TCP_FASTOPEN, 381 TCP_FASTOPEN,
407 &daemon->fastopen_queue_size, 382 &daemon->fo_queue_length,
408 sizeof (daemon->fastopen_queue_size))) 383 sizeof (daemon->fo_queue_length)))
409 { 384 {
410#ifdef HAVE_MESSAGES 385#ifdef HAVE_MESSAGES
411 MHD_DLOG (daemon, 386 MHD_DLOG (daemon,
@@ -421,7 +396,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
421 396
422 /* setup listening */ 397 /* setup listening */
423 if (0 > listen (daemon->listen_socket, 398 if (0 > listen (daemon->listen_socket,
424 daemon->listen_backlog_size)) 399 daemon->listen_backlog))
425 { 400 {
426#ifdef HAVE_MESSAGES 401#ifdef HAVE_MESSAGES
427 MHD_DLOG (daemon, 402 MHD_DLOG (daemon,
@@ -449,7 +424,7 @@ get_listen_port_number (struct MHD_Daemon *daemon)
449 struct sockaddr_storage servaddr; 424 struct sockaddr_storage servaddr;
450 socklen_t addrlen; 425 socklen_t addrlen;
451 426
452 if ( (0 != daemon->port) || 427 if ( (0 != daemon->listen_port) ||
453 (MHD_INVALID_SOCKET == daemon->listen_socket) ) 428 (MHD_INVALID_SOCKET == daemon->listen_socket) )
454 return; /* nothing to be done */ 429 return; /* nothing to be done */
455 430
@@ -487,7 +462,7 @@ get_listen_port_number (struct MHD_Daemon *daemon)
487 { 462 {
488 struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr; 463 struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr;
489 464
490 daemon->port = ntohs (s4->sin_port); 465 daemon->listen_port = ntohs (s4->sin_port);
491 break; 466 break;
492 } 467 }
493#ifdef HAVE_INET6 468#ifdef HAVE_INET6
@@ -495,13 +470,13 @@ get_listen_port_number (struct MHD_Daemon *daemon)
495 { 470 {
496 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr; 471 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr;
497 472
498 daemon->port = ntohs(s6->sin6_port); 473 daemon->listen_port = ntohs(s6->sin6_port);
499 break; 474 break;
500 } 475 }
501#endif /* HAVE_INET6 */ 476#endif /* HAVE_INET6 */
502#ifdef AF_UNIX 477#ifdef AF_UNIX
503 case AF_UNIX: 478 case AF_UNIX:
504 daemon->port = 0; /* special value for UNIX domain sockets */ 479 daemon->listen_port = 0; /* special value for UNIX domain sockets */
505 break; 480 break;
506#endif 481#endif
507 default: 482 default:
@@ -510,12 +485,57 @@ get_listen_port_number (struct MHD_Daemon *daemon)
510 MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF, 485 MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF,
511 _("Unknown address family!\n")); 486 _("Unknown address family!\n"));
512#endif 487#endif
513 daemon->port = 0; /* ugh */ 488 daemon->listen_port = 0; /* ugh */
514 break; 489 break;
515 } 490 }
516} 491}
517 492
518 493
494#ifdef EPOLL_SUPPORT
495/**
496 * Setup file descriptor to be used for epoll() control.
497 *
498 * @param daemon the daemon to setup epoll FD for
499 * @return the epoll() fd to use
500 */
501static int
502setup_epoll_fd (struct MHD_Daemon *daemon)
503{
504 int fd;
505
506#ifndef HAVE_MESSAGES
507 (void)daemon; /* Mute compiler warning. */
508#endif /* ! HAVE_MESSAGES */
509
510#ifdef USE_EPOLL_CREATE1
511 fd = epoll_create1 (EPOLL_CLOEXEC);
512#else /* ! USE_EPOLL_CREATE1 */
513 fd = epoll_create (MAX_EVENTS);
514#endif /* ! USE_EPOLL_CREATE1 */
515 if (MHD_INVALID_SOCKET == fd)
516 {
517#ifdef HAVE_MESSAGES
518 MHD_DLOG (daemon,
519 MHD_SC_EPOLL_CTL_CREATE_FAILED,
520 _("Call to epoll_create1 failed: %s\n"),
521 MHD_socket_last_strerr_ ());
522#endif
523 return MHD_INVALID_SOCKET;
524 }
525#if !defined(USE_EPOLL_CREATE1)
526 if (! MHD_socket_noninheritable_ (fd))
527 {
528#ifdef HAVE_MESSAGES
529 MHD_DLOG (daemon,
530 MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED,
531 _("Failed to set noninheritable mode on epoll FD.\n"));
532#endif
533 }
534#endif /* ! USE_EPOLL_CREATE1 */
535 return fd;
536}
537
538
519/** 539/**
520 * Setup epoll() FD for the daemon and initialize it to listen 540 * Setup epoll() FD for the daemon and initialize it to listen
521 * on the listen FD. 541 * on the listen FD.
@@ -536,14 +556,14 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
536 if (-1 == daemon->epoll_fd) 556 if (-1 == daemon->epoll_fd)
537 return MHD_NO; 557 return MHD_NO;
538#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 558#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
539 if (0 != (MHD_ALLOW_UPGRADE & daemon->options)) 559 if (! daemon->disallow_upgrade)
540 { 560 {
541 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); 561 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
542 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) 562 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
543 return MHD_NO; 563 return MHD_NO;
544 } 564 }
545#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 565#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
546 if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) || 566 if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_socket)) ||
547 (daemon->was_quiesced) ) 567 (daemon->was_quiesced) )
548 return MHD_YES; /* non-listening daemon */ 568 return MHD_YES; /* non-listening daemon */
549 event.events = EPOLLIN; 569 event.events = EPOLLIN;
@@ -555,6 +575,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
555 { 575 {
556#ifdef HAVE_MESSAGES 576#ifdef HAVE_MESSAGES
557 MHD_DLOG (daemon, 577 MHD_DLOG (daemon,
578 MHD_SC_EPOLL_CTL_ADD_FAILED,
558 _("Call to epoll_ctl failed: %s\n"), 579 _("Call to epoll_ctl failed: %s\n"),
559 MHD_socket_last_strerr_ ()); 580 MHD_socket_last_strerr_ ());
560#endif 581#endif
@@ -564,7 +585,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
564 if (MHD_ITC_IS_VALID_(daemon->itc)) 585 if (MHD_ITC_IS_VALID_(daemon->itc))
565 { 586 {
566 event.events = EPOLLIN; 587 event.events = EPOLLIN;
567 event.data.ptr = (void *) epoll_itc_marker; 588 event.data.ptr = (void *) daemon->epoll_itc_marker;
568 if (0 != epoll_ctl (daemon->epoll_fd, 589 if (0 != epoll_ctl (daemon->epoll_fd,
569 EPOLL_CTL_ADD, 590 EPOLL_CTL_ADD,
570 MHD_itc_r_fd_ (daemon->itc), 591 MHD_itc_r_fd_ (daemon->itc),
@@ -572,6 +593,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
572 { 593 {
573#ifdef HAVE_MESSAGES 594#ifdef HAVE_MESSAGES
574 MHD_DLOG (daemon, 595 MHD_DLOG (daemon,
596 MHD_SC_EPOLL_CTL_ADD_FAILED,
575 _("Call to epoll_ctl failed: %s\n"), 597 _("Call to epoll_ctl failed: %s\n"),
576 MHD_socket_last_strerr_ ()); 598 MHD_socket_last_strerr_ ());
577#endif 599#endif
@@ -647,7 +669,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
647 / daemon->threading_model; 669 / daemon->threading_model;
648 unsigned int leftover_conns = daemon->global_connection_limit 670 unsigned int leftover_conns = daemon->global_connection_limit
649 % daemon->threading_model; 671 % daemon->threading_model;
650 unsigned int i; 672 int i;
651 enum MHD_StatusCode sc; 673 enum MHD_StatusCode sc;
652 674
653 /* Allocate memory for pooled objects */ 675 /* Allocate memory for pooled objects */
@@ -675,7 +697,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
675 * Thread indexes in [0, leftover_conns) each get one of the 697 * Thread indexes in [0, leftover_conns) each get one of the
676 * leftover connections. */ 698 * leftover connections. */
677 d->global_connection_limit = conns_per_thread; 699 d->global_connection_limit = conns_per_thread;
678 if (i < leftover_conns) 700 if (((unsigned int) i) < leftover_conns)
679 ++d->global_connection_limit; 701 ++d->global_connection_limit;
680 702
681 if (! daemon->disable_itc) 703 if (! daemon->disable_itc)
@@ -733,7 +755,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
733 /* Spawn the worker thread */ 755 /* Spawn the worker thread */
734 if (! MHD_create_named_thread_ (&d->pid, 756 if (! MHD_create_named_thread_ (&d->pid,
735 "MHD-worker", 757 "MHD-worker",
736 daemon->thread_stack_size, 758 daemon->thread_stack_limit_b,
737 &MHD_polling_thread, 759 &MHD_polling_thread,
738 d)) 760 d))
739 { 761 {
@@ -909,9 +931,9 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
909 (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model) 931 (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model)
910 ? "MHD-listen" 932 ? "MHD-listen"
911 : "MHD-single", 933 : "MHD-single",
912 daemon->thread_stack_size, 934 daemon->thread_stack_limit_b,
913 &MHD_polling_thread, 935 &MHD_polling_thread,
914 daemon) ) 936 daemon) ) )
915 { 937 {
916#ifdef HAVE_MESSAGES 938#ifdef HAVE_MESSAGES
917 MHD_DLOG (daemon, 939 MHD_DLOG (daemon,
@@ -928,7 +950,10 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
928 (MHD_INVALID_SOCKET != daemon->listen_socket) && 950 (MHD_INVALID_SOCKET != daemon->listen_socket) &&
929 (MHD_SC_OK != (sc = setup_thread_pool (daemon))) ) 951 (MHD_SC_OK != (sc = setup_thread_pool (daemon))) )
930 return sc; 952 return sc;
931 953
954 /* make sure we know our listen port (if any) */
955 get_listen_port_number (daemon);
956
932 return MHD_SC_OK; 957 return MHD_SC_OK;
933} 958}
934 959