Mercurial > hg > nginx
annotate src/stream/ngx_stream_ssl_preread_module.c @ 7349:f6047a579ca1
gRPC: improved keepalive handling.
The code is now able to parse additional control frames after
the response is received, and can send control frames as well.
This fixes keepalive problems as observed with grpc-c, which can
send window update and ping frames after the response, see
http://mailman.nginx.org/pipermail/nginx/2018-August/056620.html.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 03 Sep 2018 19:34:01 +0300 |
parents | 6649d4433266 |
children |
rev | line source |
---|---|
6695 | 1 |
2 /* | |
3 * Copyright (C) Nginx, Inc. | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_stream.h> | |
10 | |
11 | |
12 typedef struct { | |
13 ngx_flag_t enabled; | |
14 } ngx_stream_ssl_preread_srv_conf_t; | |
15 | |
16 | |
17 typedef struct { | |
18 size_t left; | |
19 size_t size; | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
20 size_t ext; |
6695 | 21 u_char *pos; |
22 u_char *dst; | |
23 u_char buf[4]; | |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
24 u_char version[2]; |
6695 | 25 ngx_str_t host; |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
26 ngx_str_t alpn; |
6695 | 27 ngx_log_t *log; |
28 ngx_pool_t *pool; | |
29 ngx_uint_t state; | |
30 } ngx_stream_ssl_preread_ctx_t; | |
31 | |
32 | |
33 static ngx_int_t ngx_stream_ssl_preread_handler(ngx_stream_session_t *s); | |
34 static ngx_int_t ngx_stream_ssl_preread_parse_record( | |
35 ngx_stream_ssl_preread_ctx_t *ctx, u_char *pos, u_char *last); | |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
36 static ngx_int_t ngx_stream_ssl_preread_protocol_variable( |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
37 ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); |
6695 | 38 static ngx_int_t ngx_stream_ssl_preread_server_name_variable( |
39 ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
40 static ngx_int_t ngx_stream_ssl_preread_alpn_protocols_variable( |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
41 ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); |
6695 | 42 static ngx_int_t ngx_stream_ssl_preread_add_variables(ngx_conf_t *cf); |
43 static void *ngx_stream_ssl_preread_create_srv_conf(ngx_conf_t *cf); | |
44 static char *ngx_stream_ssl_preread_merge_srv_conf(ngx_conf_t *cf, void *parent, | |
45 void *child); | |
46 static ngx_int_t ngx_stream_ssl_preread_init(ngx_conf_t *cf); | |
47 | |
48 | |
49 static ngx_command_t ngx_stream_ssl_preread_commands[] = { | |
50 | |
51 { ngx_string("ssl_preread"), | |
52 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, | |
53 ngx_conf_set_flag_slot, | |
54 NGX_STREAM_SRV_CONF_OFFSET, | |
55 offsetof(ngx_stream_ssl_preread_srv_conf_t, enabled), | |
56 NULL }, | |
57 | |
58 ngx_null_command | |
59 }; | |
60 | |
61 | |
62 static ngx_stream_module_t ngx_stream_ssl_preread_module_ctx = { | |
63 ngx_stream_ssl_preread_add_variables, /* preconfiguration */ | |
64 ngx_stream_ssl_preread_init, /* postconfiguration */ | |
65 | |
66 NULL, /* create main configuration */ | |
67 NULL, /* init main configuration */ | |
68 | |
69 ngx_stream_ssl_preread_create_srv_conf, /* create server configuration */ | |
70 ngx_stream_ssl_preread_merge_srv_conf /* merge server configuration */ | |
71 }; | |
72 | |
73 | |
74 ngx_module_t ngx_stream_ssl_preread_module = { | |
75 NGX_MODULE_V1, | |
76 &ngx_stream_ssl_preread_module_ctx, /* module context */ | |
77 ngx_stream_ssl_preread_commands, /* module directives */ | |
78 NGX_STREAM_MODULE, /* module type */ | |
79 NULL, /* init master */ | |
80 NULL, /* init module */ | |
81 NULL, /* init process */ | |
82 NULL, /* init thread */ | |
83 NULL, /* exit thread */ | |
84 NULL, /* exit process */ | |
85 NULL, /* exit master */ | |
86 NGX_MODULE_V1_PADDING | |
87 }; | |
88 | |
89 | |
90 static ngx_stream_variable_t ngx_stream_ssl_preread_vars[] = { | |
91 | |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
92 { ngx_string("ssl_preread_protocol"), NULL, |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
93 ngx_stream_ssl_preread_protocol_variable, 0, 0, 0 }, |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
94 |
6695 | 95 { ngx_string("ssl_preread_server_name"), NULL, |
96 ngx_stream_ssl_preread_server_name_variable, 0, 0, 0 }, | |
97 | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
98 { ngx_string("ssl_preread_alpn_protocols"), NULL, |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
99 ngx_stream_ssl_preread_alpn_protocols_variable, 0, 0, 0 }, |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
100 |
7077
2a288909abc6
Variables: macros for null variables.
Ruslan Ermilov <ru@nginx.com>
parents:
6849
diff
changeset
|
101 ngx_stream_null_variable |
6695 | 102 }; |
103 | |
104 | |
105 static ngx_int_t | |
106 ngx_stream_ssl_preread_handler(ngx_stream_session_t *s) | |
107 { | |
108 u_char *last, *p; | |
109 size_t len; | |
110 ngx_int_t rc; | |
111 ngx_connection_t *c; | |
112 ngx_stream_ssl_preread_ctx_t *ctx; | |
113 ngx_stream_ssl_preread_srv_conf_t *sscf; | |
114 | |
115 c = s->connection; | |
116 | |
117 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "ssl preread handler"); | |
118 | |
119 sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_preread_module); | |
120 | |
121 if (!sscf->enabled) { | |
122 return NGX_DECLINED; | |
123 } | |
124 | |
125 if (c->type != SOCK_STREAM) { | |
126 return NGX_DECLINED; | |
127 } | |
128 | |
129 if (c->buffer == NULL) { | |
130 return NGX_AGAIN; | |
131 } | |
132 | |
133 ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module); | |
134 if (ctx == NULL) { | |
135 ctx = ngx_pcalloc(c->pool, sizeof(ngx_stream_ssl_preread_ctx_t)); | |
136 if (ctx == NULL) { | |
137 return NGX_ERROR; | |
138 } | |
139 | |
140 ngx_stream_set_ctx(s, ctx, ngx_stream_ssl_preread_module); | |
141 | |
142 ctx->pool = c->pool; | |
143 ctx->log = c->log; | |
144 ctx->pos = c->buffer->pos; | |
145 } | |
146 | |
147 p = ctx->pos; | |
148 last = c->buffer->last; | |
149 | |
150 while (last - p >= 5) { | |
151 | |
7322
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
152 if ((p[0] & 0x80) && p[2] == 1 && (p[3] == 0 || p[3] == 3)) { |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
153 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
154 "ssl preread: version 2 ClientHello"); |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
155 ctx->version[0] = p[3]; |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
156 ctx->version[1] = p[4]; |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
157 return NGX_OK; |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
158 } |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
159 |
6695 | 160 if (p[0] != 0x16) { |
6696
e83540f825cd
Stream ssl_preread: removed internal macro.
Vladimir Homutov <vl@nginx.com>
parents:
6695
diff
changeset
|
161 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
e83540f825cd
Stream ssl_preread: removed internal macro.
Vladimir Homutov <vl@nginx.com>
parents:
6695
diff
changeset
|
162 "ssl preread: not a handshake"); |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
163 ngx_stream_set_ctx(s, NULL, ngx_stream_ssl_preread_module); |
6695 | 164 return NGX_DECLINED; |
165 } | |
166 | |
6849
01adb18a5d23
Stream ssl_preread: relaxed SSL version check.
Roman Arutyunyan <arut@nginx.com>
parents:
6728
diff
changeset
|
167 if (p[1] != 3) { |
6696
e83540f825cd
Stream ssl_preread: removed internal macro.
Vladimir Homutov <vl@nginx.com>
parents:
6695
diff
changeset
|
168 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
e83540f825cd
Stream ssl_preread: removed internal macro.
Vladimir Homutov <vl@nginx.com>
parents:
6695
diff
changeset
|
169 "ssl preread: unsupported SSL version"); |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
170 ngx_stream_set_ctx(s, NULL, ngx_stream_ssl_preread_module); |
6695 | 171 return NGX_DECLINED; |
172 } | |
173 | |
174 len = (p[3] << 8) + p[4]; | |
175 | |
176 /* read the whole record before parsing */ | |
177 if ((size_t) (last - p) < len + 5) { | |
178 break; | |
179 } | |
180 | |
181 p += 5; | |
182 | |
183 rc = ngx_stream_ssl_preread_parse_record(ctx, p, p + len); | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
184 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
185 if (rc == NGX_DECLINED) { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
186 ngx_stream_set_ctx(s, NULL, ngx_stream_ssl_preread_module); |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
187 return NGX_DECLINED; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
188 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
189 |
6695 | 190 if (rc != NGX_AGAIN) { |
191 return rc; | |
192 } | |
193 | |
194 p += len; | |
195 } | |
196 | |
197 ctx->pos = p; | |
198 | |
199 return NGX_AGAIN; | |
200 } | |
201 | |
202 | |
203 static ngx_int_t | |
204 ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx, | |
205 u_char *pos, u_char *last) | |
206 { | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
207 size_t left, n, size, ext; |
6695 | 208 u_char *dst, *p; |
209 | |
210 enum { | |
211 sw_start = 0, | |
212 sw_header, /* handshake msg_type, length */ | |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
213 sw_version, /* client_version */ |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
214 sw_random, /* random */ |
6695 | 215 sw_sid_len, /* session_id length */ |
216 sw_sid, /* session_id */ | |
217 sw_cs_len, /* cipher_suites length */ | |
218 sw_cs, /* cipher_suites */ | |
219 sw_cm_len, /* compression_methods length */ | |
220 sw_cm, /* compression_methods */ | |
221 sw_ext, /* extension */ | |
222 sw_ext_header, /* extension_type, extension_data length */ | |
223 sw_sni_len, /* SNI length */ | |
224 sw_sni_host_head, /* SNI name_type, host_name length */ | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
225 sw_sni_host, /* SNI host_name */ |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
226 sw_alpn_len, /* ALPN length */ |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
227 sw_alpn_proto_len, /* ALPN protocol_name length */ |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
228 sw_alpn_proto_data, /* ALPN protocol_name */ |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
229 sw_supver_len /* supported_versions length */ |
6695 | 230 } state; |
231 | |
232 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, ctx->log, 0, | |
233 "ssl preread: state %ui left %z", ctx->state, ctx->left); | |
234 | |
235 state = ctx->state; | |
236 size = ctx->size; | |
237 left = ctx->left; | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
238 ext = ctx->ext; |
6695 | 239 dst = ctx->dst; |
240 p = ctx->buf; | |
241 | |
242 for ( ;; ) { | |
243 n = ngx_min((size_t) (last - pos), size); | |
244 | |
245 if (dst) { | |
246 dst = ngx_cpymem(dst, pos, n); | |
247 } | |
248 | |
249 pos += n; | |
250 size -= n; | |
251 left -= n; | |
252 | |
253 if (size != 0) { | |
254 break; | |
255 } | |
256 | |
257 switch (state) { | |
258 | |
259 case sw_start: | |
260 state = sw_header; | |
261 dst = p; | |
262 size = 4; | |
263 left = size; | |
264 break; | |
265 | |
266 case sw_header: | |
267 if (p[0] != 1) { | |
6696
e83540f825cd
Stream ssl_preread: removed internal macro.
Vladimir Homutov <vl@nginx.com>
parents:
6695
diff
changeset
|
268 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
e83540f825cd
Stream ssl_preread: removed internal macro.
Vladimir Homutov <vl@nginx.com>
parents:
6695
diff
changeset
|
269 "ssl preread: not a client hello"); |
6695 | 270 return NGX_DECLINED; |
271 } | |
272 | |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
273 state = sw_version; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
274 dst = ctx->version; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
275 size = 2; |
6695 | 276 left = (p[1] << 16) + (p[2] << 8) + p[3]; |
277 break; | |
278 | |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
279 case sw_version: |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
280 state = sw_random; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
281 dst = NULL; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
282 size = 32; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
283 break; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
284 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
285 case sw_random: |
6695 | 286 state = sw_sid_len; |
287 dst = p; | |
288 size = 1; | |
289 break; | |
290 | |
291 case sw_sid_len: | |
292 state = sw_sid; | |
293 dst = NULL; | |
294 size = p[0]; | |
295 break; | |
296 | |
297 case sw_sid: | |
298 state = sw_cs_len; | |
299 dst = p; | |
300 size = 2; | |
301 break; | |
302 | |
303 case sw_cs_len: | |
304 state = sw_cs; | |
305 dst = NULL; | |
306 size = (p[0] << 8) + p[1]; | |
307 break; | |
308 | |
309 case sw_cs: | |
310 state = sw_cm_len; | |
311 dst = p; | |
312 size = 1; | |
313 break; | |
314 | |
315 case sw_cm_len: | |
316 state = sw_cm; | |
317 dst = NULL; | |
318 size = p[0]; | |
319 break; | |
320 | |
321 case sw_cm: | |
322 if (left == 0) { | |
323 /* no extensions */ | |
324 return NGX_OK; | |
325 } | |
326 | |
327 state = sw_ext; | |
328 dst = p; | |
329 size = 2; | |
330 break; | |
331 | |
332 case sw_ext: | |
333 if (left == 0) { | |
334 return NGX_OK; | |
335 } | |
336 | |
337 state = sw_ext_header; | |
338 dst = p; | |
339 size = 4; | |
340 break; | |
341 | |
342 case sw_ext_header: | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
343 if (p[0] == 0 && p[1] == 0 && ctx->host.data == NULL) { |
6695 | 344 /* SNI extension */ |
345 state = sw_sni_len; | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
346 dst = p; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
347 size = 2; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
348 break; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
349 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
350 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
351 if (p[0] == 0 && p[1] == 16 && ctx->alpn.data == NULL) { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
352 /* ALPN extension */ |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
353 state = sw_alpn_len; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
354 dst = p; |
6695 | 355 size = 2; |
356 break; | |
357 } | |
358 | |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
359 if (p[0] == 0 && p[1] == 43) { |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
360 /* supported_versions extension */ |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
361 state = sw_supver_len; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
362 dst = p; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
363 size = 1; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
364 break; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
365 } |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
366 |
6695 | 367 state = sw_ext; |
368 dst = NULL; | |
369 size = (p[2] << 8) + p[3]; | |
370 break; | |
371 | |
372 case sw_sni_len: | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
373 ext = (p[0] << 8) + p[1]; |
6695 | 374 state = sw_sni_host_head; |
375 dst = p; | |
376 size = 3; | |
377 break; | |
378 | |
379 case sw_sni_host_head: | |
380 if (p[0] != 0) { | |
381 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, | |
382 "ssl preread: SNI hostname type is not DNS"); | |
383 return NGX_DECLINED; | |
384 } | |
385 | |
386 size = (p[1] << 8) + p[2]; | |
387 | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
388 if (ext < 3 + size) { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
389 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
390 "ssl preread: SNI format error"); |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
391 return NGX_DECLINED; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
392 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
393 ext -= 3 + size; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
394 |
6695 | 395 ctx->host.data = ngx_pnalloc(ctx->pool, size); |
396 if (ctx->host.data == NULL) { | |
397 return NGX_ERROR; | |
398 } | |
399 | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
400 state = sw_sni_host; |
6695 | 401 dst = ctx->host.data; |
402 break; | |
403 | |
404 case sw_sni_host: | |
6728
8f75d9883730
Stream ssl_preread: fixed $ssl_preread_server_name variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6696
diff
changeset
|
405 ctx->host.len = (p[1] << 8) + p[2]; |
8f75d9883730
Stream ssl_preread: fixed $ssl_preread_server_name variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6696
diff
changeset
|
406 |
6695 | 407 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
408 "ssl preread: SNI hostname \"%V\"", &ctx->host); | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
409 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
410 state = sw_ext; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
411 dst = NULL; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
412 size = ext; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
413 break; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
414 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
415 case sw_alpn_len: |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
416 ext = (p[0] << 8) + p[1]; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
417 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
418 ctx->alpn.data = ngx_pnalloc(ctx->pool, ext); |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
419 if (ctx->alpn.data == NULL) { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
420 return NGX_ERROR; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
421 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
422 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
423 state = sw_alpn_proto_len; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
424 dst = p; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
425 size = 1; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
426 break; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
427 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
428 case sw_alpn_proto_len: |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
429 size = p[0]; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
430 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
431 if (size == 0) { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
432 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
433 "ssl preread: ALPN empty protocol"); |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
434 return NGX_DECLINED; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
435 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
436 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
437 if (ext < 1 + size) { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
438 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
439 "ssl preread: ALPN format error"); |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
440 return NGX_DECLINED; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
441 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
442 ext -= 1 + size; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
443 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
444 state = sw_alpn_proto_data; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
445 dst = ctx->alpn.data + ctx->alpn.len; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
446 break; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
447 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
448 case sw_alpn_proto_data: |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
449 ctx->alpn.len += p[0]; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
450 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
451 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
452 "ssl preread: ALPN protocols \"%V\"", &ctx->alpn); |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
453 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
454 if (ext) { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
455 ctx->alpn.data[ctx->alpn.len++] = ','; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
456 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
457 state = sw_alpn_proto_len; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
458 dst = p; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
459 size = 1; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
460 break; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
461 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
462 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
463 state = sw_ext; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
464 dst = NULL; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
465 size = 0; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
466 break; |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
467 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
468 case sw_supver_len: |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
469 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
470 "ssl preread: supported_versions"); |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
471 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
472 /* set TLSv1.3 */ |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
473 ctx->version[0] = 3; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
474 ctx->version[1] = 4; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
475 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
476 state = sw_ext; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
477 dst = NULL; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
478 size = p[0]; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
479 break; |
6695 | 480 } |
481 | |
482 if (left < size) { | |
7228 | 483 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, |
484 "ssl preread: failed to parse handshake"); | |
485 return NGX_DECLINED; | |
6695 | 486 } |
487 } | |
488 | |
489 ctx->state = state; | |
490 ctx->size = size; | |
491 ctx->left = left; | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
492 ctx->ext = ext; |
6695 | 493 ctx->dst = dst; |
494 | |
495 return NGX_AGAIN; | |
496 } | |
497 | |
498 | |
499 static ngx_int_t | |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
500 ngx_stream_ssl_preread_protocol_variable(ngx_stream_session_t *s, |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
501 ngx_variable_value_t *v, uintptr_t data) |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
502 { |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
503 ngx_str_t version; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
504 ngx_stream_ssl_preread_ctx_t *ctx; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
505 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
506 ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module); |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
507 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
508 if (ctx == NULL) { |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
509 v->not_found = 1; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
510 return NGX_OK; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
511 } |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
512 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
513 /* SSL_get_version() format */ |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
514 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
515 ngx_str_null(&version); |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
516 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
517 switch (ctx->version[0]) { |
7322
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
518 case 0: |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
519 switch (ctx->version[1]) { |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
520 case 2: |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
521 ngx_str_set(&version, "SSLv2"); |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
522 break; |
6649d4433266
Stream ssl_preread: added SSLv2 Client Hello support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7314
diff
changeset
|
523 } |
7314
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
524 break; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
525 case 3: |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
526 switch (ctx->version[1]) { |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
527 case 0: |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
528 ngx_str_set(&version, "SSLv3"); |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
529 break; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
530 case 1: |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
531 ngx_str_set(&version, "TLSv1"); |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
532 break; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
533 case 2: |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
534 ngx_str_set(&version, "TLSv1.1"); |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
535 break; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
536 case 3: |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
537 ngx_str_set(&version, "TLSv1.2"); |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
538 break; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
539 case 4: |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
540 ngx_str_set(&version, "TLSv1.3"); |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
541 break; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
542 } |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
543 } |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
544 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
545 v->valid = 1; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
546 v->no_cacheable = 0; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
547 v->not_found = 0; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
548 v->len = version.len; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
549 v->data = version.data; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
550 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
551 return NGX_OK; |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
552 } |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
553 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
554 |
3dfc1584ad75
Stream ssl_preread: $ssl_preread_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7228
diff
changeset
|
555 static ngx_int_t |
6695 | 556 ngx_stream_ssl_preread_server_name_variable(ngx_stream_session_t *s, |
557 ngx_variable_value_t *v, uintptr_t data) | |
558 { | |
559 ngx_stream_ssl_preread_ctx_t *ctx; | |
560 | |
561 ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module); | |
562 | |
563 if (ctx == NULL) { | |
564 v->not_found = 1; | |
565 return NGX_OK; | |
566 } | |
567 | |
568 v->valid = 1; | |
569 v->no_cacheable = 0; | |
570 v->not_found = 0; | |
571 v->len = ctx->host.len; | |
572 v->data = ctx->host.data; | |
573 | |
574 return NGX_OK; | |
575 } | |
576 | |
577 | |
578 static ngx_int_t | |
7227
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
579 ngx_stream_ssl_preread_alpn_protocols_variable(ngx_stream_session_t *s, |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
580 ngx_variable_value_t *v, uintptr_t data) |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
581 { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
582 ngx_stream_ssl_preread_ctx_t *ctx; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
583 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
584 ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module); |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
585 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
586 if (ctx == NULL) { |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
587 v->not_found = 1; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
588 return NGX_OK; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
589 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
590 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
591 v->valid = 1; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
592 v->no_cacheable = 0; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
593 v->not_found = 0; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
594 v->len = ctx->alpn.len; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
595 v->data = ctx->alpn.data; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
596 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
597 return NGX_OK; |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
598 } |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
599 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
600 |
79eb4f7b6725
Stream ssl_preread: $ssl_preread_alpn_protocols variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7077
diff
changeset
|
601 static ngx_int_t |
6695 | 602 ngx_stream_ssl_preread_add_variables(ngx_conf_t *cf) |
603 { | |
604 ngx_stream_variable_t *var, *v; | |
605 | |
606 for (v = ngx_stream_ssl_preread_vars; v->name.len; v++) { | |
607 var = ngx_stream_add_variable(cf, &v->name, v->flags); | |
608 if (var == NULL) { | |
609 return NGX_ERROR; | |
610 } | |
611 | |
612 var->get_handler = v->get_handler; | |
613 var->data = v->data; | |
614 } | |
615 | |
616 return NGX_OK; | |
617 } | |
618 | |
619 | |
620 static void * | |
621 ngx_stream_ssl_preread_create_srv_conf(ngx_conf_t *cf) | |
622 { | |
623 ngx_stream_ssl_preread_srv_conf_t *conf; | |
624 | |
625 conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_ssl_preread_srv_conf_t)); | |
626 if (conf == NULL) { | |
627 return NULL; | |
628 } | |
629 | |
630 conf->enabled = NGX_CONF_UNSET; | |
631 | |
632 return conf; | |
633 } | |
634 | |
635 | |
636 static char * | |
637 ngx_stream_ssl_preread_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) | |
638 { | |
639 ngx_stream_ssl_preread_srv_conf_t *prev = parent; | |
640 ngx_stream_ssl_preread_srv_conf_t *conf = child; | |
641 | |
642 ngx_conf_merge_value(conf->enabled, prev->enabled, 0); | |
643 | |
644 return NGX_CONF_OK; | |
645 } | |
646 | |
647 | |
648 static ngx_int_t | |
649 ngx_stream_ssl_preread_init(ngx_conf_t *cf) | |
650 { | |
651 ngx_stream_handler_pt *h; | |
652 ngx_stream_core_main_conf_t *cmcf; | |
653 | |
654 cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); | |
655 | |
656 h = ngx_array_push(&cmcf->phases[NGX_STREAM_PREREAD_PHASE].handlers); | |
657 if (h == NULL) { | |
658 return NGX_ERROR; | |
659 } | |
660 | |
661 *h = ngx_stream_ssl_preread_handler; | |
662 | |
663 return NGX_OK; | |
664 } |