Mercurial > hg > nginx
comparison src/http/v2/ngx_http_v2.c @ 7024:79de0d2aa432
HTTP/2: make SETTINGS ACK frame reusable.
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
author | Piotr Sikora <piotrsikora@google.com> |
---|---|
date | Fri, 02 Jun 2017 15:05:28 +0300 |
parents | 859d80f57aab |
children | 7206c3630310 |
comparison
equal
deleted
inserted
replaced
7023:859d80f57aab | 7024:79de0d2aa432 |
---|---|
26 #define NGX_HTTP_V2_ENHANCE_YOUR_CALM 0xb | 26 #define NGX_HTTP_V2_ENHANCE_YOUR_CALM 0xb |
27 #define NGX_HTTP_V2_INADEQUATE_SECURITY 0xc | 27 #define NGX_HTTP_V2_INADEQUATE_SECURITY 0xc |
28 #define NGX_HTTP_V2_HTTP_1_1_REQUIRED 0xd | 28 #define NGX_HTTP_V2_HTTP_1_1_REQUIRED 0xd |
29 | 29 |
30 /* frame sizes */ | 30 /* frame sizes */ |
31 #define NGX_HTTP_V2_SETTINGS_ACK_SIZE 0 | |
31 #define NGX_HTTP_V2_RST_STREAM_SIZE 4 | 32 #define NGX_HTTP_V2_RST_STREAM_SIZE 4 |
32 #define NGX_HTTP_V2_PRIORITY_SIZE 5 | 33 #define NGX_HTTP_V2_PRIORITY_SIZE 5 |
33 #define NGX_HTTP_V2_PING_SIZE 8 | 34 #define NGX_HTTP_V2_PING_SIZE 8 |
34 #define NGX_HTTP_V2_GOAWAY_SIZE 8 | 35 #define NGX_HTTP_V2_GOAWAY_SIZE 8 |
35 #define NGX_HTTP_V2_WINDOW_UPDATE_SIZE 4 | 36 #define NGX_HTTP_V2_WINDOW_UPDATE_SIZE 4 |
126 static ngx_http_v2_node_t *ngx_http_v2_get_closed_node( | 127 static ngx_http_v2_node_t *ngx_http_v2_get_closed_node( |
127 ngx_http_v2_connection_t *h2c); | 128 ngx_http_v2_connection_t *h2c); |
128 #define ngx_http_v2_index_size(h2scf) (h2scf->streams_index_mask + 1) | 129 #define ngx_http_v2_index_size(h2scf) (h2scf->streams_index_mask + 1) |
129 #define ngx_http_v2_index(h2scf, sid) ((sid >> 1) & h2scf->streams_index_mask) | 130 #define ngx_http_v2_index(h2scf, sid) ((sid >> 1) & h2scf->streams_index_mask) |
130 | 131 |
131 static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c, | 132 static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c); |
132 ngx_uint_t ack); | |
133 static ngx_int_t ngx_http_v2_settings_frame_handler( | 133 static ngx_int_t ngx_http_v2_settings_frame_handler( |
134 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame); | 134 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame); |
135 static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c, | 135 static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c, |
136 ngx_uint_t sid, size_t window); | 136 ngx_uint_t sid, size_t window); |
137 static ngx_int_t ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c, | 137 static ngx_int_t ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c, |
267 if (h2c->streams_index == NULL) { | 267 if (h2c->streams_index == NULL) { |
268 ngx_http_close_connection(c); | 268 ngx_http_close_connection(c); |
269 return; | 269 return; |
270 } | 270 } |
271 | 271 |
272 if (ngx_http_v2_send_settings(h2c, 0) == NGX_ERROR) { | 272 if (ngx_http_v2_send_settings(h2c) == NGX_ERROR) { |
273 ngx_http_close_connection(c); | 273 ngx_http_close_connection(c); |
274 return; | 274 return; |
275 } | 275 } |
276 | 276 |
277 if (ngx_http_v2_send_window_update(h2c, 0, NGX_HTTP_V2_MAX_WINDOW | 277 if (ngx_http_v2_send_window_update(h2c, 0, NGX_HTTP_V2_MAX_WINDOW |
1965 | 1965 |
1966 static u_char * | 1966 static u_char * |
1967 ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos, | 1967 ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos, |
1968 u_char *end) | 1968 u_char *end) |
1969 { | 1969 { |
1970 ssize_t window_delta; | 1970 ssize_t window_delta; |
1971 ngx_uint_t id, value; | 1971 ngx_uint_t id, value; |
1972 ngx_http_v2_out_frame_t *frame; | |
1972 | 1973 |
1973 window_delta = 0; | 1974 window_delta = 0; |
1974 | 1975 |
1975 while (h2c->state.length) { | 1976 while (h2c->state.length) { |
1976 if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) { | 1977 if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) { |
2022 } | 2023 } |
2023 | 2024 |
2024 pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE; | 2025 pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE; |
2025 } | 2026 } |
2026 | 2027 |
2027 ngx_http_v2_send_settings(h2c, 1); | 2028 frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_SETTINGS_ACK_SIZE, |
2029 NGX_HTTP_V2_SETTINGS_FRAME, | |
2030 NGX_HTTP_V2_ACK_FLAG, 0); | |
2031 if (frame == NULL) { | |
2032 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); | |
2033 } | |
2034 | |
2035 ngx_http_v2_queue_blocked_frame(h2c, frame); | |
2028 | 2036 |
2029 if (window_delta) { | 2037 if (window_delta) { |
2030 if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) { | 2038 if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) { |
2031 return ngx_http_v2_connection_error(h2c, | 2039 return ngx_http_v2_connection_error(h2c, |
2032 NGX_HTTP_V2_INTERNAL_ERROR); | 2040 NGX_HTTP_V2_INTERNAL_ERROR); |
2474 return NGX_AGAIN; | 2482 return NGX_AGAIN; |
2475 } | 2483 } |
2476 | 2484 |
2477 | 2485 |
2478 static ngx_int_t | 2486 static ngx_int_t |
2479 ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c, ngx_uint_t ack) | 2487 ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c) |
2480 { | 2488 { |
2481 size_t len; | 2489 size_t len; |
2482 ngx_buf_t *buf; | 2490 ngx_buf_t *buf; |
2483 ngx_chain_t *cl; | 2491 ngx_chain_t *cl; |
2484 ngx_http_v2_srv_conf_t *h2scf; | 2492 ngx_http_v2_srv_conf_t *h2scf; |
2485 ngx_http_v2_out_frame_t *frame; | 2493 ngx_http_v2_out_frame_t *frame; |
2486 | 2494 |
2487 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, | 2495 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, |
2488 "http2 send SETTINGS frame ack:%ui", ack); | 2496 "http2 send SETTINGS frame"); |
2489 | 2497 |
2490 frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t)); | 2498 frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t)); |
2491 if (frame == NULL) { | 2499 if (frame == NULL) { |
2492 return NGX_ERROR; | 2500 return NGX_ERROR; |
2493 } | 2501 } |
2495 cl = ngx_alloc_chain_link(h2c->pool); | 2503 cl = ngx_alloc_chain_link(h2c->pool); |
2496 if (cl == NULL) { | 2504 if (cl == NULL) { |
2497 return NGX_ERROR; | 2505 return NGX_ERROR; |
2498 } | 2506 } |
2499 | 2507 |
2500 len = ack ? 0 : (sizeof(uint16_t) + sizeof(uint32_t)) * 3; | 2508 len = NGX_HTTP_V2_SETTINGS_PARAM_SIZE * 3; |
2501 | 2509 |
2502 buf = ngx_create_temp_buf(h2c->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE + len); | 2510 buf = ngx_create_temp_buf(h2c->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE + len); |
2503 if (buf == NULL) { | 2511 if (buf == NULL) { |
2504 return NGX_ERROR; | 2512 return NGX_ERROR; |
2505 } | 2513 } |
2519 frame->blocked = 0; | 2527 frame->blocked = 0; |
2520 | 2528 |
2521 buf->last = ngx_http_v2_write_len_and_type(buf->last, len, | 2529 buf->last = ngx_http_v2_write_len_and_type(buf->last, len, |
2522 NGX_HTTP_V2_SETTINGS_FRAME); | 2530 NGX_HTTP_V2_SETTINGS_FRAME); |
2523 | 2531 |
2524 *buf->last++ = ack ? NGX_HTTP_V2_ACK_FLAG : NGX_HTTP_V2_NO_FLAG; | 2532 *buf->last++ = NGX_HTTP_V2_NO_FLAG; |
2525 | 2533 |
2526 buf->last = ngx_http_v2_write_sid(buf->last, 0); | 2534 buf->last = ngx_http_v2_write_sid(buf->last, 0); |
2527 | 2535 |
2528 if (!ack) { | 2536 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, |
2529 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, | 2537 ngx_http_v2_module); |
2530 ngx_http_v2_module); | 2538 |
2531 | 2539 buf->last = ngx_http_v2_write_uint16(buf->last, |
2532 buf->last = ngx_http_v2_write_uint16(buf->last, | 2540 NGX_HTTP_V2_MAX_STREAMS_SETTING); |
2533 NGX_HTTP_V2_MAX_STREAMS_SETTING); | 2541 buf->last = ngx_http_v2_write_uint32(buf->last, |
2534 buf->last = ngx_http_v2_write_uint32(buf->last, | 2542 h2scf->concurrent_streams); |
2535 h2scf->concurrent_streams); | 2543 |
2536 | 2544 buf->last = ngx_http_v2_write_uint16(buf->last, |
2537 buf->last = ngx_http_v2_write_uint16(buf->last, | |
2538 NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING); | 2545 NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING); |
2539 buf->last = ngx_http_v2_write_uint32(buf->last, h2scf->preread_size); | 2546 buf->last = ngx_http_v2_write_uint32(buf->last, h2scf->preread_size); |
2540 | 2547 |
2541 buf->last = ngx_http_v2_write_uint16(buf->last, | 2548 buf->last = ngx_http_v2_write_uint16(buf->last, |
2542 NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING); | 2549 NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING); |
2543 buf->last = ngx_http_v2_write_uint32(buf->last, | 2550 buf->last = ngx_http_v2_write_uint32(buf->last, |
2544 NGX_HTTP_V2_MAX_FRAME_SIZE); | 2551 NGX_HTTP_V2_MAX_FRAME_SIZE); |
2545 } | |
2546 | 2552 |
2547 ngx_http_v2_queue_blocked_frame(h2c, frame); | 2553 ngx_http_v2_queue_blocked_frame(h2c, frame); |
2548 | 2554 |
2549 return NGX_OK; | 2555 return NGX_OK; |
2550 } | 2556 } |