]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Rework the recvmsg_realloc function to handle flags.
authorRoy Marples <roy@marples.name>
Fri, 2 Sep 2016 08:09:47 +0000 (08:09 +0000)
committerRoy Marples <roy@marples.name>
Fri, 2 Sep 2016 08:09:47 +0000 (08:09 +0000)
Commit also includes mistakenly added ifam_pid patch for BSD.
It does no harm being here, even though no BSD supports this yet.

common.c
common.h
configure
if-bsd.c
if-linux.c
if-sun.c

index 3c0de44eb1d5e86333b051b9ef82de17cca82a98..9b62a6a5e1357f54dd9b583ff2eb99809a4392a2 100644 (file)
--- a/common.c
+++ b/common.c
@@ -397,21 +397,19 @@ iovec_realloc(struct iovec *iov, size_t size)
 }
 
 ssize_t
-recvmsg_alloc(int fd, struct msghdr *msg)
+recvmsg_realloc(int fd, struct msghdr *msg, int flags)
 {
        ssize_t bytes;
 
-       if (msg->msg_iovlen == 0)
-               msg->msg_iovlen = 1;
-
        for (;;) {
-               msg->msg_flags &= ~MSG_TRUNC;
-               if ((bytes = recvmsg(fd, msg, MSG_PEEK | MSG_TRUNC)) == -1)
+               msg->msg_flags = 0;
+               bytes = recvmsg(fd, msg, flags | MSG_PEEK | MSG_TRUNC);
+               if (bytes == -1)
                        return -1;
                if (!(msg->msg_flags & MSG_TRUNC))
                        break;
 
-               /* Some buggy kernels return the truncated size. */
+               /* Some kernels return the truncated size. */
                if (msg->msg_iov->iov_len == (size_t)bytes) {
                        size_t nl;
 
@@ -425,6 +423,6 @@ recvmsg_alloc(int fd, struct msghdr *msg)
                }
        }
 
-       bytes = recvmsg(fd, msg, 0);
+       bytes = recvmsg(fd, msg, flags);
        return msg->msg_flags & MSG_TRUNC ? -1 : bytes;
 }
index 38924bc3bc40d34d3f7119c3cd7477a1f213d123..da9aea9627b97d2827c14616c4a9b4d0fb2640f1 100644 (file)
--- a/common.h
+++ b/common.h
@@ -197,5 +197,5 @@ char *hwaddr_ntoa(const uint8_t *, size_t, char *, size_t);
 size_t hwaddr_aton(uint8_t *, const char *);
 size_t read_hwaddr_aton(uint8_t **, const char *);
 
-ssize_t recvmsg_alloc(int fd, struct msghdr *msg);
+ssize_t recvmsg_realloc(int, struct msghdr *, int);
 #endif
index 0f22c8694c3755d79be9f74535ccbb3b3e744afe..a6ed2f29f0c7aff7abbf7111862fdd685762229a 100755 (executable)
--- a/configure
+++ b/configure
@@ -506,7 +506,22 @@ EOF
                echo "no"
        fi
        rm -f _IN6_ADDR_GEN_MODE_NONE.c _IN6_ADDR_GEN_MODE_NONE
-
+else
+       printf "Testing for ifam_pid ... "
+       cat <<EOF >_ifam_pid.c
+#include <net/if.h>
+int main(void) {
+       struct ifa_msghdr ifam = { };
+       return (int)ifam.ifam_pid;
+}
+EOF
+       if $XCC _ifam_pid.c -o _ifam_pid 2>&3; then
+               echo "yes"
+               echo "#define HAVE_IFAM_PID" >>$CONFIG_H
+       else
+               echo "no"
+       fi
+       rm -f _ifam_pid.c _ifam_pid
 fi
 
 abort=false
index fbcb517260c2b48fca7efa7e1fa70fcfae3756e2..7bc54e09c303246d9c69bd6f213a2f3658343e64 100644 (file)
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -1312,32 +1312,43 @@ if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm)
            (unsigned int)ifm->ifm_flags, ifp->name);
 }
 
-static void
-if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
+static int
+if_ownmsgpid(struct dhcpcd_ctx *ctx, pid_t pid, int seq)
 {
-       const struct sockaddr *sa;
 
        /* Ignore messages generated by us */
-       if (rtm->rtm_pid == getpid()) {
+       if (getpid() == pid) {
                ctx->options &= ~DHCPCD_RTM_PPID;
-               return;
+               return 1;
        }
 
        /* Ignore messages sent by the parent after forking */
        if ((ctx->options &
            (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) ==
            (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) &&
-           rtm->rtm_pid == ctx->ppid)
+           ctx->ppid == pid)
        {
                /* If this is the last successful message sent,
                 * clear the check flag as it's possible another
                 * process could re-use the same pid and also
-                * manipulate therouting table. */
-               if (rtm->rtm_seq == ctx->pseq)
+                * manipulate the routing table. */
+               if (ctx->pseq == seq)
                        ctx->options &= ~DHCPCD_RTM_PPID;
-               return;
+               return 1;
        }
 
+       /* Not a message we made. */
+       return 0;
+}
+
+static void
+if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
+{
+       const struct sockaddr *sa;
+
+       if (if_ownmsgpid(ctx, rtm->rtm_pid, rtm->rtm_seq))
+               return;
+
        sa = (const void *)(rtm + 1);
        switch (sa->sa_family) {
 #ifdef INET
@@ -1395,9 +1406,11 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
        struct interface *ifp;
        const struct sockaddr *rti_info[RTAX_MAX];
 
-       /* XXX We have no way of knowing who generated these
-        * messages wich truely sucks because we want to
-        * avoid listening to our own delete messages. */
+#ifdef HAVE_IFAM_PID
+       if (if_ownmsgpid(ctx, ifam->ifam_pid, 0))
+               return;
+#endif
+
        if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL)
                return;
        get_addrs(ifam->ifam_addrs, ifam + 1, rti_info);
@@ -1521,8 +1534,9 @@ if_handlelink(struct dhcpcd_ctx *ctx)
 
        memset(&msg, 0, sizeof(msg));
        msg.msg_iov = &ctx->iov;
+       msg.msg_iovlen = 1;
 
-       if ((bytes = recvmsg_alloc(ctx->link_fd, &msg)) == -1)
+       if ((bytes = recvmsg_realloc(ctx->link_fd, &msg, 0)) == -1)
                return -1;
        if_dispatch(ctx, ctx->iov.iov_base);
        return 0;
index 9d37919399bdf8682641138e5e992dd4440b8ff1..c247b10107a6efda0868eef1da41355ef10edafd 100644 (file)
@@ -344,12 +344,12 @@ get_netlink(struct dhcpcd_ctx *ctx, struct interface *ifp, int fd, int flags,
        int r;
 
        memset(&msg, 0, sizeof(msg));
-       msg.msg_flags = flags;
        msg.msg_name = &nladdr;
        msg.msg_namelen = sizeof(nladdr);
        memset(&nladdr, 0, sizeof(nladdr));
        msg.msg_iov = &ctx->iov;
-       if ((bytes = recvmsg_alloc(fd, &msg)) == -1)
+       msg.msg_iovlen = 1;
+       if ((bytes = recvmsg_realloc(fd, &msg, flags)) == -1)
                return -1;
 
        /* Check sender */
index 064ab936bfa1c3e346df670cd391e0a4bb0f8d04..8ce1887bdfcb1dc0e1c986f89bbd3b94adbe57df 100644 (file)
--- a/if-sun.c
+++ b/if-sun.c
@@ -774,8 +774,9 @@ if_handlelink(struct dhcpcd_ctx *ctx)
 
        memset(&msg, 0, sizeof(msg));
        msg.msg_iov = &ctx->iov;
+       msg.msg_iovlen = 1;
 
-       if ((bytes = recvmsg_alloc(ctx->link_fd, &msg)) == -1)
+       if ((bytes = recvmsg_realloc(ctx->link_fd, &msg, 0)) == -1)
                return -1;
        if_dispatch(ctx, ctx->iov.iov_base);
        return 0;