diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-11-27 23:01:39 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-11-27 23:01:39 +0100 |
commit | db6a2374adc1d5feb250b8c31f0649df64e2e920 (patch) | |
tree | 0078ef9172f336f8852a9364c7bc274e78208220 | |
parent | 42dd288259ee016007c78d756e0a76c6071bbca0 (diff) | |
download | libmicrohttpd-db6a2374adc1d5feb250b8c31f0649df64e2e920.tar.gz libmicrohttpd-db6a2374adc1d5feb250b8c31f0649df64e2e920.zip |
fix warning 'Failed to get listen port number due to small buffer' encountered when we try to derive the port of a unix domain socket
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 98 |
2 files changed, 50 insertions, 53 deletions
@@ -1,3 +1,8 @@ | |||
1 | Mon Nov 27 22:58:38 CET 2017 | ||
2 | Tolerate AF_UNIX when trying to determine our binding port | ||
3 | from socket. Use `sockaddr_storage` instead of trying to | ||
4 | guess the sockaddr type before calling getsockname(). -CG | ||
5 | |||
1 | Mon Nov 27 22:24:00 MSK 2017 | 6 | Mon Nov 27 22:24:00 MSK 2017 |
2 | Releasing GNU libmicrohttpd 0.9.57. -EG | 7 | Releasing GNU libmicrohttpd 0.9.57. -EG |
3 | 8 | ||
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index abe40e72..cf27a885 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -5764,74 +5764,66 @@ MHD_start_daemon_va (unsigned int flags, | |||
5764 | if ( (0 == daemon->port) && | 5764 | if ( (0 == daemon->port) && |
5765 | (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) | 5765 | (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) |
5766 | { /* Get port number. */ | 5766 | { /* Get port number. */ |
5767 | struct sockaddr *realaddr; | 5767 | struct sockaddr_storage servaddr; |
5768 | #ifdef MHD_POSIX_SOCKETS | 5768 | |
5769 | socklen_t alloc_len; | 5769 | memset (&servaddr, |
5770 | #endif /* MHD_POSIX_SOCKETS */ | 5770 | 0, |
5771 | #ifdef HAVE_INET6 | 5771 | sizeof (struct sockaddr_storage)); |
5772 | if (0 != (*pflags & MHD_USE_IPv6)) | 5772 | addrlen = sizeof (servaddr); |
5773 | { | 5773 | if (0 != getsockname (listen_fd, |
5774 | memset (&servaddr6, | 5774 | (struct sockaddr *) &servaddr, |
5775 | 0, | 5775 | &addrlen)) |
5776 | sizeof (struct sockaddr_in6)); | 5776 | { |
5777 | servaddr6.sin6_family = AF_INET6; | ||
5778 | #ifdef HAVE_SOCKADDR_IN_SIN_LEN | ||
5779 | servaddr6.sin6_len = sizeof (struct sockaddr_in6); | ||
5780 | #endif /* HAVE_SOCKADDR_IN_SIN_LEN */ | ||
5781 | addrlen = (socklen_t) sizeof (struct sockaddr_in6); | ||
5782 | realaddr = (struct sockaddr *) &servaddr6; | ||
5783 | } | ||
5784 | else | ||
5785 | #else /* ! HAVE_INET6 */ | ||
5786 | if (1) | ||
5787 | #endif /* ! HAVE_INET6 */ | ||
5788 | { | ||
5789 | memset (&servaddr4, | ||
5790 | 0, | ||
5791 | sizeof (struct sockaddr_in)); | ||
5792 | servaddr4.sin_family = AF_INET; | ||
5793 | #ifdef HAVE_SOCKADDR_IN_SIN_LEN | ||
5794 | servaddr4.sin_len = sizeof (struct sockaddr_in); | ||
5795 | #endif /* HAVE_SOCKADDR_IN_SIN_LEN */ | ||
5796 | addrlen = (socklen_t) sizeof (struct sockaddr_in); | ||
5797 | realaddr = (struct sockaddr *) &servaddr4; | ||
5798 | } | ||
5799 | #ifdef MHD_POSIX_SOCKETS | ||
5800 | alloc_len = addrlen; | ||
5801 | #endif /* MHD_POSIX_SOCKETS */ | ||
5802 | if (0 != getsockname (listen_fd, realaddr, &addrlen)) | ||
5803 | { | ||
5804 | #ifdef HAVE_MESSAGES | 5777 | #ifdef HAVE_MESSAGES |
5805 | MHD_DLOG (daemon, | 5778 | MHD_DLOG (daemon, |
5806 | _("Failed to get listen port number: %s\n"), | 5779 | _("Failed to get listen port number: %s\n"), |
5807 | MHD_socket_last_strerr_ ()); | 5780 | MHD_socket_last_strerr_ ()); |
5808 | #endif /* HAVE_MESSAGES */ | 5781 | #endif /* HAVE_MESSAGES */ |
5809 | } | 5782 | } |
5810 | #ifdef MHD_POSIX_SOCKETS | 5783 | #ifdef MHD_POSIX_SOCKETS |
5811 | else if (alloc_len < addrlen) | 5784 | else if (sizeof (servaddr) < addrlen) |
5812 | { | 5785 | { |
5786 | /* should be impossible with `struct sockaddr_storage` */ | ||
5813 | #ifdef HAVE_MESSAGES | 5787 | #ifdef HAVE_MESSAGES |
5814 | MHD_DLOG (daemon, | 5788 | MHD_DLOG (daemon, |
5815 | _("Failed to get listen port number due to small buffer\n")); | 5789 | _("Failed to get listen port number (`struct sockaddr_storage` too small!?)\n")); |
5816 | #endif /* HAVE_MESSAGES */ | 5790 | #endif /* HAVE_MESSAGES */ |
5817 | } | 5791 | } |
5818 | #endif /* MHD_POSIX_SOCKETS */ | 5792 | #endif /* MHD_POSIX_SOCKETS */ |
5819 | else | 5793 | else |
5820 | { | 5794 | { |
5821 | #ifdef HAVE_INET6 | 5795 | switch (servaddr.ss_family) |
5822 | if (0 != (*pflags & MHD_USE_IPv6)) | 5796 | { |
5797 | case AF_INET: | ||
5823 | { | 5798 | { |
5824 | mhd_assert (AF_INET6 == servaddr6.sin6_family); | 5799 | struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr; |
5825 | daemon->port = ntohs(servaddr6.sin6_port); | 5800 | |
5801 | daemon->port = ntohs (s4->sin_port); | ||
5802 | break; | ||
5826 | } | 5803 | } |
5827 | else | 5804 | #ifdef HAVE_INET6 |
5828 | #else /* ! HAVE_INET6 */ | 5805 | case AF_INET6: |
5829 | if (1) | ||
5830 | #endif /* ! HAVE_INET6 */ | ||
5831 | { | 5806 | { |
5832 | mhd_assert (AF_INET == servaddr4.sin_family); | 5807 | struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr; |
5833 | daemon->port = ntohs(servaddr4.sin_port); | 5808 | |
5809 | daemon->port = ntohs(s6->sin6_port); | ||
5810 | mhd_assert (0 != (*pflags & MHD_USE_IPv6)); | ||
5811 | break; | ||
5834 | } | 5812 | } |
5813 | #endif /* HAVE_INET6 */ | ||
5814 | #ifdef AF_UNIX | ||
5815 | case AF_UNIX: | ||
5816 | daemon->port = 0; /* special value for UNIX domain sockets */ | ||
5817 | break; | ||
5818 | #endif | ||
5819 | default: | ||
5820 | #ifdef HAVE_MESSAGES | ||
5821 | MHD_DLOG (daemon, | ||
5822 | _("Unknown address family!\n")); | ||
5823 | #endif | ||
5824 | daemon->port = 0; /* ugh */ | ||
5825 | break; | ||
5826 | } | ||
5835 | } | 5827 | } |
5836 | } | 5828 | } |
5837 | 5829 | ||