sync with OpenBSD -current
This commit is contained in:
parent
137d408ac1
commit
e0d126d03b
143 changed files with 5355 additions and 3727 deletions
|
@ -142,6 +142,7 @@ config_create(void)
|
|||
cfg->log_tag_queryreply = 0;
|
||||
cfg->log_local_actions = 0;
|
||||
cfg->log_servfail = 0;
|
||||
cfg->log_destaddr = 0;
|
||||
#ifndef USE_WINSOCK
|
||||
# ifdef USE_MINI_EVENT
|
||||
/* select max 1024 sockets */
|
||||
|
@ -271,6 +272,7 @@ config_create(void)
|
|||
cfg->val_permissive_mode = 0;
|
||||
cfg->aggressive_nsec = 1;
|
||||
cfg->ignore_cd = 0;
|
||||
cfg->disable_edns_do = 0;
|
||||
cfg->serve_expired = 0;
|
||||
cfg->serve_expired_ttl = 0;
|
||||
cfg->serve_expired_ttl_reset = 0;
|
||||
|
@ -381,6 +383,7 @@ config_create(void)
|
|||
#ifdef USE_CACHEDB
|
||||
if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit;
|
||||
if(!(cfg->cachedb_secret = strdup("default"))) goto error_exit;
|
||||
cfg->cachedb_no_store = 0;
|
||||
#ifdef USE_REDIS
|
||||
if(!(cfg->redis_server_host = strdup("127.0.0.1"))) goto error_exit;
|
||||
cfg->redis_server_path = NULL;
|
||||
|
@ -388,6 +391,7 @@ config_create(void)
|
|||
cfg->redis_timeout = 100;
|
||||
cfg->redis_server_port = 6379;
|
||||
cfg->redis_expire_records = 0;
|
||||
cfg->redis_logical_db = 0;
|
||||
#endif /* USE_REDIS */
|
||||
#endif /* USE_CACHEDB */
|
||||
#ifdef USE_IPSET
|
||||
|
@ -687,9 +691,11 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
else S_YNO("log-tag-queryreply:", log_tag_queryreply)
|
||||
else S_YNO("log-local-actions:", log_local_actions)
|
||||
else S_YNO("log-servfail:", log_servfail)
|
||||
else S_YNO("log-destaddr:", log_destaddr)
|
||||
else S_YNO("val-permissive-mode:", val_permissive_mode)
|
||||
else S_YNO("aggressive-nsec:", aggressive_nsec)
|
||||
else S_YNO("ignore-cd-flag:", ignore_cd)
|
||||
else S_YNO("disable-edns-do:", disable_edns_do)
|
||||
else if(strcmp(opt, "serve-expired:") == 0)
|
||||
{ IS_YES_OR_NO; cfg->serve_expired = (strcmp(val, "yes") == 0);
|
||||
SERVE_EXPIRED = cfg->serve_expired; }
|
||||
|
@ -819,6 +825,9 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
{ IS_NUMBER_OR_ZERO; cfg->ipsecmod_max_ttl = atoi(val); }
|
||||
else S_YNO("ipsecmod-strict:", ipsecmod_strict)
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
else S_YNO("cachedb-no-store:", cachedb_no_store)
|
||||
#endif /* USE_CACHEDB */
|
||||
else if(strcmp(opt, "define-tag:") ==0) {
|
||||
return config_add_tag(cfg, val);
|
||||
/* val_sig_skew_min, max and val_max_restart are copied into val_env
|
||||
|
@ -1120,6 +1129,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_YNO(opt, "log-tag-queryreply", log_tag_queryreply)
|
||||
else O_YNO(opt, "log-local-actions", log_local_actions)
|
||||
else O_YNO(opt, "log-servfail", log_servfail)
|
||||
else O_YNO(opt, "log-destaddr", log_destaddr)
|
||||
else O_STR(opt, "pidfile", pidfile)
|
||||
else O_YNO(opt, "hide-identity", hide_identity)
|
||||
else O_YNO(opt, "hide-version", hide_version)
|
||||
|
@ -1149,6 +1159,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_YNO(opt, "val-permissive-mode", val_permissive_mode)
|
||||
else O_YNO(opt, "aggressive-nsec", aggressive_nsec)
|
||||
else O_YNO(opt, "ignore-cd-flag", ignore_cd)
|
||||
else O_YNO(opt, "disable-edns-do", disable_edns_do)
|
||||
else O_YNO(opt, "serve-expired", serve_expired)
|
||||
else O_DEC(opt, "serve-expired-ttl", serve_expired_ttl)
|
||||
else O_YNO(opt, "serve-expired-ttl-reset", serve_expired_ttl_reset)
|
||||
|
@ -1306,6 +1317,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
#ifdef USE_CACHEDB
|
||||
else O_STR(opt, "backend", cachedb_backend)
|
||||
else O_STR(opt, "secret-seed", cachedb_secret)
|
||||
else O_YNO(opt, "cachedb-no-store", cachedb_no_store)
|
||||
#ifdef USE_REDIS
|
||||
else O_STR(opt, "redis-server-host", redis_server_host)
|
||||
else O_DEC(opt, "redis-server-port", redis_server_port)
|
||||
|
@ -1313,6 +1325,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_STR(opt, "redis-server-password", redis_server_password)
|
||||
else O_DEC(opt, "redis-timeout", redis_timeout)
|
||||
else O_YNO(opt, "redis-expire-records", redis_expire_records)
|
||||
else O_DEC(opt, "redis-logical-db", redis_logical_db)
|
||||
#endif /* USE_REDIS */
|
||||
#endif /* USE_CACHEDB */
|
||||
#ifdef USE_IPSET
|
||||
|
|
|
@ -349,6 +349,8 @@ struct config_file {
|
|||
int log_servfail;
|
||||
/** log identity to report */
|
||||
char* log_identity;
|
||||
/** log dest addr for log_replies */
|
||||
int log_destaddr;
|
||||
|
||||
/** do not report identity (id.server, hostname.bind) */
|
||||
int hide_identity;
|
||||
|
@ -409,6 +411,8 @@ struct config_file {
|
|||
int aggressive_nsec;
|
||||
/** ignore the CD flag in incoming queries and refuse them bogus data */
|
||||
int ignore_cd;
|
||||
/** disable EDNS DO flag in outgoing requests */
|
||||
int disable_edns_do;
|
||||
/** serve expired entries and prefetch them */
|
||||
int serve_expired;
|
||||
/** serve expired entries until TTL after expiration */
|
||||
|
@ -699,6 +703,8 @@ struct config_file {
|
|||
char* cachedb_backend;
|
||||
/** secret seed for hash key calculation */
|
||||
char* cachedb_secret;
|
||||
/** cachedb that does not store, but only reads from database, if on */
|
||||
int cachedb_no_store;
|
||||
#ifdef USE_REDIS
|
||||
/** redis server's IP address or host name */
|
||||
char* redis_server_host;
|
||||
|
@ -712,6 +718,8 @@ struct config_file {
|
|||
int redis_timeout;
|
||||
/** set timeout on redis records based on DNS response ttl */
|
||||
int redis_expire_records;
|
||||
/** set the redis logical database upon connection */
|
||||
int redis_logical_db;
|
||||
#endif
|
||||
#endif
|
||||
/** Downstream DNS Cookies */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -403,6 +403,7 @@ val-clean-additional{COLON} { YDVAR(1, VAR_VAL_CLEAN_ADDITIONAL) }
|
|||
val-permissive-mode{COLON} { YDVAR(1, VAR_VAL_PERMISSIVE_MODE) }
|
||||
aggressive-nsec{COLON} { YDVAR(1, VAR_AGGRESSIVE_NSEC) }
|
||||
ignore-cd-flag{COLON} { YDVAR(1, VAR_IGNORE_CD_FLAG) }
|
||||
disable-edns-do{COLON} { YDVAR(1, VAR_DISABLE_EDNS_DO) }
|
||||
serve-expired{COLON} { YDVAR(1, VAR_SERVE_EXPIRED) }
|
||||
serve-expired-ttl{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_TTL) }
|
||||
serve-expired-ttl-reset{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_TTL_RESET) }
|
||||
|
@ -433,6 +434,7 @@ log-replies{COLON} { YDVAR(1, VAR_LOG_REPLIES) }
|
|||
log-tag-queryreply{COLON} { YDVAR(1, VAR_LOG_TAG_QUERYREPLY) }
|
||||
log-local-actions{COLON} { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) }
|
||||
log-servfail{COLON} { YDVAR(1, VAR_LOG_SERVFAIL) }
|
||||
log-destaddr{COLON} { YDVAR(1, VAR_LOG_DESTADDR) }
|
||||
local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) }
|
||||
local-data{COLON} { YDVAR(1, VAR_LOCAL_DATA) }
|
||||
local-data-ptr{COLON} { YDVAR(1, VAR_LOCAL_DATA_PTR) }
|
||||
|
@ -557,12 +559,14 @@ ipsecmod-strict{COLON} { YDVAR(1, VAR_IPSECMOD_STRICT) }
|
|||
cachedb{COLON} { YDVAR(0, VAR_CACHEDB) }
|
||||
backend{COLON} { YDVAR(1, VAR_CACHEDB_BACKEND) }
|
||||
secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) }
|
||||
cachedb-no-store{COLON} { YDVAR(1, VAR_CACHEDB_NO_STORE) }
|
||||
redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) }
|
||||
redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) }
|
||||
redis-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISPATH) }
|
||||
redis-server-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) }
|
||||
redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) }
|
||||
redis-expire-records{COLON} { YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) }
|
||||
redis-logical-db{COLON} { YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) }
|
||||
ipset{COLON} { YDVAR(0, VAR_IPSET) }
|
||||
name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) }
|
||||
name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) }
|
||||
|
|
|
@ -283,64 +283,68 @@
|
|||
#define VAR_CACHEDB_REDISEXPIRERECORDS 539
|
||||
#define VAR_CACHEDB_REDISPATH 540
|
||||
#define VAR_CACHEDB_REDISPASSWORD 541
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 542
|
||||
#define VAR_FOR_UPSTREAM 543
|
||||
#define VAR_AUTH_ZONE 544
|
||||
#define VAR_ZONEFILE 545
|
||||
#define VAR_MASTER 546
|
||||
#define VAR_URL 547
|
||||
#define VAR_FOR_DOWNSTREAM 548
|
||||
#define VAR_FALLBACK_ENABLED 549
|
||||
#define VAR_TLS_ADDITIONAL_PORT 550
|
||||
#define VAR_LOW_RTT 551
|
||||
#define VAR_LOW_RTT_PERMIL 552
|
||||
#define VAR_FAST_SERVER_PERMIL 553
|
||||
#define VAR_FAST_SERVER_NUM 554
|
||||
#define VAR_ALLOW_NOTIFY 555
|
||||
#define VAR_TLS_WIN_CERT 556
|
||||
#define VAR_TCP_CONNECTION_LIMIT 557
|
||||
#define VAR_ANSWER_COOKIE 558
|
||||
#define VAR_COOKIE_SECRET 559
|
||||
#define VAR_IP_RATELIMIT_COOKIE 560
|
||||
#define VAR_FORWARD_NO_CACHE 561
|
||||
#define VAR_STUB_NO_CACHE 562
|
||||
#define VAR_LOG_SERVFAIL 563
|
||||
#define VAR_DENY_ANY 564
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 565
|
||||
#define VAR_LOG_TAG_QUERYREPLY 566
|
||||
#define VAR_STREAM_WAIT_SIZE 567
|
||||
#define VAR_TLS_CIPHERS 568
|
||||
#define VAR_TLS_CIPHERSUITES 569
|
||||
#define VAR_TLS_USE_SNI 570
|
||||
#define VAR_IPSET 571
|
||||
#define VAR_IPSET_NAME_V4 572
|
||||
#define VAR_IPSET_NAME_V6 573
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 574
|
||||
#define VAR_RPZ 575
|
||||
#define VAR_TAGS 576
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 577
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 578
|
||||
#define VAR_RPZ_LOG 579
|
||||
#define VAR_RPZ_LOG_NAME 580
|
||||
#define VAR_DYNLIB 581
|
||||
#define VAR_DYNLIB_FILE 582
|
||||
#define VAR_EDNS_CLIENT_STRING 583
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 584
|
||||
#define VAR_NSID 585
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 586
|
||||
#define VAR_ZONEMD_CHECK 587
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 588
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 589
|
||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 590
|
||||
#define VAR_EDE 591
|
||||
#define VAR_INTERFACE_ACTION 592
|
||||
#define VAR_INTERFACE_VIEW 593
|
||||
#define VAR_INTERFACE_TAG 594
|
||||
#define VAR_INTERFACE_TAG_ACTION 595
|
||||
#define VAR_INTERFACE_TAG_DATA 596
|
||||
#define VAR_PROXY_PROTOCOL_PORT 597
|
||||
#define VAR_STATISTICS_INHIBIT_ZERO 598
|
||||
#define VAR_HARDEN_UNKNOWN_ADDITIONAL 599
|
||||
#define VAR_CACHEDB_REDISLOGICALDB 542
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 543
|
||||
#define VAR_FOR_UPSTREAM 544
|
||||
#define VAR_AUTH_ZONE 545
|
||||
#define VAR_ZONEFILE 546
|
||||
#define VAR_MASTER 547
|
||||
#define VAR_URL 548
|
||||
#define VAR_FOR_DOWNSTREAM 549
|
||||
#define VAR_FALLBACK_ENABLED 550
|
||||
#define VAR_TLS_ADDITIONAL_PORT 551
|
||||
#define VAR_LOW_RTT 552
|
||||
#define VAR_LOW_RTT_PERMIL 553
|
||||
#define VAR_FAST_SERVER_PERMIL 554
|
||||
#define VAR_FAST_SERVER_NUM 555
|
||||
#define VAR_ALLOW_NOTIFY 556
|
||||
#define VAR_TLS_WIN_CERT 557
|
||||
#define VAR_TCP_CONNECTION_LIMIT 558
|
||||
#define VAR_ANSWER_COOKIE 559
|
||||
#define VAR_COOKIE_SECRET 560
|
||||
#define VAR_IP_RATELIMIT_COOKIE 561
|
||||
#define VAR_FORWARD_NO_CACHE 562
|
||||
#define VAR_STUB_NO_CACHE 563
|
||||
#define VAR_LOG_SERVFAIL 564
|
||||
#define VAR_DENY_ANY 565
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 566
|
||||
#define VAR_LOG_TAG_QUERYREPLY 567
|
||||
#define VAR_STREAM_WAIT_SIZE 568
|
||||
#define VAR_TLS_CIPHERS 569
|
||||
#define VAR_TLS_CIPHERSUITES 570
|
||||
#define VAR_TLS_USE_SNI 571
|
||||
#define VAR_IPSET 572
|
||||
#define VAR_IPSET_NAME_V4 573
|
||||
#define VAR_IPSET_NAME_V6 574
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 575
|
||||
#define VAR_RPZ 576
|
||||
#define VAR_TAGS 577
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 578
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 579
|
||||
#define VAR_RPZ_LOG 580
|
||||
#define VAR_RPZ_LOG_NAME 581
|
||||
#define VAR_DYNLIB 582
|
||||
#define VAR_DYNLIB_FILE 583
|
||||
#define VAR_EDNS_CLIENT_STRING 584
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 585
|
||||
#define VAR_NSID 586
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 587
|
||||
#define VAR_ZONEMD_CHECK 588
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 589
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 590
|
||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 591
|
||||
#define VAR_EDE 592
|
||||
#define VAR_INTERFACE_ACTION 593
|
||||
#define VAR_INTERFACE_VIEW 594
|
||||
#define VAR_INTERFACE_TAG 595
|
||||
#define VAR_INTERFACE_TAG_ACTION 596
|
||||
#define VAR_INTERFACE_TAG_DATA 597
|
||||
#define VAR_PROXY_PROTOCOL_PORT 598
|
||||
#define VAR_STATISTICS_INHIBIT_ZERO 599
|
||||
#define VAR_HARDEN_UNKNOWN_ADDITIONAL 600
|
||||
#define VAR_DISABLE_EDNS_DO 601
|
||||
#define VAR_CACHEDB_NO_STORE 602
|
||||
#define VAR_LOG_DESTADDR 603
|
||||
#ifndef YYSTYPE_DEFINED
|
||||
#define YYSTYPE_DEFINED
|
||||
typedef union {
|
||||
|
|
|
@ -179,6 +179,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED
|
||||
%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT
|
||||
%token VAR_CACHEDB_REDISEXPIRERECORDS VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISPASSWORD
|
||||
%token VAR_CACHEDB_REDISLOGICALDB
|
||||
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
|
||||
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
|
||||
%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
|
||||
|
@ -198,7 +199,8 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_INTERFACE_ACTION VAR_INTERFACE_VIEW VAR_INTERFACE_TAG
|
||||
%token VAR_INTERFACE_TAG_ACTION VAR_INTERFACE_TAG_DATA
|
||||
%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
|
||||
%token VAR_HARDEN_UNKNOWN_ADDITIONAL
|
||||
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
|
||||
%token VAR_LOG_DESTADDR
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
|
@ -332,7 +334,8 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
|
||||
server_interface_automatic_ports | server_ede |
|
||||
server_proxy_protocol_port | server_statistics_inhibit_zero |
|
||||
server_harden_unknown_additional
|
||||
server_harden_unknown_additional | server_disable_edns_do |
|
||||
server_log_destaddr
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
|
@ -1249,6 +1252,15 @@ server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_log_destaddr: VAR_LOG_DESTADDR STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_log_destaddr:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->log_destaddr = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_log_local_actions:%s)\n", $2));
|
||||
|
@ -2060,6 +2072,15 @@ server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_disable_edns_do: VAR_DISABLE_EDNS_DO STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_disable_edns_do:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->disable_edns_do = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_serve_expired: VAR_SERVE_EXPIRED STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_serve_expired:%s)\n", $2));
|
||||
|
@ -3701,7 +3722,8 @@ contents_cachedb: contents_cachedb content_cachedb
|
|||
| ;
|
||||
content_cachedb: cachedb_backend_name | cachedb_secret_seed |
|
||||
redis_server_host | redis_server_port | redis_timeout |
|
||||
redis_expire_records | redis_server_path | redis_server_password
|
||||
redis_expire_records | redis_server_path | redis_server_password |
|
||||
cachedb_no_store | redis_logical_db
|
||||
;
|
||||
cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
|
||||
{
|
||||
|
@ -3727,6 +3749,19 @@ cachedb_secret_seed: VAR_CACHEDB_SECRETSEED STRING_ARG
|
|||
#endif
|
||||
}
|
||||
;
|
||||
cachedb_no_store: VAR_CACHEDB_NO_STORE STRING_ARG
|
||||
{
|
||||
#ifdef USE_CACHEDB
|
||||
OUTYY(("P(cachedb_no_store:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->cachedb_no_store = (strcmp($2, "yes")==0);
|
||||
#else
|
||||
OUTYY(("P(Compiled without cachedb, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
redis_server_host: VAR_CACHEDB_REDISHOST STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
|
@ -3804,6 +3839,21 @@ redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
redis_logical_db: VAR_CACHEDB_REDISLOGICALDB STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
int db;
|
||||
OUTYY(("P(redis_logical_db:%s)\n", $2));
|
||||
db = atoi($2);
|
||||
if((db == 0 && strcmp($2, "0") != 0) || db < 0)
|
||||
yyerror("valid redis logical database index expected");
|
||||
else cfg_parser->cfg->redis_logical_db = db;
|
||||
#else
|
||||
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_tcp_connection_limit:%s %s)\n", $2, $3));
|
||||
|
|
|
@ -886,6 +886,9 @@ ede_trim_text(struct edns_option** list)
|
|||
curr->opt_len = 2;
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
} else {
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
} else {
|
||||
/* continue */
|
||||
|
@ -1012,8 +1015,10 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
|||
ede_size = calc_ede_option_size(edns, &ede_txt_size);
|
||||
if(sldns_buffer_capacity(pkt) < udpsize)
|
||||
udpsize = sldns_buffer_capacity(pkt);
|
||||
if(!edns || !edns->edns_present) {
|
||||
attach_edns = 0;
|
||||
/* EDEs are optional, try to fit anything else before them */
|
||||
if(udpsize < LDNS_HEADER_SIZE + edns_field_size - ede_size) {
|
||||
} else if(udpsize < LDNS_HEADER_SIZE + edns_field_size - ede_size) {
|
||||
/* packet too small to contain edns, omit it. */
|
||||
attach_edns = 0;
|
||||
} else {
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "util/regional.h"
|
||||
#include "util/rfc_1982.h"
|
||||
#include "util/edns.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/rrdef.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/parseutil.h"
|
||||
|
@ -1306,3 +1307,27 @@ log_edns_opt_list(enum verbosity_value level, const char* info_str,
|
|||
}
|
||||
}
|
||||
|
||||
/** remove RR from msgparse RRset, return true if rrset is entirely bad */
|
||||
int
|
||||
msgparse_rrset_remove_rr(const char* str, sldns_buffer* pkt, struct rrset_parse* rrset,
|
||||
struct rr_parse* prev, struct rr_parse* rr, struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
{
|
||||
if(verbosity >= VERB_QUERY && rrset->dname_len <= LDNS_MAX_DOMAINLEN && str) {
|
||||
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
|
||||
dname_pkt_copy(pkt, buf, rrset->dname);
|
||||
if(addr)
|
||||
log_name_addr(VERB_QUERY, str, buf, addr, addrlen);
|
||||
else log_nametypeclass(VERB_QUERY, str, buf,
|
||||
rrset->type, ntohs(rrset->rrset_class));
|
||||
}
|
||||
if(prev)
|
||||
prev->next = rr->next;
|
||||
else rrset->rr_first = rr->next;
|
||||
if(rrset->rr_last == rr)
|
||||
rrset->rr_last = prev;
|
||||
rrset->rr_count --;
|
||||
rrset->size -= rr->size;
|
||||
/* rr struct still exists, but is unlinked, so that in the for loop
|
||||
* the rr->next works fine to continue. */
|
||||
return rrset->rr_count == 0;
|
||||
}
|
||||
|
|
|
@ -371,4 +371,22 @@ void msgparse_bucket_remove(struct msg_parse* msg, struct rrset_parse* rrset);
|
|||
void log_edns_opt_list(enum verbosity_value level, const char* info_str,
|
||||
struct edns_option* list);
|
||||
|
||||
/**
|
||||
* Remove RR from msgparse RRset.
|
||||
* @param str: this string is used for logging if verbose. If NULL, there is
|
||||
* no logging of the remove.
|
||||
* @param pkt: packet in buffer that is removed from. Used to log the name
|
||||
* of the item removed.
|
||||
* @param rrset: RRset that the RR is removed from.
|
||||
* @param prev: previous RR in list, or NULL.
|
||||
* @param rr: RR that is removed.
|
||||
* @param addr: address used for logging, if verbose, or NULL then it is not
|
||||
* used.
|
||||
* @param addrlen: length of addr, if that is not NULL.
|
||||
* @return true if rrset is entirely bad, it would then need to be removed.
|
||||
*/
|
||||
int msgparse_rrset_remove_rr(const char* str, struct sldns_buffer* pkt,
|
||||
struct rrset_parse* rrset, struct rr_parse* prev, struct rr_parse* rr,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
#endif /* UTIL_DATA_MSGPARSE_H */
|
||||
|
|
|
@ -918,13 +918,15 @@ log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep)
|
|||
void
|
||||
log_reply_info(enum verbosity_value v, struct query_info *qinf,
|
||||
struct sockaddr_storage *addr, socklen_t addrlen, struct timeval dur,
|
||||
int cached, struct sldns_buffer *rmsg)
|
||||
int cached, struct sldns_buffer *rmsg, struct sockaddr_storage* daddr,
|
||||
enum comm_point_type tp)
|
||||
{
|
||||
char qname_buf[LDNS_MAX_DOMAINLEN+1];
|
||||
char clientip_buf[128];
|
||||
char rcode_buf[16];
|
||||
char type_buf[16];
|
||||
char class_buf[16];
|
||||
char dest_buf[160];
|
||||
size_t pktlen;
|
||||
uint16_t rcode = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(rmsg, 2));
|
||||
|
||||
|
@ -933,11 +935,46 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf,
|
|||
|
||||
sldns_wire2str_rcode_buf((int)rcode, rcode_buf, sizeof(rcode_buf));
|
||||
addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf));
|
||||
if(daddr) {
|
||||
char da[128];
|
||||
int port = 0;
|
||||
char* comm;
|
||||
if(daddr->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *d = (struct sockaddr_in6 *)daddr;
|
||||
if(inet_ntop(d->sin6_family, &d->sin6_addr, da,
|
||||
sizeof(*d)) == 0)
|
||||
snprintf(dest_buf, sizeof(dest_buf),
|
||||
"(inet_ntop_error)");
|
||||
port = ntohs(d->sin6_port);
|
||||
} else if(daddr->ss_family == AF_INET) {
|
||||
struct sockaddr_in *d = (struct sockaddr_in *)daddr;
|
||||
if(inet_ntop(d->sin_family, &d->sin_addr, da,
|
||||
sizeof(*d)) == 0)
|
||||
snprintf(dest_buf, sizeof(dest_buf),
|
||||
"(inet_ntop_error)");
|
||||
port = ntohs(d->sin_port);
|
||||
} else {
|
||||
snprintf(da, sizeof(da), "socket%d",
|
||||
(int)daddr->ss_family);
|
||||
}
|
||||
comm = "udp";
|
||||
if(tp == comm_tcp) comm = "tcp";
|
||||
else if(tp == comm_tcp_accept) comm = "tcp";
|
||||
else if(tp == comm_http) comm = "dot";
|
||||
else if(tp == comm_local) comm = "unix";
|
||||
else if(tp == comm_raw) comm = "raw";
|
||||
snprintf(dest_buf, sizeof(dest_buf), " on %s %s %d",
|
||||
comm, da, port);
|
||||
} else {
|
||||
dest_buf[0]=0;
|
||||
}
|
||||
if(rcode == LDNS_RCODE_FORMERR)
|
||||
{
|
||||
if(LOG_TAG_QUERYREPLY)
|
||||
log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf);
|
||||
else log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
|
||||
log_reply("%s - - - %s - - -%s", clientip_buf,
|
||||
rcode_buf, dest_buf);
|
||||
else log_info("%s - - - %s - - -%s", clientip_buf,
|
||||
rcode_buf, dest_buf);
|
||||
} else {
|
||||
if(qinf->qname)
|
||||
dname_str(qinf->qname, qname_buf);
|
||||
|
@ -946,12 +983,14 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf,
|
|||
sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf));
|
||||
sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf));
|
||||
if(LOG_TAG_QUERYREPLY)
|
||||
log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
|
||||
log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d%s",
|
||||
clientip_buf, qname_buf, type_buf, class_buf,
|
||||
rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
|
||||
else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
|
||||
rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec,
|
||||
cached, (int)pktlen, dest_buf);
|
||||
else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d%s",
|
||||
clientip_buf, qname_buf, type_buf, class_buf,
|
||||
rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
|
||||
rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec,
|
||||
cached, (int)pktlen, dest_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ struct msg_parse;
|
|||
struct rrset_parse;
|
||||
struct local_rrset;
|
||||
struct dns_msg;
|
||||
enum comm_point_type;
|
||||
|
||||
/** calculate the prefetch TTL as 90% of original. Calculation
|
||||
* without numerical overflow (uin32_t) */
|
||||
|
@ -520,10 +521,13 @@ void log_dns_msg(const char* str, struct query_info* qinfo,
|
|||
* @param cached: whether or not the reply is coming from
|
||||
* the cache, or an outside network.
|
||||
* @param rmsg: sldns buffer packet.
|
||||
* @param daddr: if not NULL, the destination address and port are logged.
|
||||
* @param tp: type of the comm point for logging destination connection type.
|
||||
*/
|
||||
void log_reply_info(enum verbosity_value v, struct query_info *qinf,
|
||||
struct sockaddr_storage *addr, socklen_t addrlen, struct timeval dur,
|
||||
int cached, struct sldns_buffer *rmsg);
|
||||
int cached, struct sldns_buffer *rmsg, struct sockaddr_storage* daddr,
|
||||
enum comm_point_type tp);
|
||||
|
||||
/**
|
||||
* Print string with neat domain name, type, class from query info.
|
||||
|
|
|
@ -275,6 +275,7 @@ int packed_rr_to_string(struct ub_packed_rrset_key* rrset, size_t i,
|
|||
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
|
||||
entry.data;
|
||||
uint8_t rr[65535];
|
||||
size_t wlen;
|
||||
size_t rlen = rrset->rk.dname_len + 2 + 2 + 4 + d->rr_len[i];
|
||||
time_t adjust = 0;
|
||||
log_assert(dest_len > 0 && dest);
|
||||
|
@ -292,7 +293,9 @@ int packed_rr_to_string(struct ub_packed_rrset_key* rrset, size_t i,
|
|||
sldns_write_uint32(rr+rrset->rk.dname_len+4,
|
||||
(uint32_t)(d->rr_ttl[i]-adjust));
|
||||
memmove(rr+rrset->rk.dname_len+8, d->rr_data[i], d->rr_len[i]);
|
||||
if(sldns_wire2str_rr_buf(rr, rlen, dest, dest_len) == -1) {
|
||||
wlen = (size_t)sldns_wire2str_rr_buf(rr, rlen, dest, dest_len);
|
||||
if(wlen >= dest_len) {
|
||||
/* the output string was truncated */
|
||||
log_info("rrbuf failure %d %s", (int)d->rr_len[i], dest);
|
||||
dest[0] = 0;
|
||||
return 0;
|
||||
|
|
|
@ -169,7 +169,9 @@ int
|
|||
fptr_whitelist_event(void (*fptr)(int, short, void *))
|
||||
{
|
||||
if(fptr == &comm_point_udp_callback) return 1;
|
||||
#if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(HAVE_RECVMSG)
|
||||
else if(fptr == &comm_point_udp_ancil_callback) return 1;
|
||||
#endif
|
||||
else if(fptr == &comm_point_tcp_accept_callback) return 1;
|
||||
else if(fptr == &comm_point_tcp_handle_callback) return 1;
|
||||
else if(fptr == &comm_timer_callback) return 1;
|
||||
|
|
|
@ -258,7 +258,6 @@
|
|||
356,
|
||||
357,
|
||||
358,
|
||||
359,
|
||||
360,
|
||||
361,
|
||||
362,
|
||||
|
|
|
@ -187,7 +187,7 @@ void log_ident_set_default(const char* id)
|
|||
default_ident = id;
|
||||
}
|
||||
|
||||
void log_ident_revert_to_default()
|
||||
void log_ident_revert_to_default(void)
|
||||
{
|
||||
ident = default_ident;
|
||||
}
|
||||
|
|
|
@ -194,6 +194,24 @@ char* errinf_to_str_servfail(struct module_qstate* qstate)
|
|||
return p;
|
||||
}
|
||||
|
||||
char* errinf_to_str_misc(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct errinf_strlist* s;
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, "misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, "%s%s", (s==qstate->errinf?"":" "), s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr)
|
||||
{
|
||||
char buf[1024];
|
||||
|
|
|
@ -691,6 +691,8 @@ struct module_qstate {
|
|||
struct respip_action_info* respip_action_info;
|
||||
/** if the query is rpz passthru, no further rpz processing for it */
|
||||
int rpz_passthru;
|
||||
/* Flag tcp required. */
|
||||
int tcp_required;
|
||||
|
||||
/** whether the reply should be dropped */
|
||||
int is_drop;
|
||||
|
@ -842,6 +844,14 @@ sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate);
|
|||
*/
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Create error info in string. For misc failures that are not servfail.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_misc(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Initialize the edns known options by allocating the required space.
|
||||
* @param env: the module environment.
|
||||
|
|
|
@ -952,6 +952,111 @@ void log_crypto_err_code(const char* str, unsigned long err)
|
|||
#endif /* HAVE_SSL */
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
/** Print crypt erro with SSL_get_error want code and err_get_error code */
|
||||
static void log_crypto_err_io_code_arg(const char* str, int r,
|
||||
unsigned long err, int err_present)
|
||||
{
|
||||
int print_errno = 0, print_crypto_err = 0;
|
||||
const char* inf = NULL;
|
||||
|
||||
switch(r) {
|
||||
case SSL_ERROR_NONE:
|
||||
inf = "no error";
|
||||
break;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
inf = "channel closed";
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
inf = "want read";
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
inf = "want write";
|
||||
break;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
inf = "want connect";
|
||||
break;
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
inf = "want accept";
|
||||
break;
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
inf = "want X509 lookup";
|
||||
break;
|
||||
#ifdef SSL_ERROR_WANT_ASYNC
|
||||
case SSL_ERROR_WANT_ASYNC:
|
||||
inf = "want async";
|
||||
break;
|
||||
#endif
|
||||
#ifdef SSL_ERROR_WANT_ASYNC_JOB
|
||||
case SSL_ERROR_WANT_ASYNC_JOB:
|
||||
inf = "want async job";
|
||||
break;
|
||||
#endif
|
||||
#ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB
|
||||
case SSL_ERROR_WANT_CLIENT_HELLO_CB:
|
||||
inf = "want client hello cb";
|
||||
break;
|
||||
#endif
|
||||
case SSL_ERROR_SYSCALL:
|
||||
print_errno = 1;
|
||||
inf = "syscall";
|
||||
break;
|
||||
case SSL_ERROR_SSL:
|
||||
print_crypto_err = 1;
|
||||
inf = "SSL, usually protocol, error";
|
||||
break;
|
||||
default:
|
||||
inf = "unknown SSL_get_error result code";
|
||||
print_errno = 1;
|
||||
print_crypto_err = 1;
|
||||
}
|
||||
if(print_crypto_err) {
|
||||
if(print_errno) {
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "%s with errno %s",
|
||||
str, strerror(errno));
|
||||
if(err_present)
|
||||
log_crypto_err_code(buf, err);
|
||||
else log_crypto_err(buf);
|
||||
} else {
|
||||
if(err_present)
|
||||
log_crypto_err_code(str, err);
|
||||
else log_crypto_err(str);
|
||||
}
|
||||
} else {
|
||||
if(print_errno) {
|
||||
if(errno == 0)
|
||||
log_err("str: syscall error with errno %s",
|
||||
strerror(errno));
|
||||
else log_err("str: %s", strerror(errno));
|
||||
} else {
|
||||
log_err("str: %s", inf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
void log_crypto_err_io(const char* str, int r)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
log_crypto_err_io_code_arg(str, r, 0, 0);
|
||||
#else
|
||||
(void)str;
|
||||
(void)r;
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
|
||||
void log_crypto_err_io_code(const char* str, int r, unsigned long err)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
log_crypto_err_io_code_arg(str, r, err, 1);
|
||||
#else
|
||||
(void)str;
|
||||
(void)r;
|
||||
(void)err;
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
/** log certificate details */
|
||||
void
|
||||
|
|
|
@ -429,6 +429,24 @@ void log_crypto_err(const char* str);
|
|||
*/
|
||||
void log_crypto_err_code(const char* str, unsigned long err);
|
||||
|
||||
/**
|
||||
* Log an error from libcrypto that came from SSL_write and so on, with
|
||||
* a value from SSL_get_error, calls log_err. If that fails it logs with
|
||||
* log_crypto_err.
|
||||
* @param str: what failed
|
||||
* @param r: output of SSL_get_error on the I/O operation result.
|
||||
*/
|
||||
void log_crypto_err_io(const char* str, int r);
|
||||
|
||||
/**
|
||||
* Log an error from libcrypt that came from an I/O routine with the
|
||||
* errcode from ERR_get_error. Calls log_err() and log_crypto_err_code.
|
||||
* @param str: what failed
|
||||
* @param r: output of SSL_get_error on the I/O operation result.
|
||||
* @param err: error code from ERR_get_error
|
||||
*/
|
||||
void log_crypto_err_io_code(const char* str, int r, unsigned long err);
|
||||
|
||||
/**
|
||||
* Log certificate details verbosity, string, of X509 cert
|
||||
* @param level: verbosity level
|
||||
|
|
|
@ -892,15 +892,18 @@ static int udp_recv_needs_log(int err)
|
|||
static int consume_pp2_header(struct sldns_buffer* buf, struct comm_reply* rep,
|
||||
int stream) {
|
||||
size_t size;
|
||||
struct pp2_header *header = pp2_read_header(buf);
|
||||
if(header == NULL) return 0;
|
||||
struct pp2_header *header;
|
||||
int err = pp2_read_header(sldns_buffer_begin(buf),
|
||||
sldns_buffer_remaining(buf));
|
||||
if(err) return 0;
|
||||
header = (struct pp2_header*)sldns_buffer_begin(buf);
|
||||
size = PP2_HEADER_SIZE + ntohs(header->len);
|
||||
if((header->ver_cmd & 0xF) == PP2_CMD_LOCAL) {
|
||||
/* A connection from the proxy itself.
|
||||
* No need to do anything with addresses. */
|
||||
goto done;
|
||||
}
|
||||
if(header->fam_prot == 0x00) {
|
||||
if(header->fam_prot == PP2_UNSPEC_UNSPEC) {
|
||||
/* Unspecified family and protocol. This could be used for
|
||||
* health checks by proxies.
|
||||
* No need to do anything with addresses. */
|
||||
|
@ -908,8 +911,8 @@ static int consume_pp2_header(struct sldns_buffer* buf, struct comm_reply* rep,
|
|||
}
|
||||
/* Read the proxied address */
|
||||
switch(header->fam_prot) {
|
||||
case 0x11: /* AF_INET|STREAM */
|
||||
case 0x12: /* AF_INET|DGRAM */
|
||||
case PP2_INET_STREAM:
|
||||
case PP2_INET_DGRAM:
|
||||
{
|
||||
struct sockaddr_in* addr =
|
||||
(struct sockaddr_in*)&rep->client_addr;
|
||||
|
@ -920,8 +923,8 @@ static int consume_pp2_header(struct sldns_buffer* buf, struct comm_reply* rep,
|
|||
}
|
||||
/* Ignore the destination address; it should be us. */
|
||||
break;
|
||||
case 0x21: /* AF_INET6|STREAM */
|
||||
case 0x22: /* AF_INET6|DGRAM */
|
||||
case PP2_INET6_STREAM:
|
||||
case PP2_INET6_DGRAM:
|
||||
{
|
||||
struct sockaddr_in6* addr =
|
||||
(struct sockaddr_in6*)&rep->client_addr;
|
||||
|
@ -934,6 +937,10 @@ static int consume_pp2_header(struct sldns_buffer* buf, struct comm_reply* rep,
|
|||
}
|
||||
/* Ignore the destination address; it should be us. */
|
||||
break;
|
||||
default:
|
||||
log_err("proxy_protocol: unsupported family and "
|
||||
"protocol 0x%x", (int)header->fam_prot);
|
||||
return 0;
|
||||
}
|
||||
rep->is_proxied = 1;
|
||||
done:
|
||||
|
@ -948,10 +955,10 @@ done:
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(HAVE_RECVMSG)
|
||||
void
|
||||
comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
||||
{
|
||||
#if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(HAVE_RECVMSG)
|
||||
struct comm_reply rep;
|
||||
struct msghdr msg;
|
||||
struct iovec iov[1];
|
||||
|
@ -1063,21 +1070,21 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
|||
fptr_ok(fptr_whitelist_comm_point(rep.c->callback));
|
||||
if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) {
|
||||
/* send back immediate reply */
|
||||
(void)comm_point_send_udp_msg_if(rep.c, rep.c->buffer,
|
||||
struct sldns_buffer *buffer;
|
||||
#ifdef USE_DNSCRYPT
|
||||
buffer = rep.c->dnscrypt_buffer;
|
||||
#else
|
||||
buffer = rep.c->buffer;
|
||||
#endif
|
||||
(void)comm_point_send_udp_msg_if(rep.c, buffer,
|
||||
(struct sockaddr*)&rep.remote_addr,
|
||||
rep.remote_addrlen, &rep);
|
||||
}
|
||||
if(!rep.c || rep.c->fd == -1) /* commpoint closed */
|
||||
break;
|
||||
}
|
||||
#else
|
||||
(void)fd;
|
||||
(void)event;
|
||||
(void)arg;
|
||||
fatal_exit("recvmsg: No support for IPV6_PKTINFO; IP_PKTINFO or IP_RECVDSTADDR. "
|
||||
"Please disable interface-automatic");
|
||||
#endif /* AF_INET6 && IPV6_PKTINFO && HAVE_RECVMSG */
|
||||
}
|
||||
#endif /* AF_INET6 && IPV6_PKTINFO && HAVE_RECVMSG */
|
||||
|
||||
void
|
||||
comm_point_udp_callback(int fd, short event, void* arg)
|
||||
|
@ -1665,7 +1672,13 @@ ssl_handshake(struct comm_point* c)
|
|||
} else {
|
||||
unsigned long err = ERR_get_error();
|
||||
if(!squelch_err_ssl_handshake(err)) {
|
||||
log_crypto_err_code("ssl handshake failed", err);
|
||||
long vr;
|
||||
log_crypto_err_io_code("ssl handshake failed",
|
||||
want, err);
|
||||
if((vr=SSL_get_verify_result(c->ssl)) != 0)
|
||||
log_err("ssl handshake cert error: %s",
|
||||
X509_verify_cert_error_string(
|
||||
vr));
|
||||
log_addr(VERB_OPS, "ssl handshake failed",
|
||||
&c->repinfo.remote_addr,
|
||||
c->repinfo.remote_addrlen);
|
||||
|
@ -1740,6 +1753,9 @@ ssl_handshake(struct comm_point* c)
|
|||
/* connection upgraded to HTTP2 */
|
||||
c->tcp_do_toggle_rw = 0;
|
||||
c->use_h2 = 1;
|
||||
} else {
|
||||
verbose(VERB_ALGO, "client doesn't support HTTP/2");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1815,23 +1831,30 @@ ssl_handle_read(struct comm_point* c)
|
|||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
log_crypto_err("could not SSL_read");
|
||||
log_crypto_err_io("could not SSL_read",
|
||||
want);
|
||||
return 0;
|
||||
}
|
||||
c->tcp_byte_count += r;
|
||||
sldns_buffer_skip(c->buffer, r);
|
||||
if(c->tcp_byte_count != current_read_size) return 1;
|
||||
c->pp2_header_state = pp2_header_init;
|
||||
}
|
||||
}
|
||||
if(c->pp2_header_state == pp2_header_init) {
|
||||
header = pp2_read_header(c->buffer);
|
||||
if(!header) {
|
||||
int err;
|
||||
err = pp2_read_header(
|
||||
sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_limit(c->buffer));
|
||||
if(err) {
|
||||
log_err("proxy_protocol: could not parse "
|
||||
"PROXYv2 header");
|
||||
"PROXYv2 header (%s)",
|
||||
pp_lookup_error(err));
|
||||
return 0;
|
||||
}
|
||||
header = (struct pp2_header*)sldns_buffer_begin(c->buffer);
|
||||
want_read_size = ntohs(header->len);
|
||||
if(sldns_buffer_remaining(c->buffer) <
|
||||
if(sldns_buffer_limit(c->buffer) <
|
||||
PP2_HEADER_SIZE + want_read_size) {
|
||||
log_err_addr("proxy_protocol: not enough "
|
||||
"buffer size to read PROXYv2 header", "",
|
||||
|
@ -1876,10 +1899,12 @@ ssl_handle_read(struct comm_point* c)
|
|||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
log_crypto_err("could not SSL_read");
|
||||
log_crypto_err_io("could not SSL_read",
|
||||
want);
|
||||
return 0;
|
||||
}
|
||||
c->tcp_byte_count += r;
|
||||
sldns_buffer_skip(c->buffer, r);
|
||||
if(c->tcp_byte_count != current_read_size) return 1;
|
||||
c->pp2_header_state = pp2_header_done;
|
||||
}
|
||||
|
@ -1890,6 +1915,7 @@ ssl_handle_read(struct comm_point* c)
|
|||
c->repinfo.remote_addrlen);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_flip(c->buffer);
|
||||
if(!consume_pp2_header(c->buffer, &c->repinfo, 1)) {
|
||||
log_err_addr("proxy_protocol: could not consume "
|
||||
"PROXYv2 header", "", &c->repinfo.remote_addr,
|
||||
|
@ -1934,7 +1960,7 @@ ssl_handle_read(struct comm_point* c)
|
|||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
log_crypto_err("could not SSL_read");
|
||||
log_crypto_err_io("could not SSL_read", want);
|
||||
return 0;
|
||||
}
|
||||
c->tcp_byte_count += r;
|
||||
|
@ -1984,7 +2010,7 @@ ssl_handle_read(struct comm_point* c)
|
|||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
log_crypto_err("could not SSL_read");
|
||||
log_crypto_err_io("could not SSL_read", want);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_skip(c->buffer, (ssize_t)r);
|
||||
|
@ -2075,7 +2101,7 @@ ssl_handle_write(struct comm_point* c)
|
|||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
log_crypto_err("could not SSL_write");
|
||||
log_crypto_err_io("could not SSL_write", want);
|
||||
return 0;
|
||||
}
|
||||
if(c->tcp_write_and_read) {
|
||||
|
@ -2127,7 +2153,7 @@ ssl_handle_write(struct comm_point* c)
|
|||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
log_crypto_err("could not SSL_write");
|
||||
log_crypto_err_io("could not SSL_write", want);
|
||||
return 0;
|
||||
}
|
||||
if(c->tcp_write_and_read) {
|
||||
|
@ -2211,19 +2237,25 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
|
|||
goto recv_error_initial;
|
||||
}
|
||||
c->tcp_byte_count += r;
|
||||
sldns_buffer_skip(c->buffer, r);
|
||||
if(c->tcp_byte_count != current_read_size) return 1;
|
||||
c->pp2_header_state = pp2_header_init;
|
||||
}
|
||||
}
|
||||
if(c->pp2_header_state == pp2_header_init) {
|
||||
header = pp2_read_header(c->buffer);
|
||||
if(!header) {
|
||||
int err;
|
||||
err = pp2_read_header(
|
||||
sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_limit(c->buffer));
|
||||
if(err) {
|
||||
log_err("proxy_protocol: could not parse "
|
||||
"PROXYv2 header");
|
||||
"PROXYv2 header (%s)",
|
||||
pp_lookup_error(err));
|
||||
return 0;
|
||||
}
|
||||
header = (struct pp2_header*)sldns_buffer_begin(c->buffer);
|
||||
want_read_size = ntohs(header->len);
|
||||
if(sldns_buffer_remaining(c->buffer) <
|
||||
if(sldns_buffer_limit(c->buffer) <
|
||||
PP2_HEADER_SIZE + want_read_size) {
|
||||
log_err_addr("proxy_protocol: not enough "
|
||||
"buffer size to read PROXYv2 header", "",
|
||||
|
@ -2250,6 +2282,7 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
|
|||
goto recv_error;
|
||||
}
|
||||
c->tcp_byte_count += r;
|
||||
sldns_buffer_skip(c->buffer, r);
|
||||
if(c->tcp_byte_count != current_read_size) return 1;
|
||||
c->pp2_header_state = pp2_header_done;
|
||||
}
|
||||
|
@ -2260,6 +2293,7 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
|
|||
c->repinfo.remote_addrlen);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_flip(c->buffer);
|
||||
if(!consume_pp2_header(c->buffer, &c->repinfo, 1)) {
|
||||
log_err_addr("proxy_protocol: could not consume "
|
||||
"PROXYv2 header", "", &c->repinfo.remote_addr,
|
||||
|
@ -2913,7 +2947,7 @@ ssl_http_read_more(struct comm_point* c)
|
|||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
log_crypto_err("could not SSL_read");
|
||||
log_crypto_err_io("could not SSL_read", want);
|
||||
return 0;
|
||||
}
|
||||
verbose(VERB_ALGO, "ssl http read more skip to %d + %d",
|
||||
|
@ -3364,7 +3398,7 @@ ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf,
|
|||
strerror(errno));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
log_crypto_err("could not SSL_read");
|
||||
log_crypto_err_io("could not SSL_read", want);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return r;
|
||||
|
@ -3619,7 +3653,7 @@ ssl_http_write_more(struct comm_point* c)
|
|||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
log_crypto_err("could not SSL_write");
|
||||
log_crypto_err_io("could not SSL_write", want);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_skip(c->buffer, (ssize_t)r);
|
||||
|
@ -3692,7 +3726,7 @@ ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session), const uint8_t* buf,
|
|||
strerror(errno));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
log_crypto_err("could not SSL_write");
|
||||
log_crypto_err_io("could not SSL_write", want);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return r;
|
||||
|
@ -3958,11 +3992,7 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
|
|||
evbits = UB_EV_READ | UB_EV_PERSIST;
|
||||
/* ub_event stuff */
|
||||
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
|
||||
#ifdef USE_WINSOCK
|
||||
comm_point_udp_callback, c);
|
||||
#else
|
||||
comm_point_udp_ancil_callback, c);
|
||||
#endif
|
||||
if(c->ev->ev == NULL) {
|
||||
log_err("could not baseset udp event");
|
||||
comm_point_delete(c);
|
||||
|
@ -3977,6 +4007,7 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
|
|||
return c;
|
||||
}
|
||||
|
||||
#if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(HAVE_RECVMSG)
|
||||
struct comm_point*
|
||||
comm_point_create_udp_ancil(struct comm_base *base, int fd,
|
||||
sldns_buffer* buffer, int pp2_enabled,
|
||||
|
@ -4039,6 +4070,7 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
|
|||
c->event_added = 1;
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct comm_point*
|
||||
comm_point_create_tcp_handler(struct comm_base *base,
|
||||
|
@ -4742,7 +4774,7 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
|||
if(repinfo->c->dtenv != NULL && repinfo->c->dtenv->log_client_response_messages) {
|
||||
log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
|
||||
log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
|
||||
dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->buffer);
|
||||
dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl, repinfo->c->buffer);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
|
@ -4753,7 +4785,7 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
|||
if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->dtenv->log_client_response_messages) {
|
||||
log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
|
||||
log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
|
||||
dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type,
|
||||
dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl,
|
||||
( repinfo->c->tcp_req_info? repinfo->c->tcp_req_info->spool_buffer: repinfo->c->buffer ));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -38,102 +38,162 @@
|
|||
*
|
||||
* This file contains PROXY protocol functions.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "util/log.h"
|
||||
#include "util/proxy_protocol.h"
|
||||
|
||||
int
|
||||
pp2_write_to_buf(struct sldns_buffer* buf, struct sockaddr_storage* src,
|
||||
/**
|
||||
* Internal struct initialized with function pointers for writing uint16 and
|
||||
* uint32.
|
||||
*/
|
||||
struct proxy_protocol_data {
|
||||
void (*write_uint16)(void* buf, uint16_t data);
|
||||
void (*write_uint32)(void* buf, uint32_t data);
|
||||
};
|
||||
struct proxy_protocol_data pp_data;
|
||||
|
||||
/**
|
||||
* Internal lookup table; could be further generic like sldns_lookup_table
|
||||
* for all the future generic stuff.
|
||||
*/
|
||||
struct proxy_protocol_lookup_table {
|
||||
int id;
|
||||
const char *text;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal parsing error text; could be exposed with pp_lookup_error.
|
||||
*/
|
||||
static struct proxy_protocol_lookup_table pp_parse_errors_data[] = {
|
||||
{ PP_PARSE_NOERROR, "no parse error" },
|
||||
{ PP_PARSE_SIZE, "not enough space for header" },
|
||||
{ PP_PARSE_WRONG_HEADERv2, "could not match PROXYv2 header" },
|
||||
{ PP_PARSE_UNKNOWN_CMD, "unknown command" },
|
||||
{ PP_PARSE_UNKNOWN_FAM_PROT, "unknown family and protocol" },
|
||||
};
|
||||
|
||||
void
|
||||
pp_init(void (*write_uint16)(void* buf, uint16_t data),
|
||||
void (*write_uint32)(void* buf, uint32_t data)) {
|
||||
pp_data.write_uint16 = write_uint16;
|
||||
pp_data.write_uint32 = write_uint32;
|
||||
}
|
||||
|
||||
const char*
|
||||
pp_lookup_error(enum pp_parse_errors error) {
|
||||
return pp_parse_errors_data[error].text;
|
||||
}
|
||||
|
||||
size_t
|
||||
pp2_write_to_buf(uint8_t* buf, size_t buflen,
|
||||
#ifdef INET6
|
||||
struct sockaddr_storage* src,
|
||||
#else
|
||||
struct sockaddr_in* src,
|
||||
#endif
|
||||
int stream)
|
||||
{
|
||||
int af;
|
||||
size_t expected_size;
|
||||
if(!src) return 0;
|
||||
af = (int)((struct sockaddr_in*)src)->sin_family;
|
||||
if(sldns_buffer_remaining(buf) <
|
||||
PP2_HEADER_SIZE + (af==AF_INET?12:36)) {
|
||||
expected_size = PP2_HEADER_SIZE + (af==AF_INET?12:36);
|
||||
if(buflen < expected_size) {
|
||||
return 0;
|
||||
}
|
||||
/* sig */
|
||||
sldns_buffer_write(buf, PP2_SIG, PP2_SIG_LEN);
|
||||
memcpy(buf, PP2_SIG, PP2_SIG_LEN);
|
||||
buf += PP2_SIG_LEN;
|
||||
/* version and command */
|
||||
sldns_buffer_write_u8(buf, (PP2_VERSION << 4) | PP2_CMD_PROXY);
|
||||
if(af==AF_INET) {
|
||||
*buf = (PP2_VERSION << 4) | PP2_CMD_PROXY;
|
||||
buf++;
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
/* family and protocol */
|
||||
sldns_buffer_write_u8(buf,
|
||||
(PP2_AF_INET<<4) |
|
||||
(stream?PP2_PROT_STREAM:PP2_PROT_DGRAM));
|
||||
*buf = (PP2_AF_INET<<4) |
|
||||
(stream?PP2_PROT_STREAM:PP2_PROT_DGRAM);
|
||||
buf++;
|
||||
/* length */
|
||||
sldns_buffer_write_u16(buf, 12);
|
||||
(*pp_data.write_uint16)(buf, 12);
|
||||
buf += 2;
|
||||
/* src addr */
|
||||
sldns_buffer_write(buf,
|
||||
memcpy(buf,
|
||||
&((struct sockaddr_in*)src)->sin_addr.s_addr, 4);
|
||||
buf += 4;
|
||||
/* dst addr */
|
||||
sldns_buffer_write_u32(buf, 0);
|
||||
(*pp_data.write_uint32)(buf, 0);
|
||||
buf += 4;
|
||||
/* src port */
|
||||
sldns_buffer_write(buf,
|
||||
memcpy(buf,
|
||||
&((struct sockaddr_in*)src)->sin_port, 2);
|
||||
/* dst port */
|
||||
sldns_buffer_write_u16(buf, 0);
|
||||
} else {
|
||||
/* family and protocol */
|
||||
sldns_buffer_write_u8(buf,
|
||||
(PP2_AF_INET6<<4) |
|
||||
(stream?PP2_PROT_STREAM:PP2_PROT_DGRAM));
|
||||
/* length */
|
||||
sldns_buffer_write_u16(buf, 36);
|
||||
/* src addr */
|
||||
sldns_buffer_write(buf,
|
||||
&((struct sockaddr_in6*)src)->sin6_addr, 16);
|
||||
buf += 2;
|
||||
/* dst addr */
|
||||
sldns_buffer_set_at(buf,
|
||||
sldns_buffer_position(buf), 0, 16);
|
||||
sldns_buffer_skip(buf, 16);
|
||||
/* src port */
|
||||
sldns_buffer_write(buf,
|
||||
&((struct sockaddr_in6*)src)->sin6_port, 2);
|
||||
/* dst port */
|
||||
sldns_buffer_write_u16(buf, 0);
|
||||
(*pp_data.write_uint16)(buf, 12);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
/* family and protocol */
|
||||
*buf = (PP2_AF_INET6<<4) |
|
||||
(stream?PP2_PROT_STREAM:PP2_PROT_DGRAM);
|
||||
buf++;
|
||||
/* length */
|
||||
(*pp_data.write_uint16)(buf, 36);
|
||||
buf += 2;
|
||||
/* src addr */
|
||||
memcpy(buf,
|
||||
&((struct sockaddr_in6*)src)->sin6_addr, 16);
|
||||
buf += 16;
|
||||
/* dst addr */
|
||||
memset(buf, 0, 16);
|
||||
buf += 16;
|
||||
/* src port */
|
||||
memcpy(buf, &((struct sockaddr_in6*)src)->sin6_port, 2);
|
||||
buf += 2;
|
||||
/* dst port */
|
||||
(*pp_data.write_uint16)(buf, 0);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
case AF_UNIX:
|
||||
/* fallthrough */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
return expected_size;
|
||||
}
|
||||
|
||||
struct pp2_header*
|
||||
pp2_read_header(struct sldns_buffer* buf)
|
||||
int
|
||||
pp2_read_header(uint8_t* buf, size_t buflen)
|
||||
{
|
||||
size_t size;
|
||||
struct pp2_header* header = (struct pp2_header*)sldns_buffer_begin(buf);
|
||||
struct pp2_header* header = (struct pp2_header*)buf;
|
||||
/* Try to fail all the unsupported cases first. */
|
||||
if(sldns_buffer_remaining(buf) < PP2_HEADER_SIZE) {
|
||||
log_err("proxy_protocol: not enough space for header");
|
||||
return NULL;
|
||||
if(buflen < PP2_HEADER_SIZE) {
|
||||
return PP_PARSE_SIZE;
|
||||
}
|
||||
/* Check for PROXYv2 header */
|
||||
if(memcmp(header, PP2_SIG, PP2_SIG_LEN) != 0 ||
|
||||
((header->ver_cmd & 0xF0)>>4) != PP2_VERSION) {
|
||||
log_err("proxy_protocol: could not match PROXYv2 header");
|
||||
return NULL;
|
||||
return PP_PARSE_WRONG_HEADERv2;
|
||||
}
|
||||
/* Check the length */
|
||||
size = PP2_HEADER_SIZE + ntohs(header->len);
|
||||
if(sldns_buffer_remaining(buf) < size) {
|
||||
log_err("proxy_protocol: not enough space for header");
|
||||
return NULL;
|
||||
if(buflen < size) {
|
||||
return PP_PARSE_SIZE;
|
||||
}
|
||||
/* Check for supported commands */
|
||||
if((header->ver_cmd & 0xF) != PP2_CMD_LOCAL &&
|
||||
(header->ver_cmd & 0xF) != PP2_CMD_PROXY) {
|
||||
log_err("proxy_protocol: unsupported command");
|
||||
return NULL;
|
||||
return PP_PARSE_UNKNOWN_CMD;
|
||||
}
|
||||
/* Check for supported family and protocol */
|
||||
if(header->fam_prot != 0x00 /* AF_UNSPEC|UNSPEC */ &&
|
||||
header->fam_prot != 0x11 /* AF_INET|STREAM */ &&
|
||||
header->fam_prot != 0x12 /* AF_INET|DGRAM */ &&
|
||||
header->fam_prot != 0x21 /* AF_INET6|STREAM */ &&
|
||||
header->fam_prot != 0x22 /* AF_INET6|DGRAM */) {
|
||||
log_err("proxy_protocol: unsupported family and protocol");
|
||||
return NULL;
|
||||
if(header->fam_prot != PP2_UNSPEC_UNSPEC &&
|
||||
header->fam_prot != PP2_INET_STREAM &&
|
||||
header->fam_prot != PP2_INET_DGRAM &&
|
||||
header->fam_prot != PP2_INET6_STREAM &&
|
||||
header->fam_prot != PP2_INET6_DGRAM &&
|
||||
header->fam_prot != PP2_UNIX_STREAM &&
|
||||
header->fam_prot != PP2_UNIX_DGRAM) {
|
||||
return PP_PARSE_UNKNOWN_FAM_PROT;
|
||||
}
|
||||
/* We have a correct header */
|
||||
return header;
|
||||
return PP_PARSE_NOERROR;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#ifndef PROXY_PROTOCOL_H
|
||||
#define PROXY_PROTOCOL_H
|
||||
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "config.h"
|
||||
|
||||
/** PROXYv2 minimum header size */
|
||||
#define PP2_HEADER_SIZE 16
|
||||
|
@ -51,11 +51,11 @@
|
|||
#define PP2_SIG "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
|
||||
#define PP2_SIG_LEN 12
|
||||
|
||||
/** PROXYv2 version */
|
||||
/** PROXYv2 version (protocol value) */
|
||||
#define PP2_VERSION 0x2
|
||||
|
||||
/**
|
||||
* PROXYv2 command.
|
||||
* PROXYv2 command (protocol value).
|
||||
*/
|
||||
enum pp2_command {
|
||||
PP2_CMD_LOCAL = 0x0,
|
||||
|
@ -63,7 +63,7 @@ enum pp2_command {
|
|||
};
|
||||
|
||||
/**
|
||||
* PROXYv2 address family.
|
||||
* PROXYv2 address family (protocol value).
|
||||
*/
|
||||
enum pp2_af {
|
||||
PP2_AF_UNSPEC = 0x0,
|
||||
|
@ -73,7 +73,7 @@ enum pp2_af {
|
|||
};
|
||||
|
||||
/**
|
||||
* PROXYv2 protocol.
|
||||
* PROXYv2 protocol (protocol value).
|
||||
*/
|
||||
enum pp2_protocol {
|
||||
PP2_PROT_UNSPEC = 0x0,
|
||||
|
@ -81,6 +81,19 @@ enum pp2_protocol {
|
|||
PP2_PROT_DGRAM = 0x2
|
||||
};
|
||||
|
||||
/**
|
||||
* Expected combinations of address family and protocol values used in checks.
|
||||
*/
|
||||
enum pp2_af_protocol_combination {
|
||||
PP2_UNSPEC_UNSPEC = (PP2_AF_UNSPEC<<4)|PP2_PROT_UNSPEC,
|
||||
PP2_INET_STREAM = (PP2_AF_INET<<4)|PP2_PROT_STREAM,
|
||||
PP2_INET_DGRAM = (PP2_AF_INET<<4)|PP2_PROT_DGRAM,
|
||||
PP2_INET6_STREAM = (PP2_AF_INET6<<4)|PP2_PROT_STREAM,
|
||||
PP2_INET6_DGRAM = (PP2_AF_INET6<<4)|PP2_PROT_DGRAM,
|
||||
PP2_UNIX_STREAM = (PP2_AF_UNIX<<4)|PP2_PROT_STREAM,
|
||||
PP2_UNIX_DGRAM = (PP2_AF_UNIX<<4)|PP2_PROT_DGRAM
|
||||
};
|
||||
|
||||
/**
|
||||
* PROXYv2 header.
|
||||
*/
|
||||
|
@ -109,23 +122,56 @@ struct pp2_header {
|
|||
} addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* PROXY parse errors.
|
||||
*/
|
||||
enum pp_parse_errors {
|
||||
PP_PARSE_NOERROR = 0,
|
||||
PP_PARSE_SIZE,
|
||||
PP_PARSE_WRONG_HEADERv2,
|
||||
PP_PARSE_UNKNOWN_CMD,
|
||||
PP_PARSE_UNKNOWN_FAM_PROT,
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the internal proxy structure.
|
||||
* @param write_uint16: pointer to a function that can write uint16.
|
||||
* @param write_uint32: pointer to a function that can write uint32.
|
||||
*/
|
||||
void pp_init(void (*write_uint16)(void* buf, uint16_t data),
|
||||
void (*write_uint32)(void* buf, uint32_t data));
|
||||
|
||||
/**
|
||||
* Lookup the parsing error description.
|
||||
* @param error: parsing error from pp2_read_header.
|
||||
* @return the description.
|
||||
*/
|
||||
const char* pp_lookup_error(enum pp_parse_errors error);
|
||||
|
||||
/**
|
||||
* Write a PROXYv2 header at the current position of the buffer.
|
||||
* @param buf: the buffer to write to.
|
||||
* @param buf: pointer to the buffer to write data to.
|
||||
* @param buflen: available size on the buffer.
|
||||
* @param src: the source address.
|
||||
* @param stream: if the protocol is stream or datagram.
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
int pp2_write_to_buf(struct sldns_buffer* buf, struct sockaddr_storage* src,
|
||||
size_t pp2_write_to_buf(uint8_t* buf, size_t buflen,
|
||||
#ifdef INET6
|
||||
struct sockaddr_storage* src,
|
||||
#else
|
||||
struct sockaddr_in* src,
|
||||
#endif
|
||||
int stream);
|
||||
|
||||
/**
|
||||
* Read a PROXYv2 header from the current position of the buffer.
|
||||
* It does initial validation and returns a pointer to the buffer position on
|
||||
* success.
|
||||
* @param buf: the buffer to read from.
|
||||
* @return the pointer to the buffer position on success, NULL on error.
|
||||
* @param buf: pointer to the buffer data to read from.
|
||||
* @param buflen: available size on the buffer.
|
||||
* @return parsing error, 0 on success.
|
||||
*/
|
||||
struct pp2_header* pp2_read_header(struct sldns_buffer* buf);
|
||||
int pp2_read_header(uint8_t* buf, size_t buflen);
|
||||
|
||||
#endif /* PROXY_PROTOCOL_H */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue