annotate src/os/unix/ngx_udp_send.c @ 7948:a2613fc1bce5

Fixed sendfile() limit handling on Linux. On Linux starting with 2.6.16, sendfile() silently limits all operations to MAX_RW_COUNT, defined as (INT_MAX & PAGE_MASK). This incorrectly triggered the interrupt check, and resulted in 0-sized writev() on the next loop iteration. Fix is to make sure the limit is always checked, so we will return from the loop if the limit is already reached even if number of bytes sent is not exactly equal to the number of bytes we've tried to send.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 29 Oct 2021 20:21:51 +0300
parents 8f038068f4bc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6436
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
1
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
2 /*
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
4 * Copyright (C) Nginx, Inc.
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
5 */
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
6
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
7
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
8 #include <ngx_config.h>
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
9 #include <ngx_core.h>
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
10 #include <ngx_event.h>
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
11
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
12
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
13 ssize_t
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
14 ngx_udp_unix_send(ngx_connection_t *c, u_char *buf, size_t size)
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
15 {
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
16 ssize_t n;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
17 ngx_err_t err;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
18 ngx_event_t *wev;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
19
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
20 wev = c->write;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
21
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
22 for ( ;; ) {
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
23 n = sendto(c->fd, buf, size, 0, c->sockaddr, c->socklen);
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
24
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
25 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
26 "sendto: fd:%d %z of %uz to \"%V\"",
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
27 c->fd, n, size, &c->addr_text);
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
28
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
29 if (n >= 0) {
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
30 if ((size_t) n != size) {
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
31 wev->error = 1;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
32 (void) ngx_connection_error(c, 0, "sendto() incomplete");
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
33 return NGX_ERROR;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
34 }
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
35
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
36 c->sent += n;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
37
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
38 return n;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
39 }
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
40
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
41 err = ngx_socket_errno;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
42
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
43 if (err == NGX_EAGAIN) {
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
44 wev->ready = 0;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
45 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, NGX_EAGAIN,
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
46 "sendto() not ready");
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
47 return NGX_AGAIN;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
48 }
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
49
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
50 if (err != NGX_EINTR) {
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
51 wev->error = 1;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
52 (void) ngx_connection_error(c, err, "sendto() failed");
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
53 return NGX_ERROR;
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
54 }
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
55 }
8f038068f4bc Stream: UDP proxy.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
56 }