Mercurial > hg > nginx-quic
annotate src/os/unix/ngx_linux_aio_read.c @ 4162:fb1375e8b68c stable-1.0
Merging r4036, r4055, r4056, r4057, r4058, r4059, r4060, r4061, r4062, r4063,
r4064:
Ranges related fixes:
The "max_ranges" directive.
"max_ranges 0" disables ranges support at all,
"max_ranges 1" allows the single range, etc.
By default number of ranges is unlimited, to be precise, 2^31-1.
If client requests more ranges than "max_ranges" permits,
nginx disables ranges and returns just the source response.
If total size of all ranges is greater than source response size,
then nginx disables ranges and returns just the source response.
This fix should not affect well-behaving applications but will defeat
DoS attempts exploiting malicious byte ranges.
Now unsatisfiable ranges are processed according to RFC 2616.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 30 Sep 2011 14:06:08 +0000 |
parents | 010a0907bc95 |
children | 6903dac6ad19 |
rev | line source |
---|---|
3052 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_event.h> | |
10 | |
11 | |
12 extern int ngx_eventfd; | |
13 extern aio_context_t ngx_aio_ctx; | |
14 | |
15 | |
16 static void ngx_file_aio_event_handler(ngx_event_t *ev); | |
17 | |
18 | |
19 static long | |
20 io_submit(aio_context_t ctx, long n, struct iocb **paiocb) | |
21 { | |
22 return syscall(SYS_io_submit, ctx, n, paiocb); | |
23 } | |
24 | |
25 | |
26 ssize_t | |
27 ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset, | |
28 ngx_pool_t *pool) | |
29 { | |
3294
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3052
diff
changeset
|
30 long n; |
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3052
diff
changeset
|
31 struct iocb *piocb[1]; |
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3052
diff
changeset
|
32 ngx_event_t *ev; |
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3052
diff
changeset
|
33 ngx_event_aio_t *aio; |
3052 | 34 |
3294
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3052
diff
changeset
|
35 if (!ngx_file_aio) { |
3052 | 36 return ngx_read_file(file, buf, size, offset); |
37 } | |
38 | |
39 aio = file->aio; | |
40 | |
41 if (aio == NULL) { | |
42 aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t)); | |
43 if (aio == NULL) { | |
44 return NGX_ERROR; | |
45 } | |
46 | |
47 aio->file = file; | |
48 aio->fd = file->fd; | |
49 aio->event.data = aio; | |
50 aio->event.ready = 1; | |
51 aio->event.log = file->log; | |
52 file->aio = aio; | |
53 } | |
54 | |
55 ev = &aio->event; | |
56 | |
57 if (!ev->ready) { | |
58 ngx_log_error(NGX_LOG_ALERT, file->log, 0, | |
59 "second aio post for \"%V\"", &file->name); | |
60 return NGX_AGAIN; | |
61 } | |
62 | |
63 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, | |
64 "aio complete:%d @%O:%z %V", | |
65 ev->complete, offset, size, &file->name); | |
66 | |
67 if (ev->complete) { | |
68 ev->active = 0; | |
69 ev->complete = 0; | |
70 | |
71 if (aio->res >= 0) { | |
72 ngx_set_errno(0); | |
73 return aio->res; | |
74 } | |
75 | |
76 ngx_set_errno(-aio->res); | |
4161 | 77 |
78 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, | |
79 "aio read \"%s\" failed", file->name.data); | |
80 | |
3052 | 81 return NGX_ERROR; |
82 } | |
83 | |
84 ngx_memzero(&aio->aiocb, sizeof(struct iocb)); | |
85 | |
86 aio->aiocb.aio_data = (uint64_t) (uintptr_t) ev; | |
87 aio->aiocb.aio_lio_opcode = IOCB_CMD_PREAD; | |
88 aio->aiocb.aio_fildes = file->fd; | |
89 aio->aiocb.aio_buf = (uint64_t) (uintptr_t) buf; | |
90 aio->aiocb.aio_nbytes = size; | |
91 aio->aiocb.aio_offset = offset; | |
92 aio->aiocb.aio_flags = IOCB_FLAG_RESFD; | |
93 aio->aiocb.aio_resfd = ngx_eventfd; | |
94 | |
95 ev->handler = ngx_file_aio_event_handler; | |
96 | |
97 piocb[0] = &aio->aiocb; | |
98 | |
99 n = io_submit(ngx_aio_ctx, 1, piocb); | |
100 | |
101 if (n == 1) { | |
3777
cd04f652478c
update event flags after successful io_submit()
Igor Sysoev <igor@sysoev.ru>
parents:
3294
diff
changeset
|
102 ev->active = 1; |
cd04f652478c
update event flags after successful io_submit()
Igor Sysoev <igor@sysoev.ru>
parents:
3294
diff
changeset
|
103 ev->ready = 0; |
cd04f652478c
update event flags after successful io_submit()
Igor Sysoev <igor@sysoev.ru>
parents:
3294
diff
changeset
|
104 ev->complete = 0; |
cd04f652478c
update event flags after successful io_submit()
Igor Sysoev <igor@sysoev.ru>
parents:
3294
diff
changeset
|
105 |
3052 | 106 return NGX_AGAIN; |
107 } | |
108 | |
109 n = -n; | |
110 | |
111 if (n == NGX_EAGAIN) { | |
112 return ngx_read_file(file, buf, size, offset); | |
113 } | |
114 | |
115 ngx_log_error(NGX_LOG_CRIT, file->log, n, | |
116 "io_submit(\"%V\") failed", &file->name); | |
117 | |
118 if (n == NGX_ENOSYS) { | |
3294
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3052
diff
changeset
|
119 ngx_file_aio = 0; |
3052 | 120 return ngx_read_file(file, buf, size, offset); |
121 } | |
122 | |
123 return NGX_ERROR; | |
124 } | |
125 | |
126 | |
127 static void | |
128 ngx_file_aio_event_handler(ngx_event_t *ev) | |
129 { | |
130 ngx_event_aio_t *aio; | |
131 | |
132 aio = ev->data; | |
133 | |
134 ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0, | |
135 "aio event handler fd:%d %V", aio->fd, &aio->file->name); | |
136 | |
137 aio->handler(ev); | |
138 } |