changeset 8003:0f6cc8f73744

Core: added function for local source address cmsg.
author Vladimir Homutov <vl@nginx.com>
date Tue, 25 Jan 2022 15:48:58 +0300
parents cfe1284e5d1d
children c0a432c0301b
files src/event/ngx_event_udp.c src/event/ngx_event_udp.h src/os/unix/ngx_udp_sendmsg_chain.c
diffstat 3 files changed, 77 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_udp.c
+++ b/src/event/ngx_event_udp.c
@@ -46,18 +46,8 @@ ngx_event_recvmsg(ngx_event_t *ev)
     ngx_connection_t  *c, *lc;
     static u_char      buffer[65535];
 
-#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
-
-#if (NGX_HAVE_IP_RECVDSTADDR)
-    u_char             msg_control[CMSG_SPACE(sizeof(struct in_addr))];
-#elif (NGX_HAVE_IP_PKTINFO)
-    u_char             msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))];
-#endif
-
-#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
-    u_char             msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
-#endif
-
+#if (NGX_HAVE_ADDRINFO_CMSG)
+    u_char             msg_control[CMSG_SPACE(sizeof(ngx_addrinfo_t))];
 #endif
 
     if (ev->timedout) {
@@ -92,25 +82,13 @@ ngx_event_recvmsg(ngx_event_t *ev)
         msg.msg_iov = iov;
         msg.msg_iovlen = 1;
 
-#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
-
+#if (NGX_HAVE_ADDRINFO_CMSG)
         if (ls->wildcard) {
+            msg.msg_control = &msg_control;
+            msg.msg_controllen = sizeof(msg_control);
 
-#if (NGX_HAVE_IP_RECVDSTADDR || NGX_HAVE_IP_PKTINFO)
-            if (ls->sockaddr->sa_family == AF_INET) {
-                msg.msg_control = &msg_control;
-                msg.msg_controllen = sizeof(msg_control);
-            }
-#endif
-
-#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
-            if (ls->sockaddr->sa_family == AF_INET6) {
-                msg.msg_control = &msg_control6;
-                msg.msg_controllen = sizeof(msg_control6);
-            }
-#endif
-        }
-
+            ngx_memzero(&msg_control, sizeof(msg_control));
+       }
 #endif
 
         n = recvmsg(lc->fd, &msg, 0);
@@ -129,7 +107,7 @@ ngx_event_recvmsg(ngx_event_t *ev)
             return;
         }
 
-#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
+#if (NGX_HAVE_ADDRINFO_CMSG)
         if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
             ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
                           "recvmsg() truncated data");
@@ -159,7 +137,7 @@ ngx_event_recvmsg(ngx_event_t *ev)
         local_sockaddr = ls->sockaddr;
         local_socklen = ls->socklen;
 
-#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
+#if (NGX_HAVE_ADDRINFO_CMSG)
 
         if (ls->wildcard) {
             struct cmsghdr  *cmsg;
@@ -171,59 +149,9 @@ ngx_event_recvmsg(ngx_event_t *ev)
                  cmsg != NULL;
                  cmsg = CMSG_NXTHDR(&msg, cmsg))
             {
-
-#if (NGX_HAVE_IP_RECVDSTADDR)
-
-                if (cmsg->cmsg_level == IPPROTO_IP
-                    && cmsg->cmsg_type == IP_RECVDSTADDR
-                    && local_sockaddr->sa_family == AF_INET)
-                {
-                    struct in_addr      *addr;
-                    struct sockaddr_in  *sin;
-
-                    addr = (struct in_addr *) CMSG_DATA(cmsg);
-                    sin = (struct sockaddr_in *) local_sockaddr;
-                    sin->sin_addr = *addr;
-
+                if (ngx_get_srcaddr_cmsg(cmsg, local_sockaddr) == NGX_OK) {
                     break;
                 }
-
-#elif (NGX_HAVE_IP_PKTINFO)
-
-                if (cmsg->cmsg_level == IPPROTO_IP
-                    && cmsg->cmsg_type == IP_PKTINFO
-                    && local_sockaddr->sa_family == AF_INET)
-                {
-                    struct in_pktinfo   *pkt;
-                    struct sockaddr_in  *sin;
-
-                    pkt = (struct in_pktinfo *) CMSG_DATA(cmsg);
-                    sin = (struct sockaddr_in *) local_sockaddr;
-                    sin->sin_addr = pkt->ipi_addr;
-
-                    break;
-                }
-
-#endif
-
-#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
-
-                if (cmsg->cmsg_level == IPPROTO_IPV6
-                    && cmsg->cmsg_type == IPV6_PKTINFO
-                    && local_sockaddr->sa_family == AF_INET6)
-                {
-                    struct in6_pktinfo   *pkt6;
-                    struct sockaddr_in6  *sin6;
-
-                    pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg);
-                    sin6 = (struct sockaddr_in6 *) local_sockaddr;
-                    sin6->sin6_addr = pkt6->ipi6_addr;
-
-                    break;
-                }
-
-#endif
-
             }
         }
 
--- a/src/event/ngx_event_udp.h
+++ b/src/event/ngx_event_udp.h
@@ -41,6 +41,8 @@ typedef union {
 
 size_t ngx_set_srcaddr_cmsg(struct cmsghdr *cmsg,
     struct sockaddr *local_sockaddr);
+ngx_int_t ngx_get_srcaddr_cmsg(struct cmsghdr *cmsg,
+    struct sockaddr *local_sockaddr);
 
 #endif
 
--- a/src/os/unix/ngx_udp_sendmsg_chain.c
+++ b/src/os/unix/ngx_udp_sendmsg_chain.c
@@ -316,6 +316,71 @@ ngx_set_srcaddr_cmsg(struct cmsghdr *cms
     return 0;
 }
 
+
+ngx_int_t
+ngx_get_srcaddr_cmsg(struct cmsghdr *cmsg, struct sockaddr *local_sockaddr)
+{
+
+#if (NGX_HAVE_IP_RECVDSTADDR)
+    struct in_addr       *addr;
+    struct sockaddr_in   *sin;
+#elif (NGX_HAVE_IP_PKTINFO)
+    struct in_pktinfo    *pkt;
+    struct sockaddr_in   *sin;
+#endif
+
+#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
+    struct in6_pktinfo   *pkt6;
+    struct sockaddr_in6  *sin6;
+#endif
+
+
+ #if (NGX_HAVE_IP_RECVDSTADDR)
+
+    if (cmsg->cmsg_level == IPPROTO_IP
+        && cmsg->cmsg_type == IP_RECVDSTADDR
+        && local_sockaddr->sa_family == AF_INET)
+    {
+        addr = (struct in_addr *) CMSG_DATA(cmsg);
+        sin = (struct sockaddr_in *) local_sockaddr;
+        sin->sin_addr = *addr;
+
+        return NGX_OK;
+    }
+
+#elif (NGX_HAVE_IP_PKTINFO)
+
+    if (cmsg->cmsg_level == IPPROTO_IP
+        && cmsg->cmsg_type == IP_PKTINFO
+        && local_sockaddr->sa_family == AF_INET)
+    {
+        pkt = (struct in_pktinfo *) CMSG_DATA(cmsg);
+        sin = (struct sockaddr_in *) local_sockaddr;
+        sin->sin_addr = pkt->ipi_addr;
+
+        return NGX_OK;
+    }
+
+#endif
+
+#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
+
+    if (cmsg->cmsg_level == IPPROTO_IPV6
+        && cmsg->cmsg_type == IPV6_PKTINFO
+        && local_sockaddr->sa_family == AF_INET6)
+    {
+        pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg);
+        sin6 = (struct sockaddr_in6 *) local_sockaddr;
+        sin6->sin6_addr = pkt6->ipi6_addr;
+
+        return NGX_OK;
+    }
+
+#endif
+
+    return NGX_DECLINED;
+}
+
 #endif