Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream_handler.c @ 8973:c6580dce98a8 quic
QUIC: fixed triggering stream read event (ticket #2409).
If a client packet carrying a stream data frame is not acked due to packet loss,
the stream data is retransmitted later by client. It's also possible that the
retransmitted range is bigger than before due to more stream data being
available by then. If the original data was read out by the application,
there would be no read event triggered by the retransmitted frame, even though
it contains new data.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 23 Nov 2022 18:50:26 +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 } |