Mercurial > hg > nginx
comparison src/event/ngx_event_udp.c @ 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 | fdc3d40979b0 |
children | 32b0ba4855a6 |
comparison
equal
deleted
inserted
replaced
8002:cfe1284e5d1d | 8003:0f6cc8f73744 |
---|---|
44 ngx_listening_t *ls; | 44 ngx_listening_t *ls; |
45 ngx_event_conf_t *ecf; | 45 ngx_event_conf_t *ecf; |
46 ngx_connection_t *c, *lc; | 46 ngx_connection_t *c, *lc; |
47 static u_char buffer[65535]; | 47 static u_char buffer[65535]; |
48 | 48 |
49 #if (NGX_HAVE_MSGHDR_MSG_CONTROL) | 49 #if (NGX_HAVE_ADDRINFO_CMSG) |
50 | 50 u_char msg_control[CMSG_SPACE(sizeof(ngx_addrinfo_t))]; |
51 #if (NGX_HAVE_IP_RECVDSTADDR) | |
52 u_char msg_control[CMSG_SPACE(sizeof(struct in_addr))]; | |
53 #elif (NGX_HAVE_IP_PKTINFO) | |
54 u_char msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))]; | |
55 #endif | |
56 | |
57 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) | |
58 u_char msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; | |
59 #endif | |
60 | |
61 #endif | 51 #endif |
62 | 52 |
63 if (ev->timedout) { | 53 if (ev->timedout) { |
64 if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) { | 54 if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) { |
65 return; | 55 return; |
90 msg.msg_name = &sa; | 80 msg.msg_name = &sa; |
91 msg.msg_namelen = sizeof(ngx_sockaddr_t); | 81 msg.msg_namelen = sizeof(ngx_sockaddr_t); |
92 msg.msg_iov = iov; | 82 msg.msg_iov = iov; |
93 msg.msg_iovlen = 1; | 83 msg.msg_iovlen = 1; |
94 | 84 |
95 #if (NGX_HAVE_MSGHDR_MSG_CONTROL) | 85 #if (NGX_HAVE_ADDRINFO_CMSG) |
96 | |
97 if (ls->wildcard) { | 86 if (ls->wildcard) { |
98 | 87 msg.msg_control = &msg_control; |
99 #if (NGX_HAVE_IP_RECVDSTADDR || NGX_HAVE_IP_PKTINFO) | 88 msg.msg_controllen = sizeof(msg_control); |
100 if (ls->sockaddr->sa_family == AF_INET) { | 89 |
101 msg.msg_control = &msg_control; | 90 ngx_memzero(&msg_control, sizeof(msg_control)); |
102 msg.msg_controllen = sizeof(msg_control); | 91 } |
103 } | |
104 #endif | |
105 | |
106 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) | |
107 if (ls->sockaddr->sa_family == AF_INET6) { | |
108 msg.msg_control = &msg_control6; | |
109 msg.msg_controllen = sizeof(msg_control6); | |
110 } | |
111 #endif | |
112 } | |
113 | |
114 #endif | 92 #endif |
115 | 93 |
116 n = recvmsg(lc->fd, &msg, 0); | 94 n = recvmsg(lc->fd, &msg, 0); |
117 | 95 |
118 if (n == -1) { | 96 if (n == -1) { |
127 ngx_log_error(NGX_LOG_ALERT, ev->log, err, "recvmsg() failed"); | 105 ngx_log_error(NGX_LOG_ALERT, ev->log, err, "recvmsg() failed"); |
128 | 106 |
129 return; | 107 return; |
130 } | 108 } |
131 | 109 |
132 #if (NGX_HAVE_MSGHDR_MSG_CONTROL) | 110 #if (NGX_HAVE_ADDRINFO_CMSG) |
133 if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) { | 111 if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) { |
134 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, | 112 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, |
135 "recvmsg() truncated data"); | 113 "recvmsg() truncated data"); |
136 continue; | 114 continue; |
137 } | 115 } |
157 } | 135 } |
158 | 136 |
159 local_sockaddr = ls->sockaddr; | 137 local_sockaddr = ls->sockaddr; |
160 local_socklen = ls->socklen; | 138 local_socklen = ls->socklen; |
161 | 139 |
162 #if (NGX_HAVE_MSGHDR_MSG_CONTROL) | 140 #if (NGX_HAVE_ADDRINFO_CMSG) |
163 | 141 |
164 if (ls->wildcard) { | 142 if (ls->wildcard) { |
165 struct cmsghdr *cmsg; | 143 struct cmsghdr *cmsg; |
166 | 144 |
167 ngx_memcpy(&lsa, local_sockaddr, local_socklen); | 145 ngx_memcpy(&lsa, local_sockaddr, local_socklen); |
169 | 147 |
170 for (cmsg = CMSG_FIRSTHDR(&msg); | 148 for (cmsg = CMSG_FIRSTHDR(&msg); |
171 cmsg != NULL; | 149 cmsg != NULL; |
172 cmsg = CMSG_NXTHDR(&msg, cmsg)) | 150 cmsg = CMSG_NXTHDR(&msg, cmsg)) |
173 { | 151 { |
174 | 152 if (ngx_get_srcaddr_cmsg(cmsg, local_sockaddr) == NGX_OK) { |
175 #if (NGX_HAVE_IP_RECVDSTADDR) | |
176 | |
177 if (cmsg->cmsg_level == IPPROTO_IP | |
178 && cmsg->cmsg_type == IP_RECVDSTADDR | |
179 && local_sockaddr->sa_family == AF_INET) | |
180 { | |
181 struct in_addr *addr; | |
182 struct sockaddr_in *sin; | |
183 | |
184 addr = (struct in_addr *) CMSG_DATA(cmsg); | |
185 sin = (struct sockaddr_in *) local_sockaddr; | |
186 sin->sin_addr = *addr; | |
187 | |
188 break; | 153 break; |
189 } | 154 } |
190 | |
191 #elif (NGX_HAVE_IP_PKTINFO) | |
192 | |
193 if (cmsg->cmsg_level == IPPROTO_IP | |
194 && cmsg->cmsg_type == IP_PKTINFO | |
195 && local_sockaddr->sa_family == AF_INET) | |
196 { | |
197 struct in_pktinfo *pkt; | |
198 struct sockaddr_in *sin; | |
199 | |
200 pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); | |
201 sin = (struct sockaddr_in *) local_sockaddr; | |
202 sin->sin_addr = pkt->ipi_addr; | |
203 | |
204 break; | |
205 } | |
206 | |
207 #endif | |
208 | |
209 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) | |
210 | |
211 if (cmsg->cmsg_level == IPPROTO_IPV6 | |
212 && cmsg->cmsg_type == IPV6_PKTINFO | |
213 && local_sockaddr->sa_family == AF_INET6) | |
214 { | |
215 struct in6_pktinfo *pkt6; | |
216 struct sockaddr_in6 *sin6; | |
217 | |
218 pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); | |
219 sin6 = (struct sockaddr_in6 *) local_sockaddr; | |
220 sin6->sin6_addr = pkt6->ipi6_addr; | |
221 | |
222 break; | |
223 } | |
224 | |
225 #endif | |
226 | |
227 } | 155 } |
228 } | 156 } |
229 | 157 |
230 #endif | 158 #endif |
231 | 159 |