[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    udhcpc6 kernel listen mode is broken
From:       Danomi Manchego <danomimanchego123 () gmail ! com>
Date:       2022-05-11 1:34:18
Message-ID: CANxTyt555NJ5z=C+Y+y4cYm5rTvhcQ-KM=a2=tZ=8zgtTrAi5Q () mail ! gmail ! com
[Download RAW message or body]

Hello,

On April 1, I sent "udhcpc6 renew message copy/paste error" email
about udhcpc6 sends the wrong message ID for Renew message due to
copy/paste error from IPv4 dhcpc.c.  (Was DHCPREQUEST, should be
D6_MSG_RENEW.)  After fixing that, I found that the Renew is sent
correctly, and the DHCPv6 server replies, but udhcpc6 fails to get the
reply.  Because there is no reply, the lease does not get extended by
Renew.  I found that the issue is that the udhcp_listen_socket() in
socket.c (used for kernel listen mode in d6_dhcpc.c) is somewhat
hard-coded for IPv4.  I was able to get kernel listen mode to work by
adding a new function like this to socket.c and using it in d6_dhcp.c.
My udhcp6_listen_socket() differs from udhcp_listen_socket() as
follows:

* Use PF_INET6 instead of PF_INET.

* Set IPPROTO_IPV6 / IPV6_V6ONLY socket option rather than broadcast option.

* Use `struct sockaddr_in6` instead of `struct sockaddr_in`.

* Use AF_INET6 instead of AF_INET.

(Maybe SOCK_CLOEXEC should also be set in *both* functions when
calling xsocket since udhcpc/udhcpc6 invoke external udhcpc.script,
but I did not try it.)

My function is pasted below.

int FAST_FUNC udhcp6_listen_socket(/*uint32_t ip,*/ int port, const char *inf)
{
    int fd;
    struct sockaddr_in6 addr;
    char *colon;

    log2("opening listen socket on *:%d %s", port, inf);
    fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);

    setsockopt_reuseaddr(fd);

    if (setsockopt_1(fd, IPPROTO_IPV6, IPV6_V6ONLY) < 0)
        bb_simple_perror_msg_and_die("IPPROTO_IPV6");

    /* SO_BINDTODEVICE doesn't work on ethernet aliases (ethN:M) */
    colon = strrchr(inf, ':');
    if (colon)
        *colon = '\0';

    if (setsockopt_bindtodevice(fd, inf))
        xfunc_die(); /* warning is already printed */

    if (colon)
        *colon = ':';

    memset(&addr, 0, sizeof(addr));
    addr.sin6_family = AF_INET6;
    addr.sin6_port = htons(port);
    /* addr.sin_addr.s_addr = ip; - all-zeros is INADDR_ANY */
    xbind(fd, (struct sockaddr *)&addr, sizeof(addr));

    return fd;
}

Regards,
Danomi -
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic