Core: added function for local source address cmsg.

This commit is contained in:
Vladimir Homutov 2022-01-25 15:48:58 +03:00
parent 906d7f354f
commit bb42e87e67
3 changed files with 77 additions and 82 deletions

View File

@ -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
}
}

View File

@ -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

View File

@ -316,6 +316,71 @@ ngx_set_srcaddr_cmsg(struct cmsghdr *cmsg, struct sockaddr *local_sockaddr)
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