libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

commit e95381af51dc07b16304105fbda15336d6616185
parent 0a3e9e305620fa37e515eb9b2f9f7b75dd3fb99f
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Wed,  4 Jun 2025 02:23:08 +0200

Improved error reporting for the listen socket creation

Diffstat:
Msrc/mhd2/daemon_start.c | 121++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 98 insertions(+), 23 deletions(-)

diff --git a/src/mhd2/daemon_start.c b/src/mhd2/daemon_start.c @@ -332,14 +332,20 @@ enum mhd_CreateSktType * @param v6_tried true if IPv6 has been tried already * @param force_v6_any_dual true if IPv6 is forced with dual stack either * enabled or not + * @param prev_bnd_lstn_err if this function was already tried with another and + * failed to bind or to start listening then + * this parameter must be set to respecting status + * code, otherwise this parameter must be #MHD_SC_OK * @return #MHD_SC_OK on success, - * the error code otherwise + * the error code otherwise (no error printed to log if result is + * #MHD_SC_LISTEN_SOCKET_BIND_FAILED or #MHD_SC_LISTEN_FAILURE) */ static enum MHD_StatusCode -create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, - struct DaemonOptions *restrict s, - bool v6_tried, - bool force_v6_any_dual) +create_bind_listen_stream_socket_inner (struct MHD_Daemon *restrict d, + struct DaemonOptions *restrict s, + bool v6_tried, + bool force_v6_any_dual, + enum MHD_StatusCode prev_bnd_lstn_err) { MHD_Socket sk; enum mhd_CreateSktType sk_type; @@ -695,17 +701,30 @@ create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, { #ifdef HAVE_INET6 if (mhd_SKT_IP_V4_WITH_FALLBACK == sk_type) - return create_bind_listen_stream_socket (d, s, v6_tried, true); + return create_bind_listen_stream_socket_inner (d, + s, + v6_tried, + true, + prev_bnd_lstn_err); if (mhd_SKT_IP_V4_WITH_V6_OPT == sk_type) - return create_bind_listen_stream_socket (d, s, true, false); + return create_bind_listen_stream_socket_inner (d, + s, + true, + false, + prev_bnd_lstn_err); #endif /* HAVE_INET6 */ + if (MHD_SC_OK != prev_bnd_lstn_err) + return prev_bnd_lstn_err; + if (mhd_SCKT_LERR_IS_AF ()) + { mhd_LOG_MSG (d, MHD_SC_AF_NOT_AVAILABLE, \ "The requested socket address family is rejected " \ "by the OS"); - else - mhd_LOG_MSG (d, MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET, \ + return MHD_SC_AF_NOT_AVAILABLE; + } + mhd_LOG_MSG (d, MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET, \ "Failed to open listen socket"); return MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET; @@ -791,7 +810,11 @@ create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, if (mhd_SKT_IP_V4_WITH_V6_OPT == sk_type) { (void) mhd_socket_close (sk); - return create_bind_listen_stream_socket (d, s, true, false); + return create_bind_listen_stream_socket_inner (d, + s, + true, + false, + prev_bnd_lstn_err); } if (! state_unknown) { @@ -802,7 +825,9 @@ create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, d, MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED, \ "Failed to disable IP dual-stack configuration " \ "for the listen socket"); - ret = MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED; + ret = (MHD_SC_OK == prev_bnd_lstn_err) ? + MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED : + prev_bnd_lstn_err; break; } else if (mhd_SKT_UNKNOWN != sk_type) @@ -813,7 +838,9 @@ create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, "for the listen socket"); if (mhd_SKT_IP_DUAL_REQUIRED == sk_type) { - ret = MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED; + ret = (MHD_SC_OK == prev_bnd_lstn_err) ? + MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED : + prev_bnd_lstn_err; break; } } @@ -950,21 +977,28 @@ create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, mhd_assert (0 != use_sa_size); if (0 != bind (sk, p_use_sa, use_sa_size)) { + ret = (MHD_SC_OK == prev_bnd_lstn_err) ? + MHD_SC_LISTEN_SOCKET_BIND_FAILED : prev_bnd_lstn_err; #ifdef HAVE_INET6 if (mhd_SKT_IP_V4_WITH_FALLBACK == sk_type) { (void) mhd_socket_close (sk); - return create_bind_listen_stream_socket (d, s, v6_tried, true); + return create_bind_listen_stream_socket_inner (d, + s, + v6_tried, + true, + ret); } if (mhd_SKT_IP_V4_WITH_V6_OPT == sk_type) { (void) mhd_socket_close (sk); - return create_bind_listen_stream_socket (d, s, true, false); + return create_bind_listen_stream_socket_inner (d, + s, + true, + false, + ret); } #endif /* HAVE_INET6 */ - mhd_LOG_MSG (d, MHD_SC_LISTEN_SOCKET_BIND_FAILED, \ - "Failed to bind the listen socket"); - ret = MHD_SC_LISTEN_SOCKET_BIND_FAILED; break; } @@ -984,21 +1018,27 @@ create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, } if (0 != listen (sk, accept_queue_len)) { + ret = MHD_SC_LISTEN_FAILURE; #ifdef HAVE_INET6 if (mhd_SKT_IP_V4_WITH_FALLBACK == sk_type) { (void) mhd_socket_close (sk); - return create_bind_listen_stream_socket (d, s, v6_tried, true); + return create_bind_listen_stream_socket_inner (d, + s, + v6_tried, + true, + ret); } if (mhd_SKT_IP_V4_WITH_V6_OPT == sk_type) { (void) mhd_socket_close (sk); - return create_bind_listen_stream_socket (d, s, true, false); + return create_bind_listen_stream_socket_inner (d, + s, + true, + false, + ret); } #endif /* HAVE_INET6 */ - mhd_LOG_MSG (d, MHD_SC_LISTEN_FAILURE, \ - "Failed to start listening on the listen socket"); - ret = MHD_SC_LISTEN_FAILURE; break; } } @@ -1056,6 +1096,41 @@ create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, } +/** + * Create socket, bind to the address and start listening on the socket. + * + * The socket is assigned to the daemon as listening FD. + * + * @param d the daemon to use + * @param s the user settings + * @return #MHD_SC_OK on success, + * the error code otherwise (no error printed to log if result is + * #MHD_SC_LISTEN_SOCKET_BIND_FAILED or #MHD_SC_LISTEN_FAILURE) + */ +static enum MHD_StatusCode +create_bind_listen_stream_socket (struct MHD_Daemon *restrict d, + struct DaemonOptions *restrict s) +{ + enum MHD_StatusCode ret; + + ret = create_bind_listen_stream_socket_inner (d, + s, + false, + false, + MHD_SC_OK); +#ifdef MHD_SUPPORT_LOG_FUNCTIONALITY + if (MHD_SC_LISTEN_SOCKET_BIND_FAILED == ret) + mhd_LOG_MSG (d, MHD_SC_LISTEN_SOCKET_BIND_FAILED, \ + "Failed to bind the listen socket"); + else if (MHD_SC_LISTEN_FAILURE == ret) + mhd_LOG_MSG (d, MHD_SC_LISTEN_FAILURE, \ + "Failed to start listening on the listen socket"); +#endif /* MHD_SUPPORT_LOG_FUNCTIONALITY */ + + return ret; +} + + #ifdef MHD_USE_GETSOCKNAME /** * Detect and set the type and port of the listening socket @@ -1471,7 +1546,7 @@ daemon_init_net (struct MHD_Daemon *restrict d, if (MHD_SC_OK == ret) { - ret = create_bind_listen_stream_socket (d, s, false, false); + ret = create_bind_listen_stream_socket (d, s); if (MHD_SC_OK == ret) {