Mercurial > hg > nginx-quic
annotate src/os/unix/ngx_udp_sendmsg_chain.c @ 8717:e06283038ec8 quic
QUIC: clear SSL_OP_ENABLE_MIDDLEBOX_COMPAT on SSL context switch.
The SSL_OP_ENABLE_MIDDLEBOX_COMPAT option is provided by QuicTLS and enabled
by default in the newly created SSL contexts. SSL_set_quic_method() is used
to clear it, which is required for SSL handshake to work on QUIC connections.
Switching context in the ngx_http_ssl_servername() SNI callback overrides SSL
options from the new SSL context. This results in the option set again.
Fix is to explicitly clear it when switching to another SSL context.
Initially reported here (in Russian):
http://mailman.nginx.org/pipermail/nginx-ru/2021-November/063989.html
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Tue, 07 Dec 2021 15:49:51 +0300 |
parents | 913ff20e4c62 |
children | 4646a981111f |
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); | |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 | |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 | |
7968
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 | |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
207 ngx_sendmsg_vec(ngx_connection_t *c, ngx_iovec_t *vec) |
6692 | 208 { |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
211 #if defined(NGX_HAVE_ADDRINFO_CMSG) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
212 struct cmsghdr *cmsg; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 | |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
226 #if defined(NGX_HAVE_ADDRINFO_CMSG) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
227 if (c->listening && c->listening->wildcard && c->local_sockaddr) { |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
228 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
229 msg.msg_control = msg_control; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
230 msg.msg_controllen = sizeof(msg_control); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
231 ngx_memzero(msg_control, sizeof(msg_control)); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
232 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
233 cmsg = CMSG_FIRSTHDR(&msg); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
234 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
235 msg.msg_controllen = ngx_set_srcaddr_cmsg(cmsg, c->local_sockaddr); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
236 } |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
237 #endif |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
238 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
239 return ngx_sendmsg(c, &msg, 0); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
240 } |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
241 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
242 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
243 #if defined(NGX_HAVE_ADDRINFO_CMSG) |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
244 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
245 size_t |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
246 ngx_set_srcaddr_cmsg(struct cmsghdr *cmsg, struct sockaddr *local_sockaddr) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
247 { |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
248 size_t len; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
249 #if (NGX_HAVE_IP_SENDSRCADDR) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
250 struct in_addr *addr; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
251 struct sockaddr_in *sin; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
252 #elif (NGX_HAVE_IP_PKTINFO) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
253 struct in_pktinfo *pkt; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
254 struct sockaddr_in *sin; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
255 #endif |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
256 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
257 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
258 struct in6_pktinfo *pkt6; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
259 struct sockaddr_in6 *sin6; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
260 #endif |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
261 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
262 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
263 #if (NGX_HAVE_IP_SENDSRCADDR) || (NGX_HAVE_IP_PKTINFO) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
264 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
265 if (local_sockaddr->sa_family == AF_INET) { |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
266 |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
271 cmsg->cmsg_type = IP_SENDSRCADDR; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
272 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
277 addr = (struct in_addr *) CMSG_DATA(cmsg); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
282 cmsg->cmsg_type = IP_PKTINFO; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
283 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
288 pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
289 ngx_memzero(pkt, sizeof(struct in_pktinfo)); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
292 #endif |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
293 return len; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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) |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
301 cmsg->cmsg_level = IPPROTO_IPV6; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
302 cmsg->cmsg_type = IPV6_PKTINFO; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
303 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
308 pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
309 ngx_memzero(pkt6, sizeof(struct in6_pktinfo)); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
312 return len; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
313 } |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
314 #endif |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
315 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
316 return 0; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
317 } |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
318 |
8513
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
319 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
320 ngx_int_t |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
321 ngx_get_srcaddr_cmsg(struct cmsghdr *cmsg, struct sockaddr *local_sockaddr) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
322 { |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
323 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
324 #if (NGX_HAVE_IP_RECVDSTADDR) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
325 struct in_addr *addr; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
326 struct sockaddr_in *sin; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
327 #elif (NGX_HAVE_IP_PKTINFO) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
328 struct in_pktinfo *pkt; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
329 struct sockaddr_in *sin; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
330 #endif |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
331 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
332 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
333 struct in6_pktinfo *pkt6; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
334 struct sockaddr_in6 *sin6; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
335 #endif |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
336 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
337 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
338 #if (NGX_HAVE_IP_RECVDSTADDR) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
339 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
340 if (cmsg->cmsg_level == IPPROTO_IP |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
341 && cmsg->cmsg_type == IP_RECVDSTADDR |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
342 && local_sockaddr->sa_family == AF_INET) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
343 { |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
344 addr = (struct in_addr *) CMSG_DATA(cmsg); |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
345 sin = (struct sockaddr_in *) local_sockaddr; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
346 sin->sin_addr = *addr; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
347 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
348 return NGX_OK; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
349 } |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
350 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
351 #elif (NGX_HAVE_IP_PKTINFO) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
352 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
353 if (cmsg->cmsg_level == IPPROTO_IP |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
354 && cmsg->cmsg_type == IP_PKTINFO |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
355 && local_sockaddr->sa_family == AF_INET) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
356 { |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
357 pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
358 sin = (struct sockaddr_in *) local_sockaddr; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
359 sin->sin_addr = pkt->ipi_addr; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
360 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
361 return NGX_OK; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
362 } |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
363 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
364 #endif |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
365 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
366 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
367 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
368 if (cmsg->cmsg_level == IPPROTO_IPV6 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
369 && cmsg->cmsg_type == IPV6_PKTINFO |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
370 && local_sockaddr->sa_family == AF_INET6) |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
371 { |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
372 pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
373 sin6 = (struct sockaddr_in6 *) local_sockaddr; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
374 sin6->sin6_addr = pkt6->ipi6_addr; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
375 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
376 return NGX_OK; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
377 } |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
378 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
379 #endif |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
380 |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
381 return NGX_DECLINED; |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
382 } |
e7a2d3914877
Core: added separate function for local source address cmsg.
Vladimir Homutov <vl@nginx.com>
parents:
8511
diff
changeset
|
383 |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
384 #endif |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
385 |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
386 |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
387 ssize_t |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
388 ngx_sendmsg(ngx_connection_t *c, struct msghdr *msg, int flags) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
389 { |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
390 ssize_t n; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
391 ngx_err_t err; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
392 #if (NGX_DEBUG) |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
393 size_t size; |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
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 | |
8511
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
399 n = sendmsg(c->fd, msg, flags); |
2dfd313f22f2
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7968
diff
changeset
|
400 |
6692 | 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 | |
8539
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
422 #if (NGX_DEBUG) |
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
423 for (i = 0, size = 0; i < (size_t) msg->msg_iovlen; i++) { |
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
424 size += msg->msg_iov[i].iov_len; |
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
425 } |
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
426 |
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
427 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
428 "sendmsg: %z of %uz", n, size); |
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
429 #endif |
913ff20e4c62
Core: fixed errno clobbering in ngx_sendmsg().
Vladimir Homutov <vl@nginx.com>
parents:
8513
diff
changeset
|
430 |
6692 | 431 return n; |
432 } |