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.c427
1 files changed, 310 insertions, 117 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 0b7902e7..b55b7feb 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -6181,7 +6181,22 @@ struct MHD_InterimParams_
6181 * Application-provided listen socket. 6181 * Application-provided listen socket.
6182 */ 6182 */
6183 MHD_socket listen_fd; 6183 MHD_socket listen_fd;
6184 6184 /**
6185 * Set to 'true' if @a server_addr is set by application.
6186 */
6187 bool pserver_addr_set;
6188 /**
6189 * Application-provided struct sockaddr to bind server to.
6190 */
6191 const struct sockaddr *pserver_addr;
6192 /**
6193 * Set to 'true' if @a server_addr_len is set by application.
6194 */
6195 bool server_addr_len_set;
6196 /**
6197 * Applicaiton-provided the size of the memory pointed by @a server_addr.
6198 */
6199 socklen_t server_addr_len;
6185}; 6200};
6186 6201
6187/** 6202/**
@@ -6208,7 +6223,6 @@ typedef void
6208 */ 6223 */
6209static enum MHD_Result 6224static enum MHD_Result
6210parse_options_va (struct MHD_Daemon *daemon, 6225parse_options_va (struct MHD_Daemon *daemon,
6211 const struct sockaddr **servaddr,
6212 struct MHD_InterimParams_ *params, 6226 struct MHD_InterimParams_ *params,
6213 va_list ap); 6227 va_list ap);
6214 6228
@@ -6224,7 +6238,6 @@ parse_options_va (struct MHD_Daemon *daemon,
6224 */ 6238 */
6225static enum MHD_Result 6239static enum MHD_Result
6226parse_options (struct MHD_Daemon *daemon, 6240parse_options (struct MHD_Daemon *daemon,
6227 const struct sockaddr **servaddr,
6228 struct MHD_InterimParams_ *params, 6241 struct MHD_InterimParams_ *params,
6229 ...) 6242 ...)
6230{ 6243{
@@ -6233,7 +6246,6 @@ parse_options (struct MHD_Daemon *daemon,
6233 6246
6234 va_start (ap, params); 6247 va_start (ap, params);
6235 ret = parse_options_va (daemon, 6248 ret = parse_options_va (daemon,
6236 servaddr,
6237 params, 6249 params,
6238 ap); 6250 ap);
6239 va_end (ap); 6251 va_end (ap);
@@ -6507,15 +6519,13 @@ daemon_tls_priorities_init_append (struct MHD_Daemon *daemon, const char *prio)
6507/** 6519/**
6508 * Parse a list of options given as varargs. 6520 * Parse a list of options given as varargs.
6509 * 6521 *
6510 * @param daemon the daemon to initialize 6522 * @param[in,out] daemon the daemon to initialize
6511 * @param servaddr where to store the server's listen address 6523 * @param[out] params the interim parameters to be assigned to
6512 * @param params the interim parameters to be assigned to
6513 * @param ap the options 6524 * @param ap the options
6514 * @return #MHD_YES on success, #MHD_NO on error 6525 * @return #MHD_YES on success, #MHD_NO on error
6515 */ 6526 */
6516static enum MHD_Result 6527static enum MHD_Result
6517parse_options_va (struct MHD_Daemon *daemon, 6528parse_options_va (struct MHD_Daemon *daemon,
6518 const struct sockaddr **servaddr,
6519 struct MHD_InterimParams_ *params, 6529 struct MHD_InterimParams_ *params,
6520 va_list ap) 6530 va_list ap)
6521{ 6531{
@@ -6618,9 +6628,19 @@ parse_options_va (struct MHD_Daemon *daemon,
6618 daemon->per_ip_connection_limit = va_arg (ap, 6628 daemon->per_ip_connection_limit = va_arg (ap,
6619 unsigned int); 6629 unsigned int);
6620 break; 6630 break;
6631 case MHD_OPTION_SOCK_ADDR_LEN:
6632 params->server_addr_len = va_arg (ap,
6633 socklen_t);
6634 params->server_addr_len_set = true;
6635 params->pserver_addr = va_arg (ap,
6636 const struct sockaddr *);
6637 params->pserver_addr_set = true;
6638 break;
6621 case MHD_OPTION_SOCK_ADDR: 6639 case MHD_OPTION_SOCK_ADDR:
6622 *servaddr = va_arg (ap, 6640 params->server_addr_len_set = false;
6623 const struct sockaddr *); 6641 params->pserver_addr = va_arg (ap,
6642 const struct sockaddr *);
6643 params->pserver_addr_set = true;
6624 break; 6644 break;
6625 case MHD_OPTION_URI_LOG_CALLBACK: 6645 case MHD_OPTION_URI_LOG_CALLBACK:
6626 daemon->uri_log_callback = va_arg (ap, 6646 daemon->uri_log_callback = va_arg (ap,
@@ -7006,7 +7026,6 @@ parse_options_va (struct MHD_Daemon *daemon,
7006 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: 7026 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
7007 case MHD_OPTION_THREAD_STACK_SIZE: 7027 case MHD_OPTION_THREAD_STACK_SIZE:
7008 if (MHD_NO == parse_options (daemon, 7028 if (MHD_NO == parse_options (daemon,
7009 servaddr,
7010 params, 7029 params,
7011 opt, 7030 opt,
7012 (size_t) oa[i].value, 7031 (size_t) oa[i].value,
@@ -7025,7 +7044,6 @@ parse_options_va (struct MHD_Daemon *daemon,
7025 case MHD_OPTION_SERVER_INSANITY: 7044 case MHD_OPTION_SERVER_INSANITY:
7026 case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE: 7045 case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE:
7027 if (MHD_NO == parse_options (daemon, 7046 if (MHD_NO == parse_options (daemon,
7028 servaddr,
7029 params, 7047 params,
7030 opt, 7048 opt,
7031 (unsigned int) oa[i].value, 7049 (unsigned int) oa[i].value,
@@ -7036,7 +7054,6 @@ parse_options_va (struct MHD_Daemon *daemon,
7036 case MHD_OPTION_HTTPS_CRED_TYPE: 7054 case MHD_OPTION_HTTPS_CRED_TYPE:
7037#ifdef HTTPS_SUPPORT 7055#ifdef HTTPS_SUPPORT
7038 if (MHD_NO == parse_options (daemon, 7056 if (MHD_NO == parse_options (daemon,
7039 servaddr,
7040 params, 7057 params,
7041 opt, 7058 opt,
7042 (gnutls_credentials_type_t) oa[i].value, 7059 (gnutls_credentials_type_t) oa[i].value,
@@ -7047,7 +7064,6 @@ parse_options_va (struct MHD_Daemon *daemon,
7047 /* all options taking 'MHD_socket' */ 7064 /* all options taking 'MHD_socket' */
7048 case MHD_OPTION_LISTEN_SOCKET: 7065 case MHD_OPTION_LISTEN_SOCKET:
7049 if (MHD_NO == parse_options (daemon, 7066 if (MHD_NO == parse_options (daemon,
7050 servaddr,
7051 params, 7067 params,
7052 opt, 7068 opt,
7053 (MHD_socket) oa[i].value, 7069 (MHD_socket) oa[i].value,
@@ -7061,7 +7077,6 @@ parse_options_va (struct MHD_Daemon *daemon,
7061 case MHD_OPTION_TLS_NO_ALPN: 7077 case MHD_OPTION_TLS_NO_ALPN:
7062 case MHD_OPTION_APP_FD_SETSIZE: 7078 case MHD_OPTION_APP_FD_SETSIZE:
7063 if (MHD_NO == parse_options (daemon, 7079 if (MHD_NO == parse_options (daemon,
7064 servaddr,
7065 params, 7080 params,
7066 opt, 7081 opt,
7067 (int) oa[i].value, 7082 (int) oa[i].value,
@@ -7081,7 +7096,6 @@ parse_options_va (struct MHD_Daemon *daemon,
7081 case MHD_OPTION_HTTPS_CERT_CALLBACK: 7096 case MHD_OPTION_HTTPS_CERT_CALLBACK:
7082 case MHD_OPTION_HTTPS_CERT_CALLBACK2: 7097 case MHD_OPTION_HTTPS_CERT_CALLBACK2:
7083 if (MHD_NO == parse_options (daemon, 7098 if (MHD_NO == parse_options (daemon,
7084 servaddr,
7085 params, 7099 params,
7086 opt, 7100 opt,
7087 oa[i].ptr_value, 7101 oa[i].ptr_value,
@@ -7096,7 +7110,6 @@ parse_options_va (struct MHD_Daemon *daemon,
7096 case MHD_OPTION_UNESCAPE_CALLBACK: 7110 case MHD_OPTION_UNESCAPE_CALLBACK:
7097 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: 7111 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
7098 if (MHD_NO == parse_options (daemon, 7112 if (MHD_NO == parse_options (daemon,
7099 servaddr,
7100 params, 7113 params,
7101 opt, 7114 opt,
7102 (void *) oa[i].value, 7115 (void *) oa[i].value,
@@ -7108,7 +7121,6 @@ parse_options_va (struct MHD_Daemon *daemon,
7108 case MHD_OPTION_DIGEST_AUTH_RANDOM: 7121 case MHD_OPTION_DIGEST_AUTH_RANDOM:
7109 case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY: 7122 case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY:
7110 if (MHD_NO == parse_options (daemon, 7123 if (MHD_NO == parse_options (daemon,
7111 servaddr,
7112 params, 7124 params,
7113 opt, 7125 opt,
7114 (size_t) oa[i].value, 7126 (size_t) oa[i].value,
@@ -7116,6 +7128,16 @@ parse_options_va (struct MHD_Daemon *daemon,
7116 MHD_OPTION_END)) 7128 MHD_OPTION_END))
7117 return MHD_NO; 7129 return MHD_NO;
7118 break; 7130 break;
7131 /* options taking socklen_t-number followed by pointer */
7132 case MHD_OPTION_SOCK_ADDR_LEN:
7133 if (MHD_NO == parse_options (daemon,
7134 params,
7135 opt,
7136 (socklen_t) oa[i].value,
7137 oa[i].ptr_value,
7138 MHD_OPTION_END))
7139 return MHD_NO;
7140 break;
7119 case MHD_OPTION_END: /* Not possible */ 7141 case MHD_OPTION_END: /* Not possible */
7120 default: 7142 default:
7121 return MHD_NO; 7143 return MHD_NO;
@@ -7342,13 +7364,19 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
7342 7364
7343/** 7365/**
7344 * Apply interim parameters 7366 * Apply interim parameters
7345 * @param d the daemon to use 7367 * @param[in,out] d the daemon to use
7346 * @param params the interim parameters to process 7368 * @param[out] ppsockaddr the pointer to store the pointer to 'struct sockaddr'
7369 * if provided by application
7370 * @param[out] psockaddr_len the size memory area pointed by 'struct sockaddr'
7371 * if provided by application
7372 * @param[in] params the interim parameters to process
7347 * @return true in case of success, 7373 * @return true in case of success,
7348 * false in case of critical error (the daemon must be closed). 7374 * false in case of critical error (the daemon must be closed).
7349 */ 7375 */
7350static bool 7376static bool
7351process_interim_params (struct MHD_Daemon *d, 7377process_interim_params (struct MHD_Daemon *d,
7378 const struct sockaddr **ppsockaddr,
7379 socklen_t *psockaddr_len,
7352 struct MHD_InterimParams_ *params) 7380 struct MHD_InterimParams_ *params)
7353{ 7381{
7354 if (params->fdset_size_set) 7382 if (params->fdset_size_set)
@@ -7453,6 +7481,51 @@ process_interim_params (struct MHD_Daemon *d,
7453#endif /* MHD_USE_GETSOCKNAME */ 7481#endif /* MHD_USE_GETSOCKNAME */
7454 } 7482 }
7455 } 7483 }
7484
7485 mhd_assert (! params->server_addr_len_set || params->pserver_addr_set);
7486 if (params->pserver_addr_set)
7487 {
7488 if (NULL == params->pserver_addr)
7489 {
7490 /* The size must be zero if set */
7491 if (params->server_addr_len_set && (0 != params->server_addr_len))
7492 return false;
7493 /* Ignore parameter if it is NULL */
7494 }
7495 else if (MHD_INVALID_SOCKET != d->listen_fd)
7496 {
7497#ifdef HAVE_MESSAGES
7498 MHD_DLOG (d,
7499 _ ("MHD_OPTION_LISTEN_SOCKET cannot be used together with " \
7500 "MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR.\n"));
7501#endif /* HAVE_MESSAGES */
7502 return false;
7503 }
7504 else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET))
7505 {
7506#ifdef HAVE_MESSAGES
7507 MHD_DLOG (d,
7508 _ ("MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR " \
7509 "specified for daemon with MHD_USE_NO_LISTEN_SOCKET " \
7510 "flag set.\n"));
7511#endif /* HAVE_MESSAGES */
7512 (void) MHD_socket_close_ (params->listen_fd);
7513 return false;
7514 }
7515 else
7516 {
7517 *ppsockaddr = params->pserver_addr;
7518 if (params->server_addr_len_set)
7519 {
7520 /* The size must be non-zero if set */
7521 if (0 == params->server_addr_len)
7522 return false;
7523 *psockaddr_len = params->server_addr_len;
7524 }
7525 else
7526 *psockaddr_len = 0;
7527 }
7528 }
7456 return true; 7529 return true;
7457} 7530}
7458 7531
@@ -7490,11 +7563,7 @@ MHD_start_daemon_va (unsigned int flags,
7490 const MHD_SCKT_OPT_BOOL_ on = 1; 7563 const MHD_SCKT_OPT_BOOL_ on = 1;
7491 struct MHD_Daemon *daemon; 7564 struct MHD_Daemon *daemon;
7492 MHD_socket listen_fd; 7565 MHD_socket listen_fd;
7493 struct sockaddr_in servaddr4; 7566 const struct sockaddr *pservaddr = NULL;
7494#ifdef HAVE_INET6
7495 struct sockaddr_in6 servaddr6;
7496#endif
7497 const struct sockaddr *servaddr = NULL;
7498 socklen_t addrlen; 7567 socklen_t addrlen;
7499#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7568#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7500 unsigned int i; 7569 unsigned int i;
@@ -7666,9 +7735,12 @@ MHD_start_daemon_va (unsigned int flags,
7666 interim_params->fdset_size = 0; 7735 interim_params->fdset_size = 0;
7667 interim_params->listen_fd_set = false; 7736 interim_params->listen_fd_set = false;
7668 interim_params->listen_fd = MHD_INVALID_SOCKET; 7737 interim_params->listen_fd = MHD_INVALID_SOCKET;
7738 interim_params->pserver_addr_set = false;
7739 interim_params->pserver_addr = NULL;
7740 interim_params->server_addr_len_set = false;
7741 interim_params->server_addr_len = 0;
7669 7742
7670 if (MHD_NO == parse_options_va (daemon, 7743 if (MHD_NO == parse_options_va (daemon,
7671 &servaddr,
7672 interim_params, 7744 interim_params,
7673 ap)) 7745 ap))
7674 { 7746 {
@@ -7681,7 +7753,10 @@ MHD_start_daemon_va (unsigned int flags,
7681 free (daemon); 7753 free (daemon);
7682 return NULL; 7754 return NULL;
7683 } 7755 }
7684 if (! process_interim_params (daemon, interim_params)) 7756 if (! process_interim_params (daemon,
7757 &pservaddr,
7758 &addrlen,
7759 interim_params))
7685 { 7760 {
7686 free (interim_params); 7761 free (interim_params);
7687 free (daemon); 7762 free (daemon);
@@ -7853,19 +7928,216 @@ MHD_start_daemon_va (unsigned int flags,
7853 goto free_and_fail; 7928 goto free_and_fail;
7854 } 7929 }
7855#endif 7930#endif
7931
7856 if ( (MHD_INVALID_SOCKET == daemon->listen_fd) && 7932 if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
7857 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) 7933 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
7858 { 7934 {
7859 /* try to open listen socket */ 7935 /* try to open listen socket */
7860 int domain; 7936 struct sockaddr_in servaddr4;
7861
7862#ifdef HAVE_INET6 7937#ifdef HAVE_INET6
7863 domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET; 7938 struct sockaddr_in6 servaddr6;
7939 const bool use_ipv6 = (0 != (*pflags & MHD_USE_IPv6));
7864#else /* ! HAVE_INET6 */ 7940#else /* ! HAVE_INET6 */
7865 if (*pflags & MHD_USE_IPv6) 7941 const bool use_ipv6 = false;
7866 goto free_and_fail;
7867 domain = PF_INET;
7868#endif /* ! HAVE_INET6 */ 7942#endif /* ! HAVE_INET6 */
7943 int domain;
7944
7945 if (NULL != pservaddr)
7946 {
7947#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
7948 const socklen_t sa_len = pservaddr->sa_len;
7949#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
7950#ifdef HAVE_INET6
7951 if (use_ipv6 && (AF_INET6 != pservaddr->sa_family))
7952 {
7953#ifdef HAVE_MESSAGES
7954 MHD_DLOG (daemon,
7955 _ ("MHD_USE_IPv6 is enabled, but 'struct sockaddr *' " \
7956 "specified for MHD_OPTION_SOCK_ADDR_LEN or " \
7957 "MHD_OPTION_SOCK_ADDR is not IPv6 address.\n"));
7958#endif /* HAVE_MESSAGES */
7959 goto free_and_fail;
7960 }
7961#endif /* HAVE_INET6 */
7962 switch (pservaddr->sa_family)
7963 {
7964 case AF_INET:
7965 if (1)
7966 {
7967 struct sockaddr_in sa4;
7968 uint16_t sa4_port;
7969 if ((0 != addrlen)
7970 && (((socklen_t) sizeof(sa4)) > addrlen))
7971 {
7972#ifdef HAVE_MESSAGES
7973 MHD_DLOG (daemon,
7974 _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \
7975 "option is wrong.\n"));
7976#endif /* HAVE_MESSAGES */
7977 goto free_and_fail;
7978 }
7979#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
7980 if (0 != sa_len)
7981 {
7982 if (((socklen_t) sizeof(sa4)) > sa_len)
7983 {
7984#ifdef HAVE_MESSAGES
7985 MHD_DLOG (daemon,
7986 _ ("The value of 'struct sockaddr.sa_len' provided " \
7987 "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \
7988 "and does not match 'sa_family' value of the " \
7989 "same structure.\n"));
7990#endif /* HAVE_MESSAGES */
7991 goto free_and_fail;
7992 }
7993 if ((0 == addrlen) || (sa_len < addrlen))
7994 addrlen = sa_len; /* Use smaller value for safety */
7995 }
7996#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
7997 if (0 == addrlen)
7998 addrlen = sizeof(sa4);
7999 memcpy (&sa4, pservaddr, sizeof(sa4)); /* Required due to stronger alignment */
8000 sa4_port = (uint16_t) ntohs (sa4.sin_port);
8001#ifndef MHD_USE_GETSOCKNAME
8002 if (0 != sa4_port)
8003#endif /* ! MHD_USE_GETSOCKNAME */
8004 daemon->port = sa4_port;
8005 domain = PF_INET;
8006 }
8007 break;
8008#ifdef HAVE_INET6
8009 case AF_INET6:
8010 if (1)
8011 {
8012 struct sockaddr_in6 sa6;
8013 uint16_t sa6_port;
8014 if ((0 != addrlen)
8015 && (((socklen_t) sizeof(sa6)) > addrlen))
8016 {
8017#ifdef HAVE_MESSAGES
8018 MHD_DLOG (daemon,
8019 _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \
8020 "option is wrong.\n"));
8021#endif /* HAVE_MESSAGES */
8022 goto free_and_fail;
8023 }
8024#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
8025 if (0 != sa_len)
8026 {
8027 if (((socklen_t) sizeof(sa6)) > sa_len)
8028 {
8029#ifdef HAVE_MESSAGES
8030 MHD_DLOG (daemon,
8031 _ ("The value of 'struct sockaddr.sa_len' provided " \
8032 "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \
8033 "and does not match 'sa_family' value of the " \
8034 "same structure.\n"));
8035#endif /* HAVE_MESSAGES */
8036 goto free_and_fail;
8037 }
8038 if ((0 == addrlen) || (sa_len < addrlen))
8039 addrlen = sa_len; /* Use smaller value for safety */
8040 }
8041#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
8042 if (0 == addrlen)
8043 addrlen = sizeof(sa6);
8044 memcpy (&sa6, pservaddr, sizeof(sa6)); /* Required due to stronger alignment */
8045 sa6_port = (uint16_t) ntohs (sa6.sin6_port);
8046#ifndef MHD_USE_GETSOCKNAME
8047 if (0 != sa6_port)
8048#endif /* ! MHD_USE_GETSOCKNAME */
8049 daemon->port = sa6_port;
8050 domain = PF_INET6;
8051 *pflags |= ((enum MHD_FLAG) MHD_USE_IPv6);
8052 }
8053 break;
8054#endif /* HAVE_INET6 */
8055#ifdef AF_UNIX
8056 case AF_UNIX:
8057#endif /* AF_UNIX */
8058 default:
8059#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
8060 if (0 == addrlen)
8061 addrlen = sa_len;
8062 else if ((0 != sa_len) && (sa_len < addrlen))
8063 addrlen = sa_len; /* Use smaller value for safety */
8064#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
8065 if (0 >= addrlen)
8066 {
8067#ifdef HAVE_MESSAGES
8068 MHD_DLOG (daemon,
8069 _ ("The 'sa_family' of the 'struct sockaddr' provided " \
8070 "via MHD_OPTION_SOCK_ADDR option is not supported.\n"));
8071#endif /* HAVE_MESSAGES */
8072 goto free_and_fail;
8073 }
8074#ifdef AF_UNIX
8075 if (AF_UNIX == pservaddr->sa_family)
8076 {
8077 daemon->port = 0; /* special value for UNIX domain sockets */
8078 daemon->listen_is_unix = _MHD_YES;
8079#ifdef PF_UNIX
8080 domain = PF_UNIX;
8081#else /* ! PF_UNIX */
8082 domain = AF_UNIX;
8083#endif /* ! PF_UNIX */
8084 domain = PF_UNIX;
8085 }
8086 else /* combined with the next 'if' */
8087#endif /* AF_UNIX */
8088 if (1)
8089 {
8090 daemon->port = 0; /* ugh */
8091 daemon->listen_is_unix = _MHD_UNKNOWN;
8092 /* Assumed the same values for AF_* and PF_* */
8093 domain = pservaddr->sa_family;
8094 }
8095 break;
8096 }
8097 }
8098 else
8099 {
8100 if (! use_ipv6)
8101 {
8102 memset (&servaddr4,
8103 0,
8104 sizeof (struct sockaddr_in));
8105 servaddr4.sin_family = AF_INET;
8106 servaddr4.sin_port = htons (port);
8107 if (0 != INADDR_ANY)
8108 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
8109#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
8110 servaddr4.sin_len = sizeof (struct sockaddr_in);
8111#endif
8112 pservaddr = (struct sockaddr *) &servaddr4;
8113 addrlen = (socklen_t) sizeof(servaddr4);
8114 daemon->listen_is_unix = _MHD_NO;
8115 domain = PF_INET;
8116 }
8117#ifdef HAVE_INET6
8118 else
8119 {
8120#ifdef IN6ADDR_ANY_INIT
8121 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
8122#endif
8123 memset (&servaddr6,
8124 0,
8125 sizeof (struct sockaddr_in6));
8126 servaddr6.sin6_family = AF_INET6;
8127 servaddr6.sin6_port = htons (port);
8128#ifdef IN6ADDR_ANY_INIT
8129 servaddr6.sin6_addr = static_in6any;
8130#endif
8131#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
8132 servaddr6.sin6_len = sizeof (struct sockaddr_in6);
8133#endif
8134 pservaddr = (struct sockaddr *) &servaddr6;
8135 addrlen = (socklen_t) sizeof (servaddr6);
8136 daemon->listen_is_unix = _MHD_NO;
8137 domain = PF_INET6;
8138 }
8139#endif /* HAVE_INET6 */
8140 }
7869 8141
7870 listen_fd = MHD_socket_create_listen_ (domain); 8142 listen_fd = MHD_socket_create_listen_ (domain);
7871 if (MHD_INVALID_SOCKET == listen_fd) 8143 if (MHD_INVALID_SOCKET == listen_fd)
@@ -7890,7 +8162,6 @@ MHD_start_daemon_va (unsigned int flags,
7890 MHD_socket_close_chk_ (listen_fd); 8162 MHD_socket_close_chk_ (listen_fd);
7891 goto free_and_fail; 8163 goto free_and_fail;
7892 } 8164 }
7893 daemon->listen_is_unix = _MHD_NO;
7894 8165
7895 /* Apply the socket options according to listening_address_reuse. */ 8166 /* Apply the socket options according to listening_address_reuse. */
7896 if (0 == daemon->listening_address_reuse) 8167 if (0 == daemon->listening_address_reuse)
@@ -8003,87 +8274,8 @@ MHD_start_daemon_va (unsigned int flags,
8003 } 8274 }
8004 8275
8005 /* check for user supplied sockaddr */ 8276 /* check for user supplied sockaddr */
8006#ifdef HAVE_INET6
8007 if (0 != (*pflags & MHD_USE_IPv6))
8008 addrlen = sizeof (struct sockaddr_in6);
8009 else
8010#endif
8011 addrlen = sizeof (struct sockaddr_in);
8012 if (NULL == servaddr)
8013 {
8014#ifdef HAVE_INET6
8015 if (0 != (*pflags & MHD_USE_IPv6))
8016 {
8017#ifdef IN6ADDR_ANY_INIT
8018 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
8019#endif
8020 memset (&servaddr6,
8021 0,
8022 sizeof (struct sockaddr_in6));
8023 servaddr6.sin6_family = AF_INET6;
8024 servaddr6.sin6_port = htons (port);
8025#ifdef IN6ADDR_ANY_INIT
8026 servaddr6.sin6_addr = static_in6any;
8027#endif
8028#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
8029 servaddr6.sin6_len = sizeof (struct sockaddr_in6);
8030#endif
8031 servaddr = (struct sockaddr *) &servaddr6;
8032 }
8033 else
8034#endif
8035 {
8036 memset (&servaddr4,
8037 0,
8038 sizeof (struct sockaddr_in));
8039 servaddr4.sin_family = AF_INET;
8040 servaddr4.sin_port = htons (port);
8041 if (0 != INADDR_ANY)
8042 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
8043#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
8044 servaddr4.sin_len = sizeof (struct sockaddr_in);
8045#endif
8046 servaddr = (struct sockaddr *) &servaddr4;
8047 }
8048 }
8049 else
8050 {
8051#ifdef MHD_USE_GETSOCKNAME
8052 daemon->port = 0; /* Force use of autodetection */
8053#else /* ! MHD_USE_GETSOCKNAME */
8054 switch (servaddr->sa_family)
8055 {
8056 case AF_INET:
8057 {
8058 struct sockaddr_in sa4;
8059 memcpy (&sa4, servaddr, sizeof(sa4)); /* Required due to stronger alignment */
8060 daemon->port = ntohs (sa4.sin_port);
8061 break;
8062 }
8063#ifdef HAVE_INET6
8064 case AF_INET6:
8065 {
8066 struct sockaddr_in6 sa6;
8067 memcpy (&sa6, servaddr, sizeof(sa6)); /* Required due to stronger alignment */
8068 daemon->port = ntohs (sa6.sin6_port);
8069 mhd_assert (0 != (*pflags & MHD_USE_IPv6));
8070 break;
8071 }
8072#endif /* HAVE_INET6 */
8073#ifdef AF_UNIX
8074 case AF_UNIX:
8075 daemon->port = 0; /* special value for UNIX domain sockets */
8076 daemon->listen_is_unix = _MHD_YES;
8077 break;
8078#endif
8079 default:
8080 daemon->port = 0; /* ugh */
8081 daemon->listen_is_unix = _MHD_UNKNOWN;
8082 break;
8083 }
8084#endif /* ! MHD_USE_GETSOCKNAME */
8085 }
8086 daemon->listen_fd = listen_fd; 8277 daemon->listen_fd = listen_fd;
8278
8087 if (0 != (*pflags & MHD_USE_IPv6)) 8279 if (0 != (*pflags & MHD_USE_IPv6))
8088 { 8280 {
8089#ifdef IPPROTO_IPV6 8281#ifdef IPPROTO_IPV6
@@ -8108,7 +8300,7 @@ MHD_start_daemon_va (unsigned int flags,
8108#endif 8300#endif
8109#endif 8301#endif
8110 } 8302 }
8111 if (0 != bind (listen_fd, servaddr, addrlen)) 8303 if (0 != bind (listen_fd, pservaddr, addrlen))
8112 { 8304 {
8113#ifdef HAVE_MESSAGES 8305#ifdef HAVE_MESSAGES
8114 MHD_DLOG (daemon, 8306 MHD_DLOG (daemon,
@@ -8157,7 +8349,8 @@ MHD_start_daemon_va (unsigned int flags,
8157 8349
8158#ifdef MHD_USE_GETSOCKNAME 8350#ifdef MHD_USE_GETSOCKNAME
8159 if ( (0 == daemon->port) && 8351 if ( (0 == daemon->port) &&
8160 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) 8352 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) &&
8353 (_MHD_YES != daemon->listen_is_unix) )
8161 { /* Get port number. */ 8354 { /* Get port number. */
8162 struct sockaddr_storage bindaddr; 8355 struct sockaddr_storage bindaddr;
8163 8356
@@ -8166,7 +8359,7 @@ MHD_start_daemon_va (unsigned int flags,
8166 sizeof (struct sockaddr_storage)); 8359 sizeof (struct sockaddr_storage));
8167 addrlen = sizeof (struct sockaddr_storage); 8360 addrlen = sizeof (struct sockaddr_storage);
8168#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 8361#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
8169 bindaddr.ss_len = addrlen; 8362 bindaddr.ss_len = (socklen_t) addrlen;
8170#endif 8363#endif
8171 if (0 != getsockname (listen_fd, 8364 if (0 != getsockname (listen_fd,
8172 (struct sockaddr *) &bindaddr, 8365 (struct sockaddr *) &bindaddr,