Mercurial > hg > nginx
comparison src/http/v3/ngx_http_v3_module.c @ 8921:33226ac61076 quic
HTTP/3: merged ngx_http_quic_module into ngx_http_v3_module.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 06 Dec 2021 13:02:36 +0300 |
parents | 4f922f611135 |
children | be08b858086a |
comparison
equal
deleted
inserted
replaced
8920:9680f0badc95 | 8921:33226ac61076 |
---|---|
8 #include <ngx_config.h> | 8 #include <ngx_config.h> |
9 #include <ngx_core.h> | 9 #include <ngx_core.h> |
10 #include <ngx_http.h> | 10 #include <ngx_http.h> |
11 | 11 |
12 | 12 |
13 static ngx_int_t ngx_http_v3_variable_quic(ngx_http_request_t *r, | |
14 ngx_http_variable_value_t *v, uintptr_t data); | |
15 static ngx_int_t ngx_http_v3_add_variables(ngx_conf_t *cf); | |
13 static void *ngx_http_v3_create_srv_conf(ngx_conf_t *cf); | 16 static void *ngx_http_v3_create_srv_conf(ngx_conf_t *cf); |
14 static char *ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, | 17 static char *ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, |
15 void *child); | 18 void *child); |
19 static char *ngx_http_quic_max_ack_delay(ngx_conf_t *cf, void *post, | |
20 void *data); | |
21 static char *ngx_http_quic_max_udp_payload_size(ngx_conf_t *cf, void *post, | |
22 void *data); | |
23 static char *ngx_http_quic_host_key(ngx_conf_t *cf, ngx_command_t *cmd, | |
24 void *conf); | |
16 static void *ngx_http_v3_create_loc_conf(ngx_conf_t *cf); | 25 static void *ngx_http_v3_create_loc_conf(ngx_conf_t *cf); |
17 static char *ngx_http_v3_merge_loc_conf(ngx_conf_t *cf, void *parent, | 26 static char *ngx_http_v3_merge_loc_conf(ngx_conf_t *cf, void *parent, |
18 void *child); | 27 void *child); |
19 static char *ngx_http_v3_push(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 28 static char *ngx_http_v3_push(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
29 | |
30 | |
31 static ngx_conf_post_t ngx_http_quic_max_ack_delay_post = | |
32 { ngx_http_quic_max_ack_delay }; | |
33 static ngx_conf_post_t ngx_http_quic_max_udp_payload_size_post = | |
34 { ngx_http_quic_max_udp_payload_size }; | |
35 static ngx_conf_num_bounds_t ngx_http_quic_ack_delay_exponent_bounds = | |
36 { ngx_conf_check_num_bounds, 0, 20 }; | |
37 static ngx_conf_num_bounds_t ngx_http_quic_active_connection_id_limit_bounds = | |
38 { ngx_conf_check_num_bounds, 2, -1 }; | |
20 | 39 |
21 | 40 |
22 static ngx_command_t ngx_http_v3_commands[] = { | 41 static ngx_command_t ngx_http_v3_commands[] = { |
23 | 42 |
24 { ngx_string("http3_max_table_capacity"), | 43 { ngx_string("http3_max_table_capacity"), |
61 ngx_conf_set_flag_slot, | 80 ngx_conf_set_flag_slot, |
62 NGX_HTTP_LOC_CONF_OFFSET, | 81 NGX_HTTP_LOC_CONF_OFFSET, |
63 offsetof(ngx_http_v3_loc_conf_t, push_preload), | 82 offsetof(ngx_http_v3_loc_conf_t, push_preload), |
64 NULL }, | 83 NULL }, |
65 | 84 |
85 { ngx_string("quic_max_idle_timeout"), | |
86 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
87 ngx_conf_set_msec_slot, | |
88 NGX_HTTP_SRV_CONF_OFFSET, | |
89 offsetof(ngx_http_v3_srv_conf_t, quic.tp.max_idle_timeout), | |
90 NULL }, | |
91 | |
92 { ngx_string("quic_max_ack_delay"), | |
93 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
94 ngx_conf_set_msec_slot, | |
95 NGX_HTTP_SRV_CONF_OFFSET, | |
96 offsetof(ngx_http_v3_srv_conf_t, quic.tp.max_ack_delay), | |
97 &ngx_http_quic_max_ack_delay_post }, | |
98 | |
99 { ngx_string("quic_max_udp_payload_size"), | |
100 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
101 ngx_conf_set_size_slot, | |
102 NGX_HTTP_SRV_CONF_OFFSET, | |
103 offsetof(ngx_http_v3_srv_conf_t, quic.tp.max_udp_payload_size), | |
104 &ngx_http_quic_max_udp_payload_size_post }, | |
105 | |
106 { ngx_string("quic_initial_max_data"), | |
107 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
108 ngx_conf_set_size_slot, | |
109 NGX_HTTP_SRV_CONF_OFFSET, | |
110 offsetof(ngx_http_v3_srv_conf_t, quic.tp.initial_max_data), | |
111 NULL }, | |
112 | |
113 { ngx_string("quic_initial_max_stream_data_bidi_local"), | |
114 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
115 ngx_conf_set_size_slot, | |
116 NGX_HTTP_SRV_CONF_OFFSET, | |
117 offsetof(ngx_http_v3_srv_conf_t, | |
118 quic.tp.initial_max_stream_data_bidi_local), | |
119 NULL }, | |
120 | |
121 { ngx_string("quic_initial_max_stream_data_bidi_remote"), | |
122 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
123 ngx_conf_set_size_slot, | |
124 NGX_HTTP_SRV_CONF_OFFSET, | |
125 offsetof(ngx_http_v3_srv_conf_t, | |
126 quic.tp.initial_max_stream_data_bidi_remote), | |
127 NULL }, | |
128 | |
129 { ngx_string("quic_initial_max_stream_data_uni"), | |
130 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
131 ngx_conf_set_size_slot, | |
132 NGX_HTTP_SRV_CONF_OFFSET, | |
133 offsetof(ngx_http_v3_srv_conf_t, quic.tp.initial_max_stream_data_uni), | |
134 NULL }, | |
135 | |
136 { ngx_string("quic_initial_max_streams_bidi"), | |
137 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
138 ngx_conf_set_num_slot, | |
139 NGX_HTTP_SRV_CONF_OFFSET, | |
140 offsetof(ngx_http_v3_srv_conf_t, quic.tp.initial_max_streams_bidi), | |
141 NULL }, | |
142 | |
143 { ngx_string("quic_initial_max_streams_uni"), | |
144 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
145 ngx_conf_set_num_slot, | |
146 NGX_HTTP_SRV_CONF_OFFSET, | |
147 offsetof(ngx_http_v3_srv_conf_t, quic.tp.initial_max_streams_uni), | |
148 NULL }, | |
149 | |
150 { ngx_string("quic_ack_delay_exponent"), | |
151 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
152 ngx_conf_set_num_slot, | |
153 NGX_HTTP_SRV_CONF_OFFSET, | |
154 offsetof(ngx_http_v3_srv_conf_t, quic.tp.ack_delay_exponent), | |
155 &ngx_http_quic_ack_delay_exponent_bounds }, | |
156 | |
157 { ngx_string("quic_disable_active_migration"), | |
158 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
159 ngx_conf_set_flag_slot, | |
160 NGX_HTTP_SRV_CONF_OFFSET, | |
161 offsetof(ngx_http_v3_srv_conf_t, quic.tp.disable_active_migration), | |
162 NULL }, | |
163 | |
164 { ngx_string("quic_active_connection_id_limit"), | |
165 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
166 ngx_conf_set_num_slot, | |
167 NGX_HTTP_SRV_CONF_OFFSET, | |
168 offsetof(ngx_http_v3_srv_conf_t, quic.tp.active_connection_id_limit), | |
169 &ngx_http_quic_active_connection_id_limit_bounds }, | |
170 | |
171 { ngx_string("quic_retry"), | |
172 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, | |
173 ngx_conf_set_flag_slot, | |
174 NGX_HTTP_SRV_CONF_OFFSET, | |
175 offsetof(ngx_http_v3_srv_conf_t, quic.retry), | |
176 NULL }, | |
177 | |
178 { ngx_string("quic_gso"), | |
179 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, | |
180 ngx_conf_set_flag_slot, | |
181 NGX_HTTP_SRV_CONF_OFFSET, | |
182 offsetof(ngx_http_v3_srv_conf_t, quic.gso_enabled), | |
183 NULL }, | |
184 | |
185 { ngx_string("quic_host_key"), | |
186 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
187 ngx_http_quic_host_key, | |
188 NGX_HTTP_SRV_CONF_OFFSET, | |
189 0, | |
190 NULL }, | |
191 | |
66 ngx_null_command | 192 ngx_null_command |
67 }; | 193 }; |
68 | 194 |
69 | 195 |
70 static ngx_http_module_t ngx_http_v3_module_ctx = { | 196 static ngx_http_module_t ngx_http_v3_module_ctx = { |
71 NULL, /* preconfiguration */ | 197 ngx_http_v3_add_variables, /* preconfiguration */ |
72 NULL, /* postconfiguration */ | 198 NULL, /* postconfiguration */ |
73 | 199 |
74 NULL, /* create main configuration */ | 200 NULL, /* create main configuration */ |
75 NULL, /* init main configuration */ | 201 NULL, /* init main configuration */ |
76 | 202 |
96 NULL, /* exit master */ | 222 NULL, /* exit master */ |
97 NGX_MODULE_V1_PADDING | 223 NGX_MODULE_V1_PADDING |
98 }; | 224 }; |
99 | 225 |
100 | 226 |
227 static ngx_http_variable_t ngx_http_v3_vars[] = { | |
228 | |
229 { ngx_string("quic"), NULL, ngx_http_v3_variable_quic, 0, 0, 0 }, | |
230 | |
231 ngx_http_null_variable | |
232 }; | |
233 | |
234 static ngx_str_t ngx_http_quic_salt = ngx_string("ngx_quic"); | |
235 | |
236 | |
237 static ngx_int_t | |
238 ngx_http_v3_variable_quic(ngx_http_request_t *r, | |
239 ngx_http_variable_value_t *v, uintptr_t data) | |
240 { | |
241 if (r->connection->quic) { | |
242 | |
243 v->len = 4; | |
244 v->valid = 1; | |
245 v->no_cacheable = 1; | |
246 v->not_found = 0; | |
247 v->data = (u_char *) "quic"; | |
248 return NGX_OK; | |
249 } | |
250 | |
251 v->not_found = 1; | |
252 | |
253 return NGX_OK; | |
254 } | |
255 | |
256 | |
257 static ngx_int_t | |
258 ngx_http_v3_add_variables(ngx_conf_t *cf) | |
259 { | |
260 ngx_http_variable_t *var, *v; | |
261 | |
262 for (v = ngx_http_v3_vars; v->name.len; v++) { | |
263 var = ngx_http_add_variable(cf, &v->name, v->flags); | |
264 if (var == NULL) { | |
265 return NGX_ERROR; | |
266 } | |
267 | |
268 var->get_handler = v->get_handler; | |
269 var->data = v->data; | |
270 } | |
271 | |
272 return NGX_OK; | |
273 } | |
274 | |
275 | |
101 static void * | 276 static void * |
102 ngx_http_v3_create_srv_conf(ngx_conf_t *cf) | 277 ngx_http_v3_create_srv_conf(ngx_conf_t *cf) |
103 { | 278 { |
104 ngx_http_v3_srv_conf_t *h3scf; | 279 ngx_http_v3_srv_conf_t *h3scf; |
105 | 280 |
106 h3scf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v3_srv_conf_t)); | 281 h3scf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v3_srv_conf_t)); |
107 if (h3scf == NULL) { | 282 if (h3scf == NULL) { |
108 return NULL; | 283 return NULL; |
109 } | 284 } |
285 | |
286 /* | |
287 * set by ngx_pcalloc(): | |
288 * | |
289 * h3scf->quic.tp.original_dcid = { 0, NULL }; | |
290 * h3scf->quic.tp.initial_scid = { 0, NULL }; | |
291 * h3scf->quic.tp.retry_scid = { 0, NULL }; | |
292 * h3scf->quic.tp.sr_token = { 0 } | |
293 * h3scf->quic.tp.sr_enabled = 0 | |
294 * h3scf->quic.tp.preferred_address = NULL | |
295 * h3scf->quic.host_key = { 0, NULL } | |
296 * h3scf->quic.stream_reject_code_uni = 0; | |
297 */ | |
110 | 298 |
111 h3scf->max_table_capacity = NGX_CONF_UNSET_SIZE; | 299 h3scf->max_table_capacity = NGX_CONF_UNSET_SIZE; |
112 h3scf->max_blocked_streams = NGX_CONF_UNSET_UINT; | 300 h3scf->max_blocked_streams = NGX_CONF_UNSET_UINT; |
113 h3scf->max_concurrent_pushes = NGX_CONF_UNSET_UINT; | 301 h3scf->max_concurrent_pushes = NGX_CONF_UNSET_UINT; |
114 h3scf->max_uni_streams = NGX_CONF_UNSET_UINT; | 302 h3scf->max_uni_streams = NGX_CONF_UNSET_UINT; |
115 | 303 |
304 h3scf->quic.tp.max_idle_timeout = NGX_CONF_UNSET_MSEC; | |
305 h3scf->quic.tp.max_ack_delay = NGX_CONF_UNSET_MSEC; | |
306 h3scf->quic.tp.max_udp_payload_size = NGX_CONF_UNSET_SIZE; | |
307 h3scf->quic.tp.initial_max_data = NGX_CONF_UNSET_SIZE; | |
308 h3scf->quic.tp.initial_max_stream_data_bidi_local = NGX_CONF_UNSET_SIZE; | |
309 h3scf->quic.tp.initial_max_stream_data_bidi_remote = NGX_CONF_UNSET_SIZE; | |
310 h3scf->quic.tp.initial_max_stream_data_uni = NGX_CONF_UNSET_SIZE; | |
311 h3scf->quic.tp.initial_max_streams_bidi = NGX_CONF_UNSET_UINT; | |
312 h3scf->quic.tp.initial_max_streams_uni = NGX_CONF_UNSET_UINT; | |
313 h3scf->quic.tp.ack_delay_exponent = NGX_CONF_UNSET_UINT; | |
314 h3scf->quic.tp.disable_active_migration = NGX_CONF_UNSET; | |
315 h3scf->quic.tp.active_connection_id_limit = NGX_CONF_UNSET_UINT; | |
316 | |
317 h3scf->quic.retry = NGX_CONF_UNSET; | |
318 h3scf->quic.gso_enabled = NGX_CONF_UNSET; | |
319 h3scf->quic.stream_close_code = NGX_HTTP_V3_ERR_NO_ERROR; | |
320 h3scf->quic.stream_reject_code_bidi = NGX_HTTP_V3_ERR_REQUEST_REJECTED; | |
321 | |
116 return h3scf; | 322 return h3scf; |
117 } | 323 } |
118 | 324 |
119 | 325 |
120 static char * | 326 static char * |
121 ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) | 327 ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) |
122 { | 328 { |
123 ngx_http_v3_srv_conf_t *prev = parent; | 329 ngx_http_v3_srv_conf_t *prev = parent; |
124 ngx_http_v3_srv_conf_t *conf = child; | 330 ngx_http_v3_srv_conf_t *conf = child; |
125 | 331 |
332 ngx_http_ssl_srv_conf_t *sscf; | |
333 | |
126 ngx_conf_merge_size_value(conf->max_table_capacity, | 334 ngx_conf_merge_size_value(conf->max_table_capacity, |
127 prev->max_table_capacity, 16384); | 335 prev->max_table_capacity, 16384); |
128 | 336 |
129 ngx_conf_merge_uint_value(conf->max_blocked_streams, | 337 ngx_conf_merge_uint_value(conf->max_blocked_streams, |
130 prev->max_blocked_streams, 16); | 338 prev->max_blocked_streams, 16); |
133 prev->max_concurrent_pushes, 10); | 341 prev->max_concurrent_pushes, 10); |
134 | 342 |
135 ngx_conf_merge_uint_value(conf->max_uni_streams, | 343 ngx_conf_merge_uint_value(conf->max_uni_streams, |
136 prev->max_uni_streams, 3); | 344 prev->max_uni_streams, 3); |
137 | 345 |
346 ngx_conf_merge_msec_value(conf->quic.tp.max_idle_timeout, | |
347 prev->quic.tp.max_idle_timeout, 60000); | |
348 | |
349 ngx_conf_merge_msec_value(conf->quic.tp.max_ack_delay, | |
350 prev->quic.tp.max_ack_delay, | |
351 NGX_QUIC_DEFAULT_MAX_ACK_DELAY); | |
352 | |
353 ngx_conf_merge_size_value(conf->quic.tp.max_udp_payload_size, | |
354 prev->quic.tp.max_udp_payload_size, | |
355 NGX_QUIC_MAX_UDP_PAYLOAD_SIZE); | |
356 | |
357 ngx_conf_merge_size_value(conf->quic.tp.initial_max_data, | |
358 prev->quic.tp.initial_max_data, | |
359 16 * NGX_QUIC_STREAM_BUFSIZE); | |
360 | |
361 ngx_conf_merge_size_value(conf->quic.tp.initial_max_stream_data_bidi_local, | |
362 prev->quic.tp.initial_max_stream_data_bidi_local, | |
363 NGX_QUIC_STREAM_BUFSIZE); | |
364 | |
365 ngx_conf_merge_size_value(conf->quic.tp.initial_max_stream_data_bidi_remote, | |
366 prev->quic.tp.initial_max_stream_data_bidi_remote, | |
367 NGX_QUIC_STREAM_BUFSIZE); | |
368 | |
369 ngx_conf_merge_size_value(conf->quic.tp.initial_max_stream_data_uni, | |
370 prev->quic.tp.initial_max_stream_data_uni, | |
371 NGX_QUIC_STREAM_BUFSIZE); | |
372 | |
373 ngx_conf_merge_uint_value(conf->quic.tp.initial_max_streams_bidi, | |
374 prev->quic.tp.initial_max_streams_bidi, 16); | |
375 | |
376 ngx_conf_merge_uint_value(conf->quic.tp.initial_max_streams_uni, | |
377 prev->quic.tp.initial_max_streams_uni, 3); | |
378 | |
379 ngx_conf_merge_uint_value(conf->quic.tp.ack_delay_exponent, | |
380 prev->quic.tp.ack_delay_exponent, | |
381 NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT); | |
382 | |
383 ngx_conf_merge_value(conf->quic.tp.disable_active_migration, | |
384 prev->quic.tp.disable_active_migration, 0); | |
385 | |
386 ngx_conf_merge_uint_value(conf->quic.tp.active_connection_id_limit, | |
387 prev->quic.tp.active_connection_id_limit, 2); | |
388 | |
389 ngx_conf_merge_value(conf->quic.retry, prev->quic.retry, 0); | |
390 ngx_conf_merge_value(conf->quic.gso_enabled, prev->quic.gso_enabled, 0); | |
391 | |
392 ngx_conf_merge_str_value(conf->quic.host_key, prev->quic.host_key, ""); | |
393 | |
394 if (conf->quic.host_key.len == 0) { | |
395 | |
396 conf->quic.host_key.len = NGX_QUIC_DEFAULT_HOST_KEY_LEN; | |
397 conf->quic.host_key.data = ngx_palloc(cf->pool, | |
398 conf->quic.host_key.len); | |
399 if (conf->quic.host_key.data == NULL) { | |
400 return NGX_CONF_ERROR; | |
401 } | |
402 | |
403 if (RAND_bytes(conf->quic.host_key.data, NGX_QUIC_DEFAULT_HOST_KEY_LEN) | |
404 <= 0) | |
405 { | |
406 return NGX_CONF_ERROR; | |
407 } | |
408 } | |
409 | |
410 if (ngx_quic_derive_key(cf->log, "av_token_key", | |
411 &conf->quic.host_key, &ngx_http_quic_salt, | |
412 conf->quic.av_token_key, NGX_QUIC_AV_KEY_LEN) | |
413 != NGX_OK) | |
414 { | |
415 return NGX_CONF_ERROR; | |
416 } | |
417 | |
418 if (ngx_quic_derive_key(cf->log, "sr_token_key", | |
419 &conf->quic.host_key, &ngx_http_quic_salt, | |
420 conf->quic.sr_token_key, NGX_QUIC_SR_KEY_LEN) | |
421 != NGX_OK) | |
422 { | |
423 return NGX_CONF_ERROR; | |
424 } | |
425 | |
426 sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module); | |
427 conf->quic.ssl = &sscf->ssl; | |
428 | |
138 return NGX_CONF_OK; | 429 return NGX_CONF_OK; |
430 } | |
431 | |
432 | |
433 static char * | |
434 ngx_http_quic_max_ack_delay(ngx_conf_t *cf, void *post, void *data) | |
435 { | |
436 ngx_msec_t *sp = data; | |
437 | |
438 if (*sp >= 16384) { | |
439 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
440 "\"quic_max_ack_delay\" must be less than 16384"); | |
441 | |
442 return NGX_CONF_ERROR; | |
443 } | |
444 | |
445 return NGX_CONF_OK; | |
446 } | |
447 | |
448 | |
449 static char * | |
450 ngx_http_quic_max_udp_payload_size(ngx_conf_t *cf, void *post, void *data) | |
451 { | |
452 size_t *sp = data; | |
453 | |
454 if (*sp < NGX_QUIC_MIN_INITIAL_SIZE | |
455 || *sp > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE) | |
456 { | |
457 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
458 "\"quic_max_udp_payload_size\" must be between " | |
459 "%d and %d", | |
460 NGX_QUIC_MIN_INITIAL_SIZE, | |
461 NGX_QUIC_MAX_UDP_PAYLOAD_SIZE); | |
462 | |
463 return NGX_CONF_ERROR; | |
464 } | |
465 | |
466 return NGX_CONF_OK; | |
467 } | |
468 | |
469 | |
470 static char * | |
471 ngx_http_quic_host_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
472 { | |
473 ngx_http_v3_srv_conf_t *h3scf = conf; | |
474 | |
475 u_char *buf; | |
476 size_t size; | |
477 ssize_t n; | |
478 ngx_str_t *value; | |
479 ngx_file_t file; | |
480 ngx_file_info_t fi; | |
481 ngx_quic_conf_t *qcf; | |
482 | |
483 qcf = &h3scf->quic; | |
484 | |
485 if (qcf->host_key.len) { | |
486 return "is duplicate"; | |
487 } | |
488 | |
489 buf = NULL; | |
490 #if (NGX_SUPPRESS_WARN) | |
491 size = 0; | |
492 #endif | |
493 | |
494 value = cf->args->elts; | |
495 | |
496 if (ngx_conf_full_name(cf->cycle, &value[1], 1) != NGX_OK) { | |
497 return NGX_CONF_ERROR; | |
498 } | |
499 | |
500 ngx_memzero(&file, sizeof(ngx_file_t)); | |
501 file.name = value[1]; | |
502 file.log = cf->log; | |
503 | |
504 file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); | |
505 | |
506 if (file.fd == NGX_INVALID_FILE) { | |
507 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, | |
508 ngx_open_file_n " \"%V\" failed", &file.name); | |
509 return NGX_CONF_ERROR; | |
510 } | |
511 | |
512 if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) { | |
513 ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, | |
514 ngx_fd_info_n " \"%V\" failed", &file.name); | |
515 goto failed; | |
516 } | |
517 | |
518 size = ngx_file_size(&fi); | |
519 | |
520 if (size == 0) { | |
521 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
522 "\"%V\" zero key size", &file.name); | |
523 goto failed; | |
524 } | |
525 | |
526 buf = ngx_pnalloc(cf->pool, size); | |
527 if (buf == NULL) { | |
528 goto failed; | |
529 } | |
530 | |
531 n = ngx_read_file(&file, buf, size, 0); | |
532 | |
533 if (n == NGX_ERROR) { | |
534 ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, | |
535 ngx_read_file_n " \"%V\" failed", &file.name); | |
536 goto failed; | |
537 } | |
538 | |
539 if ((size_t) n != size) { | |
540 ngx_conf_log_error(NGX_LOG_CRIT, cf, 0, | |
541 ngx_read_file_n " \"%V\" returned only " | |
542 "%z bytes instead of %uz", &file.name, n, size); | |
543 goto failed; | |
544 } | |
545 | |
546 qcf->host_key.data = buf; | |
547 qcf->host_key.len = n; | |
548 | |
549 if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { | |
550 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
551 ngx_close_file_n " \"%V\" failed", &file.name); | |
552 } | |
553 | |
554 return NGX_CONF_OK; | |
555 | |
556 failed: | |
557 | |
558 if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { | |
559 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, | |
560 ngx_close_file_n " \"%V\" failed", &file.name); | |
561 } | |
562 | |
563 if (buf) { | |
564 ngx_explicit_memzero(buf, size); | |
565 } | |
566 | |
567 return NGX_CONF_ERROR; | |
139 } | 568 } |
140 | 569 |
141 | 570 |
142 static void * | 571 static void * |
143 ngx_http_v3_create_loc_conf(ngx_conf_t *cf) | 572 ngx_http_v3_create_loc_conf(ngx_conf_t *cf) |