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:
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)
{