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