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)