diff options
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r-- | src/daemon/daemon.c | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 54c98f04..39abee6a 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -209,16 +209,20 @@ MHD_handle_connection(void * data) { | |||
209 | static int | 209 | static int |
210 | MHD_accept_connection(struct MHD_Daemon * daemon) { | 210 | MHD_accept_connection(struct MHD_Daemon * daemon) { |
211 | struct MHD_Connection * connection; | 211 | struct MHD_Connection * connection; |
212 | struct sockaddr addr; | 212 | struct sockaddr_in6 addr6; |
213 | struct sockaddr * addr = (struct sockaddr*) &addr6; | ||
213 | socklen_t addrlen; | 214 | socklen_t addrlen; |
214 | int s; | 215 | int s; |
215 | 216 | ||
216 | addrlen = sizeof(struct sockaddr); | 217 | |
217 | memset(&addr, | 218 | if (sizeof(struct sockaddr) > sizeof(struct sockaddr_in6)) |
219 | abort(); /* fatal, serious error */ | ||
220 | addrlen = sizeof(struct sockaddr_in6); | ||
221 | memset(addr, | ||
218 | 0, | 222 | 0, |
219 | sizeof(struct sockaddr)); | 223 | sizeof(struct sockaddr_in6)); |
220 | s = ACCEPT(daemon->socket_fd, | 224 | s = ACCEPT(daemon->socket_fd, |
221 | &addr, | 225 | addr, |
222 | &addrlen); | 226 | &addrlen); |
223 | if ( (s < 0) || | 227 | if ( (s < 0) || |
224 | (addrlen <= 0) ) { | 228 | (addrlen <= 0) ) { |
@@ -228,7 +232,7 @@ MHD_accept_connection(struct MHD_Daemon * daemon) { | |||
228 | return MHD_NO; | 232 | return MHD_NO; |
229 | } | 233 | } |
230 | if (MHD_NO == daemon->apc(daemon->apc_cls, | 234 | if (MHD_NO == daemon->apc(daemon->apc_cls, |
231 | &addr, | 235 | addr, |
232 | addrlen)) { | 236 | addrlen)) { |
233 | CLOSE(s); | 237 | CLOSE(s); |
234 | return MHD_YES; | 238 | return MHD_YES; |
@@ -239,7 +243,7 @@ MHD_accept_connection(struct MHD_Daemon * daemon) { | |||
239 | sizeof(struct MHD_Connection)); | 243 | sizeof(struct MHD_Connection)); |
240 | connection->addr = malloc(addrlen); | 244 | connection->addr = malloc(addrlen); |
241 | memcpy(connection->addr, | 245 | memcpy(connection->addr, |
242 | &addr, | 246 | addr, |
243 | addrlen); | 247 | addrlen); |
244 | connection->addr_len = addrlen; | 248 | connection->addr_len = addrlen; |
245 | connection->socket_fd = s; | 249 | connection->socket_fd = s; |
@@ -463,18 +467,23 @@ MHD_start_daemon(unsigned int options, | |||
463 | MHD_AccessHandlerCallback dh, | 467 | MHD_AccessHandlerCallback dh, |
464 | void * dh_cls, | 468 | void * dh_cls, |
465 | ...) { | 469 | ...) { |
470 | const int on = 1; | ||
466 | struct MHD_Daemon * retVal; | 471 | struct MHD_Daemon * retVal; |
467 | int socket_fd; | 472 | int socket_fd; |
468 | struct sockaddr_in servaddr; | 473 | struct sockaddr_in servaddr4; |
469 | 474 | struct sockaddr_in6 servaddr6; | |
475 | const struct sockaddr * servaddr; | ||
476 | socklen_t addrlen; | ||
477 | |||
470 | if ((options & MHD_USE_SSL) != 0) | 478 | if ((options & MHD_USE_SSL) != 0) |
471 | return NULL; | 479 | return NULL; |
472 | if ((options & MHD_USE_IPv6) != 0) | ||
473 | return NULL; | ||
474 | if ( (port == 0) || | 480 | if ( (port == 0) || |
475 | (dh == NULL) ) | 481 | (dh == NULL) ) |
476 | return NULL; | 482 | return NULL; |
477 | socket_fd = SOCKET(AF_INET, SOCK_STREAM, 0); | 483 | if ((options & MHD_USE_IPv6) != 0) |
484 | socket_fd = SOCKET(PF_INET6, SOCK_STREAM, 0); | ||
485 | else | ||
486 | socket_fd = SOCKET(PF_INET, SOCK_STREAM, 0); | ||
478 | if (socket_fd < 0) { | 487 | if (socket_fd < 0) { |
479 | if ((options & MHD_USE_DEBUG) != 0) | 488 | if ((options & MHD_USE_DEBUG) != 0) |
480 | fprintf(stderr, | 489 | fprintf(stderr, |
@@ -482,15 +491,35 @@ MHD_start_daemon(unsigned int options, | |||
482 | STRERROR(errno)); | 491 | STRERROR(errno)); |
483 | return NULL; | 492 | return NULL; |
484 | } | 493 | } |
485 | /* FIXME: setsockopt: SO_REUSEADDR? */ | 494 | if ( (SETSOCKOPT(socket_fd, |
486 | memset(&servaddr, | 495 | SOL_SOCKET, |
487 | 0, | 496 | SO_REUSEADDR, |
488 | sizeof(struct sockaddr_in)); | 497 | &on, |
489 | servaddr.sin_family = AF_INET; | 498 | sizeof(on)) < 0) && |
490 | servaddr.sin_port = htons(port); | 499 | (options & MHD_USE_DEBUG) != 0) |
500 | fprintf(stderr, | ||
501 | "setsockopt failed: %s\n", | ||
502 | STRERROR(errno)); | ||
503 | if ((options & MHD_USE_IPv6) != 0) { | ||
504 | memset(&servaddr6, | ||
505 | 0, | ||
506 | sizeof(struct sockaddr_in6)); | ||
507 | servaddr6.sin6_family = AF_INET6; | ||
508 | servaddr6.sin6_port = htons(port); | ||
509 | servaddr = (struct sockaddr*) &servaddr6; | ||
510 | addrlen = sizeof(struct sockaddr_in6); | ||
511 | } else { | ||
512 | memset(&servaddr4, | ||
513 | 0, | ||
514 | sizeof(struct sockaddr_in)); | ||
515 | servaddr4.sin_family = AF_INET; | ||
516 | servaddr4.sin_port = htons(port); | ||
517 | servaddr = (struct sockaddr*) &servaddr4; | ||
518 | addrlen = sizeof(struct sockaddr_in); | ||
519 | } | ||
491 | if (BIND(socket_fd, | 520 | if (BIND(socket_fd, |
492 | (struct sockaddr *)&servaddr, | 521 | servaddr, |
493 | sizeof(struct sockaddr_in)) < 0) { | 522 | addrlen) < 0) { |
494 | if ( (options & MHD_USE_DEBUG) != 0) | 523 | if ( (options & MHD_USE_DEBUG) != 0) |
495 | fprintf(stderr, | 524 | fprintf(stderr, |
496 | "Failed to bind to port %u: %s\n", | 525 | "Failed to bind to port %u: %s\n", |