Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream_handler.c @ 9082:c6db94ec3841 quic
QUIC: separated path validation retransmit backoff.
Path validation packets containing PATH_CHALLENGE frames are sent separately
from regular frame queue, because of the need to use a decicated path and pad
the packets. The packets are sent periodically, separately from the regular
probe/lost detection mechanism. A path validation packet is resent up to 3
times, each time after PTO expiration, with increasing per-path PTO backoff.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Tue, 09 May 2023 19:42:39 +0400 |
parents | 2706d27d2c76 |
children |
rev | line source |
---|---|
6115 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_event.h> | |
11 #include <ngx_stream.h> | |
12 | |
13 | |
6693 | 14 static void ngx_stream_log_session(ngx_stream_session_t *s); |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
15 static void ngx_stream_close_connection(ngx_connection_t *c); |
6115 | 16 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
17 static void ngx_stream_proxy_protocol_handler(ngx_event_t *rev); |
6115 | 18 |
19 | |
20 void | |
21 ngx_stream_init_connection(ngx_connection_t *c) | |
22 { | |
6175 | 23 u_char text[NGX_SOCKADDR_STRLEN]; |
24 size_t len; | |
25 ngx_uint_t i; | |
6669
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
26 ngx_time_t *tp; |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
27 ngx_event_t *rev; |
6175 | 28 struct sockaddr *sa; |
29 ngx_stream_port_t *port; | |
30 struct sockaddr_in *sin; | |
31 ngx_stream_in_addr_t *addr; | |
32 ngx_stream_session_t *s; | |
33 ngx_stream_addr_conf_t *addr_conf; | |
6115 | 34 #if (NGX_HAVE_INET6) |
6175 | 35 struct sockaddr_in6 *sin6; |
36 ngx_stream_in6_addr_t *addr6; | |
6115 | 37 #endif |
6175 | 38 ngx_stream_core_srv_conf_t *cscf; |
39 ngx_stream_core_main_conf_t *cmcf; | |
6115 | 40 |
41 /* find the server configuration for the address:port */ | |
42 | |
43 port = c->listening->servers; | |
44 | |
45 if (port->naddrs > 1) { | |
46 | |
47 /* | |
48 * There are several addresses on this port and one of them | |
49 * is the "*:port" wildcard so getsockname() is needed to determine | |
50 * the server address. | |
51 * | |
6436 | 52 * AcceptEx() and recvmsg() already gave this address. |
6115 | 53 */ |
54 | |
55 if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { | |
56 ngx_stream_close_connection(c); | |
57 return; | |
58 } | |
59 | |
60 sa = c->local_sockaddr; | |
61 | |
62 switch (sa->sa_family) { | |
63 | |
64 #if (NGX_HAVE_INET6) | |
65 case AF_INET6: | |
66 sin6 = (struct sockaddr_in6 *) sa; | |
67 | |
68 addr6 = port->addrs; | |
69 | |
70 /* the last address is "*" */ | |
71 | |
72 for (i = 0; i < port->naddrs - 1; i++) { | |
73 if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) { | |
74 break; | |
75 } | |
76 } | |
77 | |
78 addr_conf = &addr6[i].conf; | |
79 | |
80 break; | |
81 #endif | |
82 | |
83 default: /* AF_INET */ | |
84 sin = (struct sockaddr_in *) sa; | |
85 | |
86 addr = port->addrs; | |
87 | |
88 /* the last address is "*" */ | |
89 | |
90 for (i = 0; i < port->naddrs - 1; i++) { | |
91 if (addr[i].addr == sin->sin_addr.s_addr) { | |
92 break; | |
93 } | |
94 } | |
95 | |
96 addr_conf = &addr[i].conf; | |
97 | |
98 break; | |
99 } | |
100 | |
101 } else { | |
102 switch (c->local_sockaddr->sa_family) { | |
103 | |
104 #if (NGX_HAVE_INET6) | |
105 case AF_INET6: | |
106 addr6 = port->addrs; | |
107 addr_conf = &addr6[0].conf; | |
108 break; | |
109 #endif | |
110 | |
111 default: /* AF_INET */ | |
112 addr = port->addrs; | |
113 addr_conf = &addr[0].conf; | |
114 break; | |
115 } | |
116 } | |
117 | |
118 s = ngx_pcalloc(c->pool, sizeof(ngx_stream_session_t)); | |
119 if (s == NULL) { | |
120 ngx_stream_close_connection(c); | |
121 return; | |
122 } | |
123 | |
124 s->signature = NGX_STREAM_MODULE; | |
125 s->main_conf = addr_conf->ctx->main_conf; | |
126 s->srv_conf = addr_conf->ctx->srv_conf; | |
127 | |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
128 #if (NGX_STREAM_SSL) |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
129 s->ssl = addr_conf->ssl; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
130 #endif |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
131 |
8506
e96c20b6f655
QUIC: fixed client certificates verification in stream.
Vladimir Homutov <vl@nginx.com>
parents:
8200
diff
changeset
|
132 #if (NGX_STREAM_QUIC) |
e96c20b6f655
QUIC: fixed client certificates verification in stream.
Vladimir Homutov <vl@nginx.com>
parents:
8200
diff
changeset
|
133 s->ssl |= addr_conf->quic; |
e96c20b6f655
QUIC: fixed client certificates verification in stream.
Vladimir Homutov <vl@nginx.com>
parents:
8200
diff
changeset
|
134 #endif |
e96c20b6f655
QUIC: fixed client certificates verification in stream.
Vladimir Homutov <vl@nginx.com>
parents:
8200
diff
changeset
|
135 |
6692 | 136 if (c->buffer) { |
137 s->received += c->buffer->last - c->buffer->pos; | |
138 } | |
139 | |
6115 | 140 s->connection = c; |
141 c->data = s; | |
142 | |
143 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
144 | |
6129
187aa751ad62
Core: the ngx_set_connection_log() macro.
Vladimir Homutov <vl@nginx.com>
parents:
6115
diff
changeset
|
145 ngx_set_connection_log(c, cscf->error_log); |
6115 | 146 |
147 len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1); | |
148 | |
6461
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
149 ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA %sclient %*s connected to %V", |
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
150 c->number, c->type == SOCK_DGRAM ? "udp " : "", |
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
151 len, text, &addr_conf->addr_text); |
6115 | 152 |
153 c->log->connection = c->number; | |
154 c->log->handler = ngx_stream_log_error; | |
155 c->log->data = s; | |
6693 | 156 c->log->action = "initializing session"; |
6115 | 157 c->log_error = NGX_ERROR_INFO; |
158 | |
6682
db422604ceb0
Stream: allow using the session context inside handlers.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6680
diff
changeset
|
159 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module); |
db422604ceb0
Stream: allow using the session context inside handlers.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6680
diff
changeset
|
160 if (s->ctx == NULL) { |
db422604ceb0
Stream: allow using the session context inside handlers.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6680
diff
changeset
|
161 ngx_stream_close_connection(c); |
db422604ceb0
Stream: allow using the session context inside handlers.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6680
diff
changeset
|
162 return; |
db422604ceb0
Stream: allow using the session context inside handlers.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6680
diff
changeset
|
163 } |
db422604ceb0
Stream: allow using the session context inside handlers.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6680
diff
changeset
|
164 |
6175 | 165 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); |
166 | |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
167 s->variables = ngx_pcalloc(s->connection->pool, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
168 cmcf->variables.nelts |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
169 * sizeof(ngx_stream_variable_value_t)); |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
170 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
171 if (s->variables == NULL) { |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
172 ngx_stream_close_connection(c); |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
173 return; |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
174 } |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
175 |
6669
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
176 tp = ngx_timeofday(); |
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
177 s->start_sec = tp->sec; |
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
178 s->start_msec = tp->msec; |
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
179 |
8634
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
180 #if (NGX_STREAM_QUIC) |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
181 |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
182 if (addr_conf->quic) { |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
183 ngx_quic_conf_t *qcf; |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
184 |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
185 if (c->quic == NULL) { |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
186 qcf = ngx_stream_get_module_srv_conf(addr_conf->ctx, |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
187 ngx_stream_quic_module); |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
188 ngx_quic_run(c, qcf); |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
189 return; |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
190 } |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
191 } |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
192 |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
193 #endif |
2706d27d2c76
Stream: fixed segfault when using SSL certificates with variables.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8506
diff
changeset
|
194 |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
195 rev = c->read; |
6693 | 196 rev->handler = ngx_stream_session_handler; |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
197 |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
198 if (addr_conf->proxy_protocol) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
199 c->log->action = "reading PROXY protocol"; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
200 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
201 rev->handler = ngx_stream_proxy_protocol_handler; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
202 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
203 if (!rev->ready) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
204 ngx_add_timer(rev, cscf->proxy_protocol_timeout); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
205 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
206 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
207 ngx_stream_finalize_session(s, |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
208 NGX_STREAM_INTERNAL_SERVER_ERROR); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
209 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
210 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
211 return; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
212 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
213 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
214 |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
215 if (ngx_use_accept_mutex) { |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
216 ngx_post_event(rev, &ngx_posted_events); |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
217 return; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
218 } |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
219 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
220 rev->handler(rev); |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
221 } |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
222 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
223 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
224 static void |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
225 ngx_stream_proxy_protocol_handler(ngx_event_t *rev) |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
226 { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
227 u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
228 size_t size; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
229 ssize_t n; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
230 ngx_err_t err; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
231 ngx_connection_t *c; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
232 ngx_stream_session_t *s; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
233 ngx_stream_core_srv_conf_t *cscf; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
234 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
235 c = rev->data; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
236 s = c->data; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
237 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
238 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
239 "stream PROXY protocol handler"); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
240 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
241 if (rev->timedout) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
242 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
243 ngx_stream_finalize_session(s, NGX_STREAM_OK); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
244 return; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
245 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
246 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
247 n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
248 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
249 err = ngx_socket_errno; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
250 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
251 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "recv(): %z", n); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
252 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
253 if (n == -1) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
254 if (err == NGX_EAGAIN) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
255 rev->ready = 0; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
256 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
257 if (!rev->timer_set) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
258 cscf = ngx_stream_get_module_srv_conf(s, |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
259 ngx_stream_core_module); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
260 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
261 ngx_add_timer(rev, cscf->proxy_protocol_timeout); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
262 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
263 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
264 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
265 ngx_stream_finalize_session(s, |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
266 NGX_STREAM_INTERNAL_SERVER_ERROR); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
267 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
268 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
269 return; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
270 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
271 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
272 ngx_connection_error(c, err, "recv() failed"); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
273 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
274 ngx_stream_finalize_session(s, NGX_STREAM_OK); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
275 return; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
276 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
277 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
278 if (rev->timer_set) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
279 ngx_del_timer(rev); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
280 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
281 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
282 p = ngx_proxy_protocol_read(c, buf, buf + n); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
283 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
284 if (p == NULL) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
285 ngx_stream_finalize_session(s, NGX_STREAM_BAD_REQUEST); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
286 return; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
287 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
288 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
289 size = p - buf; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
290 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
291 if (c->recv(c, buf, size) != (ssize_t) size) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
292 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
293 return; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
294 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
295 |
6693 | 296 c->log->action = "initializing session"; |
297 | |
298 ngx_stream_session_handler(rev); | |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
299 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
300 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6679
diff
changeset
|
301 |
6693 | 302 void |
303 ngx_stream_session_handler(ngx_event_t *rev) | |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
304 { |
6693 | 305 ngx_connection_t *c; |
306 ngx_stream_session_t *s; | |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
307 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
308 c = rev->data; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
309 s = c->data; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
310 |
6693 | 311 ngx_stream_core_run_phases(s); |
6115 | 312 } |
313 | |
314 | |
315 void | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
316 ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc) |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
317 { |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
318 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
319 "finalize stream session: %i", rc); |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
320 |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
321 s->status = rc; |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
322 |
6693 | 323 ngx_stream_log_session(s); |
324 | |
325 ngx_stream_close_connection(s->connection); | |
326 } | |
327 | |
328 | |
329 static void | |
330 ngx_stream_log_session(ngx_stream_session_t *s) | |
331 { | |
332 ngx_uint_t i, n; | |
333 ngx_stream_handler_pt *log_handler; | |
334 ngx_stream_core_main_conf_t *cmcf; | |
335 | |
6678 | 336 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); |
337 | |
6693 | 338 log_handler = cmcf->phases[NGX_STREAM_LOG_PHASE].handlers.elts; |
339 n = cmcf->phases[NGX_STREAM_LOG_PHASE].handlers.nelts; | |
340 | |
341 for (i = 0; i < n; i++) { | |
342 log_handler[i](s); | |
6678 | 343 } |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
344 } |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
345 |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
346 |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
347 static void |
6115 | 348 ngx_stream_close_connection(ngx_connection_t *c) |
349 { | |
350 ngx_pool_t *pool; | |
351 | |
352 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, | |
353 "close stream connection: %d", c->fd); | |
354 | |
355 #if (NGX_STREAM_SSL) | |
356 | |
357 if (c->ssl) { | |
358 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
359 c->ssl->handler = ngx_stream_close_connection; | |
360 return; | |
361 } | |
362 } | |
363 | |
364 #endif | |
365 | |
366 #if (NGX_STAT_STUB) | |
367 (void) ngx_atomic_fetch_add(ngx_stat_active, -1); | |
368 #endif | |
369 | |
370 pool = c->pool; | |
371 | |
372 ngx_close_connection(c); | |
373 | |
374 ngx_destroy_pool(pool); | |
375 } | |
376 | |
377 | |
378 static u_char * | |
379 ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len) | |
380 { | |
381 u_char *p; | |
382 ngx_stream_session_t *s; | |
383 | |
384 if (log->action) { | |
385 p = ngx_snprintf(buf, len, " while %s", log->action); | |
386 len -= p - buf; | |
387 buf = p; | |
388 } | |
389 | |
390 s = log->data; | |
391 | |
6461
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
392 p = ngx_snprintf(buf, len, ", %sclient: %V, server: %V", |
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
393 s->connection->type == SOCK_DGRAM ? "udp " : "", |
6115 | 394 &s->connection->addr_text, |
395 &s->connection->listening->addr_text); | |
6223
d1f94042c29c
Stream: fixed potential error log buffer overrun.
Vladimir Homutov <vl@nginx.com>
parents:
6221
diff
changeset
|
396 len -= p - buf; |
d1f94042c29c
Stream: fixed potential error log buffer overrun.
Vladimir Homutov <vl@nginx.com>
parents:
6221
diff
changeset
|
397 buf = p; |
6115 | 398 |
399 if (s->log_handler) { | |
6223
d1f94042c29c
Stream: fixed potential error log buffer overrun.
Vladimir Homutov <vl@nginx.com>
parents:
6221
diff
changeset
|
400 p = s->log_handler(log, buf, len); |
6115 | 401 } |
402 | |
403 return p; | |
404 } |