Mercurial > hg > nginx
annotate src/os/unix/ngx_udp_sendmsg_chain.c @ 9291:ee3eb2b9705f release-1.27.1
freenginx-1.27.1-RELEASE
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 04 Jun 2024 16:55:53 +0300 |
parents | af5adec171b4 |
children |
rev | line source |
---|---|
6692 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_event.h> | |
11 | |
12 | |
13 static ngx_chain_t *ngx_udp_output_chain_to_iovec(ngx_iovec_t *vec, | |
14 ngx_chain_t *in, ngx_log_t *log); | |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
15 static ssize_t ngx_sendmsg_vec(ngx_connection_t *c, ngx_iovec_t *vec); |
6692 | 16 |
17 | |
18 ngx_chain_t * | |
19 ngx_udp_unix_sendmsg_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) | |
20 { | |
21 ssize_t n; | |
22 off_t send; | |
23 ngx_chain_t *cl; | |
24 ngx_event_t *wev; | |
25 ngx_iovec_t vec; | |
26 struct iovec iovs[NGX_IOVS_PREALLOCATE]; | |
27 | |
28 wev = c->write; | |
29 | |
30 if (!wev->ready) { | |
31 return in; | |
32 } | |
33 | |
34 #if (NGX_HAVE_KQUEUE) | |
35 | |
36 if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) { | |
37 (void) ngx_connection_error(c, wev->kq_errno, | |
38 "kevent() reported about an closed connection"); | |
39 wev->error = 1; | |
40 return NGX_CHAIN_ERROR; | |
41 } | |
42 | |
43 #endif | |
44 | |
45 /* the maximum limit size is the maximum size_t value - the page size */ | |
46 | |
47 if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) { | |
48 limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize; | |
49 } | |
50 | |
51 send = 0; | |
52 | |
53 vec.iovs = iovs; | |
54 vec.nalloc = NGX_IOVS_PREALLOCATE; | |
55 | |
56 for ( ;; ) { | |
57 | |
58 /* create the iovec and coalesce the neighbouring bufs */ | |
59 | |
60 cl = ngx_udp_output_chain_to_iovec(&vec, in, c->log); | |
61 | |
62 if (cl == NGX_CHAIN_ERROR) { | |
63 return NGX_CHAIN_ERROR; | |
64 } | |
65 | |
66 if (cl && cl->buf->in_file) { | |
67 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
68 "file buf in sendmsg " | |
69 "t:%d r:%d f:%d %p %p-%p %p %O-%O", | |
70 cl->buf->temporary, | |
71 cl->buf->recycled, | |
72 cl->buf->in_file, | |
73 cl->buf->start, | |
74 cl->buf->pos, | |
75 cl->buf->last, | |
76 cl->buf->file, | |
77 cl->buf->file_pos, | |
78 cl->buf->file_last); | |
79 | |
80 ngx_debug_point(); | |
81 | |
82 return NGX_CHAIN_ERROR; | |
83 } | |
84 | |
85 if (cl == in) { | |
86 return in; | |
87 } | |
88 | |
89 send += vec.size; | |
90 | |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
91 n = ngx_sendmsg_vec(c, &vec); |
6692 | 92 |
93 if (n == NGX_ERROR) { | |
94 return NGX_CHAIN_ERROR; | |
95 } | |
96 | |
97 if (n == NGX_AGAIN) { | |
98 wev->ready = 0; | |
99 return in; | |
100 } | |
101 | |
102 c->sent += n; | |
103 | |
104 in = ngx_chain_update_sent(in, n); | |
105 | |
106 if (send >= limit || in == NULL) { | |
107 return in; | |
108 } | |
109 } | |
110 } | |
111 | |
112 | |
113 static ngx_chain_t * | |
114 ngx_udp_output_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *in, ngx_log_t *log) | |
115 { | |
116 size_t total, size; | |
117 u_char *prev; | |
118 ngx_uint_t n, flush; | |
119 ngx_chain_t *cl; | |
120 struct iovec *iov; | |
121 | |
122 cl = in; | |
123 iov = NULL; | |
124 prev = NULL; | |
125 total = 0; | |
126 n = 0; | |
127 flush = 0; | |
128 | |
129 for ( /* void */ ; in && !flush; in = in->next) { | |
130 | |
131 if (in->buf->flush || in->buf->last_buf) { | |
132 flush = 1; | |
133 } | |
134 | |
135 if (ngx_buf_special(in->buf)) { | |
136 continue; | |
137 } | |
138 | |
139 if (in->buf->in_file) { | |
140 break; | |
141 } | |
142 | |
143 if (!ngx_buf_in_memory(in->buf)) { | |
144 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
145 "bad buf in output chain " | |
146 "t:%d r:%d f:%d %p %p-%p %p %O-%O", | |
147 in->buf->temporary, | |
148 in->buf->recycled, | |
149 in->buf->in_file, | |
150 in->buf->start, | |
151 in->buf->pos, | |
152 in->buf->last, | |
153 in->buf->file, | |
154 in->buf->file_pos, | |
155 in->buf->file_last); | |
156 | |
157 ngx_debug_point(); | |
158 | |
159 return NGX_CHAIN_ERROR; | |
160 } | |
161 | |
162 size = in->buf->last - in->buf->pos; | |
163 | |
164 if (prev == in->buf->pos) { | |
165 iov->iov_len += size; | |
166 | |
167 } else { | |
168 if (n == vec->nalloc) { | |
169 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
170 "too many parts in a datagram"); | |
171 return NGX_CHAIN_ERROR; | |
172 } | |
173 | |
174 iov = &vec->iovs[n++]; | |
175 | |
176 iov->iov_base = (void *) in->buf->pos; | |
177 iov->iov_len = size; | |
178 } | |
179 | |
180 prev = in->buf->pos + size; | |
181 total += size; | |
182 } | |
183 | |
184 if (!flush) { | |
185 #if (NGX_SUPPRESS_WARN) | |
186 vec->size = 0; | |
187 vec->count = 0; | |
188 #endif | |
189 return cl; | |
190 } | |
191 | |
7665
d127837c714f
Stream: fixed processing of zero length UDP packets (ticket #1982).
Vladimir Homutov <vl@nginx.com>
parents:
7019
diff
changeset
|
192 /* zero-sized datagram; pretend to have at least 1 iov */ |
d127837c714f
Stream: fixed processing of zero length UDP packets (ticket #1982).
Vladimir Homutov <vl@nginx.com>
parents:
7019
diff
changeset
|
193 if (n == 0) { |
d127837c714f
Stream: fixed processing of zero length UDP packets (ticket #1982).
Vladimir Homutov <vl@nginx.com>
parents:
7019
diff
changeset
|
194 iov = &vec->iovs[n++]; |
d127837c714f
Stream: fixed processing of zero length UDP packets (ticket #1982).
Vladimir Homutov <vl@nginx.com>
parents:
7019
diff
changeset
|
195 iov->iov_base = NULL; |
d127837c714f
Stream: fixed processing of zero length UDP packets (ticket #1982).
Vladimir Homutov <vl@nginx.com>
parents:
7019
diff
changeset
|
196 iov->iov_len = 0; |
d127837c714f
Stream: fixed processing of zero length UDP packets (ticket #1982).
Vladimir Homutov <vl@nginx.com>
parents:
7019
diff
changeset
|
197 } |
d127837c714f
Stream: fixed processing of zero length UDP packets (ticket #1982).
Vladimir Homutov <vl@nginx.com>
parents:
7019
diff
changeset
|
198 |
6692 | 199 vec->count = n; |
200 vec->size = total; | |
201 | |
202 return in; | |
203 } | |
204 | |
205 | |
206 static ssize_t | |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
207 ngx_sendmsg_vec(ngx_connection_t *c, ngx_iovec_t *vec) |
6692 | 208 { |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
209 struct msghdr msg; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
210 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
211 #if (NGX_HAVE_ADDRINFO_CMSG) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
212 struct cmsghdr *cmsg; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
213 u_char msg_control[CMSG_SPACE(sizeof(ngx_addrinfo_t))]; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
214 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
215 |
6692 | 216 ngx_memzero(&msg, sizeof(struct msghdr)); |
217 | |
218 if (c->socklen) { | |
219 msg.msg_name = c->sockaddr; | |
220 msg.msg_namelen = c->socklen; | |
221 } | |
222 | |
223 msg.msg_iov = vec->iovs; | |
224 msg.msg_iovlen = vec->count; | |
225 | |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
226 #if (NGX_HAVE_ADDRINFO_CMSG) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
227 if (c->listening && c->listening->wildcard && c->local_sockaddr) { |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
228 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
229 msg.msg_control = msg_control; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
230 msg.msg_controllen = sizeof(msg_control); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
231 ngx_memzero(msg_control, sizeof(msg_control)); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
232 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
233 cmsg = CMSG_FIRSTHDR(&msg); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
234 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
235 msg.msg_controllen = ngx_set_srcaddr_cmsg(cmsg, c->local_sockaddr); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
236 } |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
237 #endif |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
238 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
239 return ngx_sendmsg(c, &msg, 0); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
240 } |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
241 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
242 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
243 #if (NGX_HAVE_ADDRINFO_CMSG) |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
244 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
245 size_t |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
246 ngx_set_srcaddr_cmsg(struct cmsghdr *cmsg, struct sockaddr *local_sockaddr) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
247 { |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
248 size_t len; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
249 #if (NGX_HAVE_IP_SENDSRCADDR) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
250 struct in_addr *addr; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
251 struct sockaddr_in *sin; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
252 #elif (NGX_HAVE_IP_PKTINFO) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
253 struct in_pktinfo *pkt; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
254 struct sockaddr_in *sin; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
255 #endif |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
256 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
257 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
258 struct in6_pktinfo *pkt6; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
259 struct sockaddr_in6 *sin6; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
260 #endif |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
261 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
262 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
263 #if (NGX_HAVE_IP_SENDSRCADDR) || (NGX_HAVE_IP_PKTINFO) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
264 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
265 if (local_sockaddr->sa_family == AF_INET) { |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
266 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
267 cmsg->cmsg_level = IPPROTO_IP; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
268 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
269 #if (NGX_HAVE_IP_SENDSRCADDR) |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
270 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
271 cmsg->cmsg_type = IP_SENDSRCADDR; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
272 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
273 len = CMSG_SPACE(sizeof(struct in_addr)); |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
274 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
275 sin = (struct sockaddr_in *) local_sockaddr; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
276 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
277 addr = (struct in_addr *) CMSG_DATA(cmsg); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
278 *addr = sin->sin_addr; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
279 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
280 #elif (NGX_HAVE_IP_PKTINFO) |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
281 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
282 cmsg->cmsg_type = IP_PKTINFO; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
283 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
284 len = CMSG_SPACE(sizeof(struct in_pktinfo)); |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
285 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
286 sin = (struct sockaddr_in *) local_sockaddr; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
287 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
288 pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
289 ngx_memzero(pkt, sizeof(struct in_pktinfo)); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
290 pkt->ipi_spec_dst = sin->sin_addr; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
291 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
292 #endif |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
293 return len; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
294 } |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
295 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
296 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
297 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
298 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
299 if (local_sockaddr->sa_family == AF_INET6) { |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
300 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
301 cmsg->cmsg_level = IPPROTO_IPV6; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
302 cmsg->cmsg_type = IPV6_PKTINFO; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
303 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
304 len = CMSG_SPACE(sizeof(struct in6_pktinfo)); |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
305 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
306 sin6 = (struct sockaddr_in6 *) local_sockaddr; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
307 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
308 pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
309 ngx_memzero(pkt6, sizeof(struct in6_pktinfo)); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
310 pkt6->ipi6_addr = sin6->sin6_addr; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
311 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
312 return len; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
313 } |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
314 #endif |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
315 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
316 return 0; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
317 } |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
318 |
8003
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
319 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
320 ngx_int_t |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
321 ngx_get_srcaddr_cmsg(struct cmsghdr *cmsg, struct sockaddr *local_sockaddr) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
322 { |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
323 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
324 #if (NGX_HAVE_IP_RECVDSTADDR) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
325 struct in_addr *addr; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
326 struct sockaddr_in *sin; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
327 #elif (NGX_HAVE_IP_PKTINFO) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
328 struct in_pktinfo *pkt; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
329 struct sockaddr_in *sin; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
330 #endif |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
331 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
332 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
333 struct in6_pktinfo *pkt6; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
334 struct sockaddr_in6 *sin6; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
335 #endif |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
336 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
337 |
8116 | 338 #if (NGX_HAVE_IP_RECVDSTADDR) |
8003
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
339 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
340 if (cmsg->cmsg_level == IPPROTO_IP |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
341 && cmsg->cmsg_type == IP_RECVDSTADDR |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
342 && local_sockaddr->sa_family == AF_INET) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
343 { |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
344 addr = (struct in_addr *) CMSG_DATA(cmsg); |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
345 sin = (struct sockaddr_in *) local_sockaddr; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
346 sin->sin_addr = *addr; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
347 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
348 return NGX_OK; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
349 } |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
350 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
351 #elif (NGX_HAVE_IP_PKTINFO) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
352 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
353 if (cmsg->cmsg_level == IPPROTO_IP |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
354 && cmsg->cmsg_type == IP_PKTINFO |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
355 && local_sockaddr->sa_family == AF_INET) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
356 { |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
357 pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
358 sin = (struct sockaddr_in *) local_sockaddr; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
359 sin->sin_addr = pkt->ipi_addr; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
360 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
361 return NGX_OK; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
362 } |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
363 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
364 #endif |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
365 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
366 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
367 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
368 if (cmsg->cmsg_level == IPPROTO_IPV6 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
369 && cmsg->cmsg_type == IPV6_PKTINFO |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
370 && local_sockaddr->sa_family == AF_INET6) |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
371 { |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
372 pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
373 sin6 = (struct sockaddr_in6 *) local_sockaddr; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
374 sin6->sin6_addr = pkt6->ipi6_addr; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
375 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
376 return NGX_OK; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
377 } |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
378 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
379 #endif |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
380 |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
381 return NGX_DECLINED; |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
382 } |
0f6cc8f73744
Core: added function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8002
diff
changeset
|
383 |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
384 #endif |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
385 |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
386 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
387 ssize_t |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
388 ngx_sendmsg(ngx_connection_t *c, struct msghdr *msg, int flags) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
389 { |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
390 ssize_t n; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
391 ngx_err_t err; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
392 #if (NGX_DEBUG) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
393 size_t size; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
394 ngx_uint_t i; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
395 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
396 |
6692 | 397 eintr: |
398 | |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
399 n = sendmsg(c->fd, msg, flags); |
6692 | 400 |
401 if (n == -1) { | |
402 err = ngx_errno; | |
403 | |
404 switch (err) { | |
405 case NGX_EAGAIN: | |
406 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
407 "sendmsg() not ready"); | |
408 return NGX_AGAIN; | |
409 | |
410 case NGX_EINTR: | |
411 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
412 "sendmsg() was interrupted"); | |
413 goto eintr; | |
414 | |
415 default: | |
416 c->write->error = 1; | |
417 ngx_connection_error(c, err, "sendmsg() failed"); | |
418 return NGX_ERROR; | |
419 } | |
420 } | |
421 | |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
422 #if (NGX_DEBUG) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
423 for (i = 0, size = 0; i < (size_t) msg->msg_iovlen; i++) { |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
424 size += msg->msg_iov[i].iov_len; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
425 } |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
426 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
427 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
428 "sendmsg: %z of %uz", n, size); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
429 #endif |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
430 |
6692 | 431 return n; |
432 } |