Mercurial > hg > nginx-quic
annotate src/os/unix/ngx_udp_sendmsg_chain.c @ 7870:e169cce912c7 quic
Avoid retransmitting of packets with discarded keys.
Sections 4.10.1 and 4.10.2 of quic transport describe discarding of initial
and handshake keys. Since the keys are discarded, we no longer need
to retransmit packets and corresponding queues should be emptied.
This patch removes previously added workaround that did not require
acknowledgement for initial packets, resulting in avoiding retransmission,
which is wrong because a packet could be lost and we have to retransmit it.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 18 May 2020 13:54:53 +0300 |
parents | 8ce1a34f160b |
children | d127837c714f |
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); | |
15 static ssize_t ngx_sendmsg(ngx_connection_t *c, ngx_iovec_t *vec); | |
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 | |
91 n = ngx_sendmsg(c, &vec); | |
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 | |
192 vec->count = n; | |
193 vec->size = total; | |
194 | |
195 return in; | |
196 } | |
197 | |
198 | |
199 static ssize_t | |
200 ngx_sendmsg(ngx_connection_t *c, ngx_iovec_t *vec) | |
201 { | |
202 ssize_t n; | |
203 ngx_err_t err; | |
204 struct msghdr msg; | |
205 | |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
206 #if (NGX_HAVE_MSGHDR_MSG_CONTROL) |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
207 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
208 #if (NGX_HAVE_IP_SENDSRCADDR) |
7019 | 209 u_char msg_control[CMSG_SPACE(sizeof(struct in_addr))]; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
210 #elif (NGX_HAVE_IP_PKTINFO) |
7019 | 211 u_char msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))]; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
212 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
213 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
214 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
7019 | 215 u_char msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
216 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
217 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
218 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
219 |
6692 | 220 ngx_memzero(&msg, sizeof(struct msghdr)); |
221 | |
222 if (c->socklen) { | |
223 msg.msg_name = c->sockaddr; | |
224 msg.msg_namelen = c->socklen; | |
225 } | |
226 | |
227 msg.msg_iov = vec->iovs; | |
228 msg.msg_iovlen = vec->count; | |
229 | |
6980
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
230 #if (NGX_HAVE_MSGHDR_MSG_CONTROL) |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
231 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
232 if (c->listening && c->listening->wildcard && c->local_sockaddr) { |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
233 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
234 #if (NGX_HAVE_IP_SENDSRCADDR) |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
235 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
236 if (c->local_sockaddr->sa_family == AF_INET) { |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
237 struct cmsghdr *cmsg; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
238 struct in_addr *addr; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
239 struct sockaddr_in *sin; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
240 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
241 msg.msg_control = &msg_control; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
242 msg.msg_controllen = sizeof(msg_control); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
243 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
244 cmsg = CMSG_FIRSTHDR(&msg); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
245 cmsg->cmsg_level = IPPROTO_IP; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
246 cmsg->cmsg_type = IP_SENDSRCADDR; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
247 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
248 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
249 sin = (struct sockaddr_in *) c->local_sockaddr; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
250 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
251 addr = (struct in_addr *) CMSG_DATA(cmsg); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
252 *addr = sin->sin_addr; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
253 } |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
254 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
255 #elif (NGX_HAVE_IP_PKTINFO) |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
256 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
257 if (c->local_sockaddr->sa_family == AF_INET) { |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
258 struct cmsghdr *cmsg; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
259 struct in_pktinfo *pkt; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
260 struct sockaddr_in *sin; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
261 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
262 msg.msg_control = &msg_control; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
263 msg.msg_controllen = sizeof(msg_control); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
264 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
265 cmsg = CMSG_FIRSTHDR(&msg); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
266 cmsg->cmsg_level = IPPROTO_IP; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
267 cmsg->cmsg_type = IP_PKTINFO; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
268 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
269 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
270 sin = (struct sockaddr_in *) c->local_sockaddr; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
271 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
272 pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
273 ngx_memzero(pkt, sizeof(struct in_pktinfo)); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
274 pkt->ipi_spec_dst = sin->sin_addr; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
275 } |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
276 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
277 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
278 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
279 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
280 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
281 if (c->local_sockaddr->sa_family == AF_INET6) { |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
282 struct cmsghdr *cmsg; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
283 struct in6_pktinfo *pkt6; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
284 struct sockaddr_in6 *sin6; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
285 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
286 msg.msg_control = &msg_control6; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
287 msg.msg_controllen = sizeof(msg_control6); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
288 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
289 cmsg = CMSG_FIRSTHDR(&msg); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
290 cmsg->cmsg_level = IPPROTO_IPV6; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
291 cmsg->cmsg_type = IPV6_PKTINFO; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
292 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
293 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
294 sin6 = (struct sockaddr_in6 *) c->local_sockaddr; |
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 pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
297 ngx_memzero(pkt6, sizeof(struct in6_pktinfo)); |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
298 pkt6->ipi6_addr = sin6->sin6_addr; |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
299 } |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
300 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
301 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
302 } |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
303 |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
304 #endif |
dbb0c854e308
Set UDP datagram source address (ticket #1239).
Roman Arutyunyan <arut@nginx.com>
parents:
6692
diff
changeset
|
305 |
6692 | 306 eintr: |
307 | |
308 n = sendmsg(c->fd, &msg, 0); | |
309 | |
310 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
311 "sendmsg: %z of %uz", n, vec->size); | |
312 | |
313 if (n == -1) { | |
314 err = ngx_errno; | |
315 | |
316 switch (err) { | |
317 case NGX_EAGAIN: | |
318 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
319 "sendmsg() not ready"); | |
320 return NGX_AGAIN; | |
321 | |
322 case NGX_EINTR: | |
323 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
324 "sendmsg() was interrupted"); | |
325 goto eintr; | |
326 | |
327 default: | |
328 c->write->error = 1; | |
329 ngx_connection_error(c, err, "sendmsg() failed"); | |
330 return NGX_ERROR; | |
331 } | |
332 } | |
333 | |
334 return n; | |
335 } |