Mercurial > hg > nginx-quic
view src/http/ngx_http_core_module.h @ 8551:c35b255d80dc quic
HTTP/3: close connection on keepalive_requests * 2.
After receiving GOAWAY, client is not supposed to create new streams. However,
until client reads this frame, we allow it to create new streams, which are
gracefully rejected. To prevent client from abusing this algorithm, a new
limit is introduced. Upon reaching keepalive_requests * 2, server now closes
the entire QUIC connection claiming excessive load.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 29 Jul 2021 16:01:37 +0300 |
parents | d514f88053e5 |
children | 61d0fa67b55e |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #ifndef _NGX_HTTP_CORE_H_INCLUDED_ #define _NGX_HTTP_CORE_H_INCLUDED_ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> #if (NGX_THREADS) #include <ngx_thread_pool.h> #elif (NGX_COMPAT) typedef struct ngx_thread_pool_s ngx_thread_pool_t; #endif #define NGX_HTTP_GZIP_PROXIED_OFF 0x0002 #define NGX_HTTP_GZIP_PROXIED_EXPIRED 0x0004 #define NGX_HTTP_GZIP_PROXIED_NO_CACHE 0x0008 #define NGX_HTTP_GZIP_PROXIED_NO_STORE 0x0010 #define NGX_HTTP_GZIP_PROXIED_PRIVATE 0x0020 #define NGX_HTTP_GZIP_PROXIED_NO_LM 0x0040 #define NGX_HTTP_GZIP_PROXIED_NO_ETAG 0x0080 #define NGX_HTTP_GZIP_PROXIED_AUTH 0x0100 #define NGX_HTTP_GZIP_PROXIED_ANY 0x0200 #define NGX_HTTP_AIO_OFF 0 #define NGX_HTTP_AIO_ON 1 #define NGX_HTTP_AIO_THREADS 2 #define NGX_HTTP_SATISFY_ALL 0 #define NGX_HTTP_SATISFY_ANY 1 #define NGX_HTTP_LINGERING_OFF 0 #define NGX_HTTP_LINGERING_ON 1 #define NGX_HTTP_LINGERING_ALWAYS 2 #define NGX_HTTP_IMS_OFF 0 #define NGX_HTTP_IMS_EXACT 1 #define NGX_HTTP_IMS_BEFORE 2 #define NGX_HTTP_KEEPALIVE_DISABLE_NONE 0x0002 #define NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 0x0004 #define NGX_HTTP_KEEPALIVE_DISABLE_SAFARI 0x0008 #define NGX_HTTP_SERVER_TOKENS_OFF 0 #define NGX_HTTP_SERVER_TOKENS_ON 1 #define NGX_HTTP_SERVER_TOKENS_BUILD 2 typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t; typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t; typedef struct { struct sockaddr *sockaddr; socklen_t socklen; ngx_str_t addr_text; unsigned set:1; unsigned default_server:1; unsigned bind:1; unsigned wildcard:1; unsigned ssl:1; unsigned quic:1; unsigned http2:1; unsigned http3:1; #if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif unsigned deferred_accept:1; unsigned reuseport:1; unsigned so_keepalive:2; unsigned proxy_protocol:1; int backlog; int rcvbuf; int sndbuf; int type; #if (NGX_HAVE_SETFIB) int setfib; #endif #if (NGX_HAVE_TCP_FASTOPEN) int fastopen; #endif #if (NGX_HAVE_KEEPALIVE_TUNABLE) int tcp_keepidle; int tcp_keepintvl; int tcp_keepcnt; #endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) char *accept_filter; #endif } ngx_http_listen_opt_t; typedef enum { NGX_HTTP_POST_READ_PHASE = 0, NGX_HTTP_SERVER_REWRITE_PHASE, NGX_HTTP_FIND_CONFIG_PHASE, NGX_HTTP_REWRITE_PHASE, NGX_HTTP_POST_REWRITE_PHASE, NGX_HTTP_PREACCESS_PHASE, NGX_HTTP_ACCESS_PHASE, NGX_HTTP_POST_ACCESS_PHASE, NGX_HTTP_PRECONTENT_PHASE, NGX_HTTP_CONTENT_PHASE, NGX_HTTP_LOG_PHASE } ngx_http_phases; typedef struct ngx_http_phase_handler_s ngx_http_phase_handler_t; typedef ngx_int_t (*ngx_http_phase_handler_pt)(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); struct ngx_http_phase_handler_s { ngx_http_phase_handler_pt checker; ngx_http_handler_pt handler; ngx_uint_t next; }; typedef struct { ngx_http_phase_handler_t *handlers; ngx_uint_t server_rewrite_index; ngx_uint_t location_rewrite_index; } ngx_http_phase_engine_t; typedef struct { ngx_array_t handlers; } ngx_http_phase_t; typedef struct { ngx_array_t servers; /* ngx_http_core_srv_conf_t */ ngx_http_phase_engine_t phase_engine; ngx_hash_t headers_in_hash; ngx_hash_t variables_hash; ngx_array_t variables; /* ngx_http_variable_t */ ngx_array_t prefix_variables; /* ngx_http_variable_t */ ngx_uint_t ncaptures; ngx_uint_t server_names_hash_max_size; ngx_uint_t server_names_hash_bucket_size; ngx_uint_t variables_hash_max_size; ngx_uint_t variables_hash_bucket_size; ngx_hash_keys_arrays_t *variables_keys; ngx_array_t *ports; ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1]; } ngx_http_core_main_conf_t; typedef struct { /* array of the ngx_http_server_name_t, "server_name" directive */ ngx_array_t server_names; /* server ctx */ ngx_http_conf_ctx_t *ctx; u_char *file_name; ngx_uint_t line; ngx_str_t server_name; size_t connection_pool_size; size_t request_pool_size; size_t client_header_buffer_size; ngx_bufs_t large_client_header_buffers; ngx_msec_t client_header_timeout; ngx_flag_t ignore_invalid_headers; ngx_flag_t merge_slashes; ngx_flag_t underscores_in_headers; unsigned listen:1; #if (NGX_PCRE) unsigned captures:1; #endif ngx_http_core_loc_conf_t **named_locations; } ngx_http_core_srv_conf_t; /* list of structures to find core_srv_conf quickly at run time */ typedef struct { #if (NGX_PCRE) ngx_http_regex_t *regex; #endif ngx_http_core_srv_conf_t *server; /* virtual name server conf */ ngx_str_t name; } ngx_http_server_name_t; typedef struct { ngx_hash_combined_t names; ngx_uint_t nregex; ngx_http_server_name_t *regex; } ngx_http_virtual_names_t; struct ngx_http_addr_conf_s { /* the default server configuration for this address:port */ ngx_http_core_srv_conf_t *default_server; ngx_http_virtual_names_t *virtual_names; unsigned ssl:1; unsigned quic:1; unsigned http2:1; unsigned http3:1; unsigned proxy_protocol:1; }; typedef struct { in_addr_t addr; ngx_http_addr_conf_t conf; } ngx_http_in_addr_t; #if (NGX_HAVE_INET6) typedef struct { struct in6_addr addr6; ngx_http_addr_conf_t conf; } ngx_http_in6_addr_t; #endif typedef struct { /* ngx_http_in_addr_t or ngx_http_in6_addr_t */ void *addrs; ngx_uint_t naddrs; } ngx_http_port_t; typedef struct { ngx_int_t family; ngx_int_t type; in_port_t port; ngx_array_t addrs; /* array of ngx_http_conf_addr_t */ } ngx_http_conf_port_t; typedef struct { ngx_http_listen_opt_t opt; ngx_hash_t hash; ngx_hash_wildcard_t *wc_head; ngx_hash_wildcard_t *wc_tail; #if (NGX_PCRE) ngx_uint_t nregex; ngx_http_server_name_t *regex; #endif /* the default server configuration for this address:port */ ngx_http_core_srv_conf_t *default_server; ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */ } ngx_http_conf_addr_t; typedef struct { ngx_int_t status; ngx_int_t overwrite; ngx_http_complex_value_t value; ngx_str_t args; } ngx_http_err_page_t; struct ngx_http_core_loc_conf_s { ngx_str_t name; /* location name */ ngx_str_t escaped_name; #if (NGX_PCRE) ngx_http_regex_t *regex; #endif unsigned noname:1; /* "if () {}" block or limit_except */ unsigned lmt_excpt:1; unsigned named:1; unsigned exact_match:1; unsigned noregex:1; unsigned auto_redirect:1; #if (NGX_HTTP_GZIP) unsigned gzip_disable_msie6:2; unsigned gzip_disable_degradation:2; #endif ngx_http_location_tree_node_t *static_locations; #if (NGX_PCRE) ngx_http_core_loc_conf_t **regex_locations; #endif /* pointer to the modules' loc_conf */ void **loc_conf; uint32_t limit_except; void **limit_except_loc_conf; ngx_http_handler_pt handler; /* location name length for inclusive location with inherited alias */ size_t alias; ngx_str_t root; /* root, alias */ ngx_str_t post_action; ngx_array_t *root_lengths; ngx_array_t *root_values; ngx_array_t *types; ngx_hash_t types_hash; ngx_str_t default_type; off_t client_max_body_size; /* client_max_body_size */ off_t directio; /* directio */ off_t directio_alignment; /* directio_alignment */ size_t client_body_buffer_size; /* client_body_buffer_size */ size_t send_lowat; /* send_lowat */ size_t postpone_output; /* postpone_output */ size_t sendfile_max_chunk; /* sendfile_max_chunk */ size_t read_ahead; /* read_ahead */ size_t subrequest_output_buffer_size; /* subrequest_output_buffer_size */ ngx_http_complex_value_t *limit_rate; /* limit_rate */ ngx_http_complex_value_t *limit_rate_after; /* limit_rate_after */ ngx_msec_t client_body_timeout; /* client_body_timeout */ ngx_msec_t send_timeout; /* send_timeout */ ngx_msec_t keepalive_time; /* keepalive_time */ ngx_msec_t keepalive_timeout; /* keepalive_timeout */ ngx_msec_t lingering_time; /* lingering_time */ ngx_msec_t lingering_timeout; /* lingering_timeout */ ngx_msec_t resolver_timeout; /* resolver_timeout */ ngx_msec_t auth_delay; /* auth_delay */ ngx_resolver_t *resolver; /* resolver */ time_t keepalive_header; /* keepalive_timeout */ ngx_uint_t keepalive_requests; /* keepalive_requests */ ngx_uint_t keepalive_disable; /* keepalive_disable */ ngx_uint_t satisfy; /* satisfy */ ngx_uint_t lingering_close; /* lingering_close */ ngx_uint_t if_modified_since; /* if_modified_since */ ngx_uint_t max_ranges; /* max_ranges */ ngx_uint_t client_body_in_file_only; /* client_body_in_file_only */ ngx_flag_t client_body_in_single_buffer; /* client_body_in_singe_buffer */ ngx_flag_t internal; /* internal */ ngx_flag_t sendfile; /* sendfile */ ngx_flag_t aio; /* aio */ ngx_flag_t aio_write; /* aio_write */ ngx_flag_t tcp_nopush; /* tcp_nopush */ ngx_flag_t tcp_nodelay; /* tcp_nodelay */ ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */ ngx_flag_t absolute_redirect; /* absolute_redirect */ ngx_flag_t server_name_in_redirect; /* server_name_in_redirect */ ngx_flag_t port_in_redirect; /* port_in_redirect */ ngx_flag_t msie_padding; /* msie_padding */ ngx_flag_t msie_refresh; /* msie_refresh */ ngx_flag_t log_not_found; /* log_not_found */ ngx_flag_t log_subrequest; /* log_subrequest */ ngx_flag_t recursive_error_pages; /* recursive_error_pages */ ngx_uint_t server_tokens; /* server_tokens */ ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */ ngx_flag_t etag; /* etag */ #if (NGX_HTTP_GZIP) ngx_flag_t gzip_vary; /* gzip_vary */ ngx_uint_t gzip_http_version; /* gzip_http_version */ ngx_uint_t gzip_proxied; /* gzip_proxied */ #if (NGX_PCRE) ngx_array_t *gzip_disable; /* gzip_disable */ #endif #endif #if (NGX_THREADS || NGX_COMPAT) ngx_thread_pool_t *thread_pool; ngx_http_complex_value_t *thread_pool_value; #endif #if (NGX_HAVE_OPENAT) ngx_uint_t disable_symlinks; /* disable_symlinks */ ngx_http_complex_value_t *disable_symlinks_from; #endif ngx_array_t *error_pages; /* error_page */ ngx_path_t *client_body_temp_path; /* client_body_temp_path */ ngx_open_file_cache_t *open_file_cache; time_t open_file_cache_valid; ngx_uint_t open_file_cache_min_uses; ngx_flag_t open_file_cache_errors; ngx_flag_t open_file_cache_events; ngx_log_t *error_log; ngx_uint_t types_hash_max_size; ngx_uint_t types_hash_bucket_size; ngx_queue_t *locations; #if 0 ngx_http_core_loc_conf_t *prev_location; #endif }; typedef struct { ngx_queue_t queue; ngx_http_core_loc_conf_t *exact; ngx_http_core_loc_conf_t *inclusive; ngx_str_t *name; u_char *file_name; ngx_uint_t line; ngx_queue_t list; } ngx_http_location_queue_t; struct ngx_http_location_tree_node_s { ngx_http_location_tree_node_t *left; ngx_http_location_tree_node_t *right; ngx_http_location_tree_node_t *tree; ngx_http_core_loc_conf_t *exact; ngx_http_core_loc_conf_t *inclusive; u_char auto_redirect; u_char len; u_char name[1]; }; void ngx_http_core_run_phases(ngx_http_request_t *r); ngx_int_t ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); ngx_int_t ngx_http_core_rewrite_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); ngx_int_t ngx_http_core_find_config_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); ngx_int_t ngx_http_core_post_rewrite_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); ngx_int_t ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); ngx_int_t ngx_http_core_post_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); void *ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash); ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r); void ngx_http_set_exten(ngx_http_request_t *r); ngx_int_t ngx_http_set_etag(ngx_http_request_t *r); void ngx_http_weak_etag(ngx_http_request_t *r); ngx_int_t ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status, ngx_str_t *ct, ngx_http_complex_value_t *cv); u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name, size_t *root_length, size_t reserved); ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r); #if (NGX_HTTP_GZIP) ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r); #endif ngx_int_t ngx_http_subrequest(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **sr, ngx_http_post_subrequest_t *psr, ngx_uint_t flags); ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args); ngx_int_t ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name); ngx_http_cleanup_t *ngx_http_cleanup_add(ngx_http_request_t *r, size_t size); typedef ngx_int_t (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r); typedef ngx_int_t (*ngx_http_output_body_filter_pt) (ngx_http_request_t *r, ngx_chain_t *chain); typedef ngx_int_t (*ngx_http_request_body_filter_pt) (ngx_http_request_t *r, ngx_chain_t *chain); ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain); ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain); ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *chain); ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of); ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies, int recursive); extern ngx_module_t ngx_http_core_module; extern ngx_uint_t ngx_http_max_module; extern ngx_str_t ngx_http_core_get_method; #define ngx_http_clear_content_length(r) \ \ r->headers_out.content_length_n = -1; \ if (r->headers_out.content_length) { \ r->headers_out.content_length->hash = 0; \ r->headers_out.content_length = NULL; \ } #define ngx_http_clear_accept_ranges(r) \ \ r->allow_ranges = 0; \ if (r->headers_out.accept_ranges) { \ r->headers_out.accept_ranges->hash = 0; \ r->headers_out.accept_ranges = NULL; \ } #define ngx_http_clear_last_modified(r) \ \ r->headers_out.last_modified_time = -1; \ if (r->headers_out.last_modified) { \ r->headers_out.last_modified->hash = 0; \ r->headers_out.last_modified = NULL; \ } #define ngx_http_clear_location(r) \ \ if (r->headers_out.location) { \ r->headers_out.location->hash = 0; \ r->headers_out.location = NULL; \ } #define ngx_http_clear_etag(r) \ \ if (r->headers_out.etag) { \ r->headers_out.etag->hash = 0; \ r->headers_out.etag = NULL; \ } #endif /* _NGX_HTTP_CORE_H_INCLUDED_ */