diff --git a/src/dns.c b/src/dns.c index 342e7a8..f402063 100644 --- a/src/dns.c +++ b/src/dns.c @@ -1369,6 +1369,38 @@ static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs * return 0; } + +static int _dns_decode_opt_cookie(struct dns_context *context, struct dns_opt_cookie *cookie) +{ + // TODO + int len = _dns_left_len(context); + if (len < 8) { + return -1; + } + + len = 8; + memcpy(cookie->client_cookie, context->ptr, len); + context->ptr += len; + + len = _dns_left_len(context); + if (len == 0) { + cookie->server_cookie_len = 0; + return 0; + } + + if (len < 8) { + return -1; + } + + memcpy(cookie->server_cookie, context->ptr, len); + cookie->server_cookie_len = len; + context->ptr += len; + + tlog(TLOG_DEBUG, "OPT COOKIE"); + return 0; +} + + static int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs) { int ret; @@ -1551,6 +1583,14 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign return -1; } } break; + case DNS_OPT_T_COOKIE: { + struct dns_opt_cookie cookie; + ret = _dns_decode_opt_cookie(context, &cookie); + if (ret != 0) { + tlog(TLOG_ERROR, "decode cookie failed."); + return -1; + } + } break; default: context->ptr += opt_len; tlog(TLOG_DEBUG, "DNS opt type = %d not supported", opt_code); diff --git a/src/dns.h b/src/dns.h index d42aa73..592800a 100644 --- a/src/dns.h +++ b/src/dns.h @@ -68,6 +68,7 @@ typedef enum dns_type { typedef enum dns_opt_code { DNS_OPT_T_ECS = 8, // OPT ECS + DNS_OPT_T_COOKIE = 10, //OPT Cookie DNS_OPT_T_TCP_KEEPALIVE = 11, DNS_OPT_T_ALL = 255 } dns_opt_code_t; @@ -171,6 +172,13 @@ struct dns_opt_ecs { unsigned char addr[DNS_RR_AAAA_LEN]; }; +/* OPT COOLIE */ +struct dns_opt_cookie { + char server_cookie_len; + unsigned char client_cookie[8]; + unsigned char server_cookie[32]; +}; + /* OPT */ struct dns_opt { unsigned short code; diff --git a/src/dns_cache.c b/src/dns_cache.c index 6d81107..ac0c98f 100644 --- a/src/dns_cache.c +++ b/src/dns_cache.c @@ -430,7 +430,7 @@ int dns_cache_get_cname_ttl(struct dns_cache *dns_cache) } int addr_ttl = dns_cache_get_ttl(dns_cache); - if (ttl < addr_ttl) { + if (ttl < addr_ttl && ttl < 0) { return addr_ttl; } diff --git a/src/dns_server.c b/src/dns_server.c index 85c67f7..2e97686 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -586,6 +586,7 @@ static int _dns_reply(struct dns_request *request) } /* send request */ + atomic_inc_return(&request->notified); return _dns_reply_inpacket(request, inpacket, encode_len); } @@ -1802,7 +1803,7 @@ static int _dns_server_get_answer(struct dns_request *request, struct dns_packet dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN); tlog(TLOG_DEBUG, "name:%s ttl: %d cname: %s\n", name, ttl, cname); safe_strncpy(request->cname, cname, DNS_MAX_CNAME_LEN); - request->ttl_cname = ttl; + request->ttl_cname = _dns_server_get_conf_ttl(ttl); request->has_cname = 1; } break; case DNS_T_SOA: { @@ -2384,7 +2385,7 @@ static int _dns_server_get_expired_cname_ttl_reply(struct dns_cache *dns_cache) return ttl; } - return dns_conf_serve_expired_reply_ttl; + return _dns_server_get_expired_ttl_reply(dns_cache); } static int _dns_server_process_cache_addr(struct dns_request *request, struct dns_cache *dns_cache)