Add support EDNS TCP-keep-alive
This commit is contained in:
96
src/dns.c
96
src/dns.c
@@ -117,6 +117,10 @@ struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, dns_rr_type type, i
|
|||||||
*count = head->nrcount;
|
*count = head->nrcount;
|
||||||
start = packet->additional;
|
start = packet->additional;
|
||||||
break;
|
break;
|
||||||
|
case DNS_RRS_OPT:
|
||||||
|
*count = packet->optcount;
|
||||||
|
start = packet->optional;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
@@ -425,6 +429,29 @@ static int _dns_get_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _dns_add_opt_RAW(struct dns_packet *packet, dns_opt_code_t opt_rrtype, void *raw, int raw_len)
|
||||||
|
{
|
||||||
|
unsigned char opt_data[DNS_MAX_OPT_LEN];
|
||||||
|
struct dns_opt *opt = (struct dns_opt *)opt_data;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
opt->code = DNS_OPT_T_TCP_KEEPALIVE;
|
||||||
|
opt->length = sizeof(unsigned short);
|
||||||
|
|
||||||
|
memcpy(opt->data, raw, raw_len);
|
||||||
|
len += raw_len;
|
||||||
|
len += sizeof(*opt);
|
||||||
|
|
||||||
|
return _dns_add_RAW(packet, DNS_RRS_OPT, DNS_OPT_T_TCP_KEEPALIVE, "", 0, opt_data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _dns_get_opt_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct dns_opt *dns_opt, int *dns_optlen)
|
||||||
|
{
|
||||||
|
*dns_optlen = DNS_MAX_OPT_LEN;
|
||||||
|
|
||||||
|
return _dns_get_RAW(rrs, domain, maxsize, ttl, dns_opt, dns_optlen);
|
||||||
|
}
|
||||||
|
|
||||||
static int __attribute__((unused)) _dns_add_OPT(struct dns_packet *packet, dns_rr_type type, unsigned short opt_code, unsigned short opt_len, struct dns_opt *opt)
|
static int __attribute__((unused)) _dns_add_OPT(struct dns_packet *packet, dns_rr_type type, unsigned short opt_code, unsigned short opt_len, struct dns_opt *opt)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
@@ -704,6 +731,54 @@ int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned shor
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dns_add_OPT_TCP_KEEYALIVE(struct dns_packet *packet, unsigned short timeout)
|
||||||
|
{
|
||||||
|
unsigned short timeout_net = htons(timeout);
|
||||||
|
int data_len = 0;
|
||||||
|
|
||||||
|
if (timeout > 0) {
|
||||||
|
data_len = sizeof(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _dns_add_opt_RAW(packet, DNS_OPT_T_TCP_KEEPALIVE, &timeout_net, data_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_get_OPT_TCP_KEEYALIVE(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, unsigned short *timeout)
|
||||||
|
{
|
||||||
|
unsigned char opt_data[DNS_MAX_OPT_LEN];
|
||||||
|
struct dns_opt *opt = (struct dns_opt *)opt_data;
|
||||||
|
int len = DNS_MAX_OPT_LEN;
|
||||||
|
int ttl = 0;
|
||||||
|
unsigned char *data = NULL;
|
||||||
|
|
||||||
|
if (_dns_get_opt_RAW(rrs, NULL, 0, &ttl, opt, &len) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len < sizeof(*opt)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt->code != DNS_OPT_T_TCP_KEEPALIVE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt->length == 0) {
|
||||||
|
*timeout = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt->length != sizeof(unsigned short)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = opt->data;
|
||||||
|
|
||||||
|
*timeout = _dns_read_short(&data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format:
|
* Format:
|
||||||
* |DNS_NAME\0(string)|qtype(short)|qclass(short)|
|
* |DNS_NAME\0(string)|qtype(short)|qclass(short)|
|
||||||
@@ -1292,6 +1367,7 @@ static int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
|
|||||||
struct dns_data_context data_context;
|
struct dns_data_context data_context;
|
||||||
int rr_len = 0;
|
int rr_len = 0;
|
||||||
int ttl;
|
int ttl;
|
||||||
|
struct dns_opt *dns_opt = NULL;
|
||||||
|
|
||||||
data_context.data = rrs->data;
|
data_context.data = rrs->data;
|
||||||
data_context.ptr = rrs->data;
|
data_context.ptr = rrs->data;
|
||||||
@@ -1302,14 +1378,24 @@ static int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dns_left_len(context) < (4 + rr_len)) {
|
if (rr_len < sizeof(*dns_opt)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dns_write_short(&context->ptr, opt_code);
|
if (_dns_left_len(context) < (rr_len)) {
|
||||||
_dns_write_short(&context->ptr, rr_len);
|
return -1;
|
||||||
memcpy(context->ptr, data_context.ptr, rr_len);
|
}
|
||||||
context->ptr += rr_len;
|
|
||||||
|
dns_opt = (struct dns_opt *)data_context.ptr;
|
||||||
|
_dns_write_short(&context->ptr, dns_opt->code);
|
||||||
|
_dns_write_short(&context->ptr, dns_opt->length);
|
||||||
|
|
||||||
|
if (_dns_left_len(context) < dns_opt->length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(context->ptr, dns_opt->data, dns_opt->length);
|
||||||
|
context->ptr += dns_opt->length;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ typedef enum dns_type {
|
|||||||
|
|
||||||
typedef enum dns_opt_code {
|
typedef enum dns_opt_code {
|
||||||
DNS_OPT_T_ECS = 8,
|
DNS_OPT_T_ECS = 8,
|
||||||
|
DNS_OPT_T_TCP_KEEPALIVE = 11,
|
||||||
DNS_OPT_T_ALL = 255
|
DNS_OPT_T_ALL = 255
|
||||||
} dns_opt_code_t;
|
} dns_opt_code_t;
|
||||||
|
|
||||||
@@ -191,6 +192,9 @@ int dns_get_OPT_payload_size(struct dns_packet *packet);
|
|||||||
|
|
||||||
int dns_add_OPT_ECS(struct dns_packet *packet, struct dns_opt_ecs *ecs);
|
int dns_add_OPT_ECS(struct dns_packet *packet, struct dns_opt_ecs *ecs);
|
||||||
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs);
|
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs);
|
||||||
|
|
||||||
|
int dns_add_OPT_TCP_KEEYALIVE(struct dns_packet *packet, unsigned short timeout);
|
||||||
|
int dns_get_OPT_TCP_KEEYALIVE(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, unsigned short *timeout);
|
||||||
/*
|
/*
|
||||||
* Packet operation
|
* Packet operation
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2182,7 +2182,7 @@ static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dns_set_OPT_payload_size(packet, DNS_IN_PACKSIZE);
|
dns_set_OPT_payload_size(packet, DNS_IN_PACKSIZE);
|
||||||
|
/* dns_add_OPT_TCP_KEEYALIVE(packet, 600); */
|
||||||
if (_dns_client_dns_add_ecs(packet, query->qtype) != 0) {
|
if (_dns_client_dns_add_ecs(packet, query->qtype) != 0) {
|
||||||
tlog(TLOG_ERROR, "add ecs failed.");
|
tlog(TLOG_ERROR, "add ecs failed.");
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user