odhcp6c: enable Non-Blocking DHCPv6 Socket
authorNicolas BESNARD <[email protected]>
Tue, 29 Oct 2024 10:06:15 +0000 (10:06 +0000)
committerÁlvaro Fernández Rojas <[email protected]>
Mon, 3 Nov 2025 15:14:48 +0000 (16:14 +0100)
Problem:
    The DHCPv6 socket is currently set to blocking mode, which causes
    the program to pause execution whenever it attempts to read from the
    socket. This can lead to delays and hinder the overall
    responsiveness of the application.

Solution:
    Add the set_nonblocking() function, using fcntl() to set the
    O_NONBLOCK flag, allowing the socket to operate in non-blocking
    mode.

Signed-off-by: Nicolas BESNARD <[email protected]>
Signed-off-by: Paul Donald <[email protected]>
Link: https://github.com/openwrt/odhcp6c/pull/106
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
src/dhcpv6.c

index 42309c7396b28566f858995046987107a1df3ee8..410a2f5ffa625b9870c273682355ddb304ab276f 100644 (file)
@@ -193,6 +193,27 @@ static char *dhcpv6_status_code_to_str(uint16_t code)
        return "Unknown";
 }
 
+static int fd_set_nonblocking(int sockfd)
+{
+       int flags = fcntl(sockfd, F_GETFL, 0);
+       if (flags == -1) {
+               syslog(LOG_ERR,
+                       "Failed to get the dhcpv6 socket flags: fcntl F_GETFL failed (%s)",
+                       strerror(errno));
+               return -1;
+       }
+
+       // Set the socket to non-blocking
+       if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
+               syslog(LOG_ERR,
+                       "Failed to set the dhcpv6 socket to non-blocking: fcntl F_SETFL failed (%s)",
+                       strerror(errno));
+               return -1;
+       }
+
+       return 0;
+}
+
 int init_dhcpv6(const char *ifname, unsigned int options, int sk_prio, int sol_timeout, unsigned int dscp)
 {
        client_options = options;
@@ -211,6 +232,10 @@ int init_dhcpv6(const char *ifname, unsigned int options, int sk_prio, int sol_t
 
        ifindex = ifr.ifr_ifindex;
 
+       // Set the socket to non-blocking mode
+       if (fd_set_nonblocking(sock) < 0)
+               goto failure;
+
        // Create client DUID
        size_t client_id_len;
        odhcp6c_get_state(STATE_CLIENT_ID, &client_id_len);