Mercurial > hg > nginx
annotate src/os/unix/ngx_udp_sendmsg_chain.c @ 8002:cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
The NGX_HAVE_ADDRINFO_CMSG macro is defined when at least one of methods
to deal with corresponding control message is available.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Tue, 25 Jan 2022 15:48:56 +0300 |
parents | d127837c714f |
children | 0f6cc8f73744 |
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 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
319 #endif |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
320 |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
321 |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
322 ssize_t |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
323 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
|
324 { |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
325 ssize_t n; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
326 ngx_err_t err; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
327 #if (NGX_DEBUG) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
328 size_t size; |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
329 ngx_uint_t i; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
330 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
331 |
6692 | 332 eintr: |
333 | |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
334 n = sendmsg(c->fd, msg, flags); |
6692 | 335 |
336 if (n == -1) { | |
337 err = ngx_errno; | |
338 | |
339 switch (err) { | |
340 case NGX_EAGAIN: | |
341 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
342 "sendmsg() not ready"); | |
343 return NGX_AGAIN; | |
344 | |
345 case NGX_EINTR: | |
346 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
347 "sendmsg() was interrupted"); | |
348 goto eintr; | |
349 | |
350 default: | |
351 c->write->error = 1; | |
352 ngx_connection_error(c, err, "sendmsg() failed"); | |
353 return NGX_ERROR; | |
354 } | |
355 } | |
356 | |
8002
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
357 #if (NGX_DEBUG) |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
358 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
|
359 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
|
360 } |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
361 |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
362 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
|
363 "sendmsg: %z of %uz", n, size); |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
364 #endif |
cfe1284e5d1d
Core: made the ngx_sendmsg() function non-static.
Vladimir Homutov <vl@nginx.com>
parents:
7665
diff
changeset
|
365 |
6692 | 366 return n; |
367 } |