DNS: support parser TYPE65 RR.
This commit is contained in:
403
src/dns.c
403
src/dns.c
@@ -542,6 +542,106 @@ static int _dns_get_rr_head(struct dns_context *context, char *domain, int maxsi
|
||||
return len;
|
||||
}
|
||||
|
||||
struct dns_rr_nested *dns_add_rr_nested_start(struct dns_rr_nested *rr_nested_buffer, struct dns_packet *packet,
|
||||
dns_rr_type type, dns_type_t rtype, const char *domain, int ttl)
|
||||
{
|
||||
int len = 0;
|
||||
memset(rr_nested_buffer, 0, sizeof(*rr_nested_buffer));
|
||||
rr_nested_buffer->type = type;
|
||||
int ret = 0;
|
||||
|
||||
/* resource record */
|
||||
/* |domain |
|
||||
* |qtype | qclass |
|
||||
* | ttl |
|
||||
* | rrlen | rrdata |
|
||||
*/
|
||||
ret = _dns_add_rrs_start(packet, &rr_nested_buffer->context);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
rr_nested_buffer->rr_start = rr_nested_buffer->context.ptr;
|
||||
|
||||
/* add rr head */
|
||||
len = _dns_add_rr_head(&rr_nested_buffer->context, domain, rtype, DNS_C_IN, ttl, 0);
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
rr_nested_buffer->rr_len_ptr = rr_nested_buffer->context.ptr - 2;
|
||||
rr_nested_buffer->rr_head_len = len;
|
||||
|
||||
return rr_nested_buffer;
|
||||
}
|
||||
|
||||
int dns_add_rr_nested_memcpy(struct dns_rr_nested *rr_nested, void *data, int data_len)
|
||||
{
|
||||
if (rr_nested == NULL || data == NULL || data_len <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_dns_left_len(&rr_nested->context) < data_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(rr_nested->context.ptr, data, data_len);
|
||||
rr_nested->context.ptr += data_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_add_rr_nested_end(struct dns_rr_nested *rr_nested, dns_type_t rtype)
|
||||
{
|
||||
if (rr_nested == NULL || rr_nested->rr_start == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int len = rr_nested->context.ptr - rr_nested->rr_start;
|
||||
unsigned char *ptr = rr_nested->rr_len_ptr;
|
||||
if (ptr == NULL || _dns_left_len(&rr_nested->context) < 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_dns_write_short(&ptr, len - rr_nested->rr_head_len);
|
||||
|
||||
return _dns_rr_add_end(rr_nested->context.packet, rr_nested->type, rtype, len);
|
||||
}
|
||||
|
||||
void *dns_get_rr_nested_start(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, int *ttl, int *rr_len)
|
||||
{
|
||||
struct dns_context data_context;
|
||||
int qclass = 0;
|
||||
int ret = 0;
|
||||
|
||||
_dns_init_context_by_rrs(rrs, &data_context);
|
||||
ret = _dns_get_rr_head(&data_context, domain, DNS_MAX_CNAME_LEN, qtype, &qclass, ttl, rr_len);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (qclass != DNS_C_IN) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*rr_len < 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data_context.ptr;
|
||||
}
|
||||
|
||||
void *dns_get_rr_nested_next(struct dns_rrs *rrs, void *rr_nested, int rr_nested_len)
|
||||
{
|
||||
void *end = rrs->data + rrs->len;
|
||||
void *p = rr_nested + rr_nested_len;
|
||||
if (p == end) {
|
||||
return NULL;
|
||||
} else if (p > end) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static int _dns_add_RAW(struct dns_packet *packet, dns_rr_type rrtype, dns_type_t rtype, const char *domain, int ttl,
|
||||
const void *raw, int raw_len)
|
||||
{
|
||||
@@ -966,6 +1066,155 @@ int dns_get_OPT_TCP_KEEYALIVE(struct dns_rrs *rrs, unsigned short *opt_code, uns
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_add_HTTPS_start(struct dns_rr_nested *svcparam_buffer, struct dns_packet *packet, dns_rr_type type,
|
||||
const char *domain, int ttl, int priority, const char *target)
|
||||
{
|
||||
svcparam_buffer = dns_add_rr_nested_start(svcparam_buffer, packet, type, DNS_T_HTTPS, domain, ttl);
|
||||
if (svcparam_buffer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int target_len = strnlen(target, DNS_MAX_CNAME_LEN) + 1;
|
||||
if (_dns_left_len(&svcparam_buffer->context) < 2 + target_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* add rr data */
|
||||
_dns_write_short(&svcparam_buffer->context.ptr, priority);
|
||||
safe_strncpy((char *)svcparam_buffer->context.ptr, target, target_len);
|
||||
svcparam_buffer->context.ptr += target_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_HTTPS_add_raw(struct dns_rr_nested *svcparam, unsigned short key, unsigned char *value, unsigned short len)
|
||||
{
|
||||
if (_dns_left_len(&svcparam->context) < 2 + len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dns_add_rr_nested_memcpy(svcparam, &key, 2);
|
||||
dns_add_rr_nested_memcpy(svcparam, &len, 2);
|
||||
dns_add_rr_nested_memcpy(svcparam, value, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_HTTPS_add_port(struct dns_rr_nested *svcparam, unsigned short port)
|
||||
{
|
||||
if (_dns_left_len(&svcparam->context) < 6) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned short value = DNS_HTTPS_T_PORT;
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
value = 2;
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
value = htons(port);
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_HTTPS_add_ech(struct dns_rr_nested *svcparam, void *ech, int ech_len)
|
||||
{
|
||||
if (_dns_left_len(&svcparam->context) < 2 + 2 + ech_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned short value = DNS_HTTPS_T_ECH;
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
|
||||
value = ech_len;
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
dns_add_rr_nested_memcpy(svcparam, ech, ech_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_HTTPS_add_ipv4hint(struct dns_rr_nested *svcparam, unsigned char addr[][DNS_RR_A_LEN], int addr_num)
|
||||
{
|
||||
if (_dns_left_len(&svcparam->context) < 4 + addr_num * DNS_RR_A_LEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned short value = DNS_HTTPS_T_IPV4HINT;
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
|
||||
value = addr_num * DNS_RR_A_LEN;
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
|
||||
for (int i = 0; i < addr_num; i++) {
|
||||
dns_add_rr_nested_memcpy(svcparam, addr[i], DNS_RR_A_LEN);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int dns_HTTPS_add_ipv6hint(struct dns_rr_nested *svcparam, unsigned char addr[][DNS_RR_AAAA_LEN], int addr_num)
|
||||
{
|
||||
if (_dns_left_len(&svcparam->context) < 4 + addr_num * DNS_RR_AAAA_LEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned short value = DNS_HTTPS_T_IPV6HINT;
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
|
||||
value = addr_num * DNS_RR_AAAA_LEN;
|
||||
dns_add_rr_nested_memcpy(svcparam, &value, 2);
|
||||
|
||||
for (int i = 0; i < addr_num; i++) {
|
||||
dns_add_rr_nested_memcpy(svcparam, addr[i], DNS_RR_AAAA_LEN);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_add_HTTPS_end(struct dns_rr_nested *svcparam)
|
||||
{
|
||||
return dns_add_rr_nested_end(svcparam, DNS_T_HTTPS);
|
||||
}
|
||||
|
||||
struct dns_https_param *dns_get_HTTPS_svcparm_start(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl,
|
||||
int *priority, char *target, int target_size)
|
||||
{
|
||||
int qtype = 0;
|
||||
unsigned char *data = NULL;
|
||||
int rr_len = 0;
|
||||
|
||||
data = dns_get_rr_nested_start(rrs, domain, maxsize, &qtype, ttl, &rr_len);
|
||||
if (data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (qtype != DNS_T_HTTPS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rr_len < 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*priority = _dns_read_short(&data);
|
||||
rr_len -= 2;
|
||||
if (rr_len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int len = strnlen((char *)data, rr_len);
|
||||
safe_strncpy(target, (char *)data, target_size);
|
||||
data += len + 1;
|
||||
rr_len -= len + 1;
|
||||
if (rr_len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct dns_https_param *)data;
|
||||
}
|
||||
|
||||
struct dns_https_param *dns_get_HTTPS_svcparm_next(struct dns_rrs *rrs, struct dns_https_param *param)
|
||||
{
|
||||
return dns_get_rr_nested_next(rrs, param, sizeof(struct dns_https_param) + param->len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Format:
|
||||
* |DNS_NAME\0(string)|qtype(short)|qclass(short)|
|
||||
@@ -1624,7 +1873,7 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
|
||||
opt_len = _dns_read_short(&context->ptr);
|
||||
|
||||
if (_dns_left_len(context) < opt_len) {
|
||||
tlog(TLOG_ERROR, "read opt data failed, opt_code = %d, opt_le = %d", opt_code, opt_len);
|
||||
tlog(TLOG_ERROR, "read opt data failed, opt_code = %d, opt_len = %d", opt_code, opt_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1665,6 +1914,139 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_encode_HTTPS(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
char target[DNS_MAX_CNAME_LEN] = {0};
|
||||
unsigned char *rr_len_ptr = NULL;
|
||||
unsigned char *start = NULL;
|
||||
unsigned char *rr_start = NULL;
|
||||
int ttl = 0;
|
||||
int priority = 0;
|
||||
struct dns_https_param *param = NULL;
|
||||
|
||||
param = dns_get_HTTPS_svcparm_start(rrs, domain, DNS_MAX_CNAME_LEN, &ttl, &priority, target, DNS_MAX_CNAME_LEN);
|
||||
if (param == NULL) {
|
||||
tlog(TLOG_ERROR, "get https param failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _dns_encode_rr_head(context, domain, qtype, qclass, ttl, 0, &rr_len_ptr);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rr_start = context->ptr;
|
||||
if (_dns_left_len(context) < 2) {
|
||||
tlog(TLOG_ERROR, "left len is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
_dns_write_short(&context->ptr, priority);
|
||||
ret = _dns_encode_domain(context, target);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
start = context->ptr;
|
||||
for (; param != NULL; param = dns_get_HTTPS_svcparm_next(rrs, param)) {
|
||||
if (context->ptr - start > rrs->len || _dns_left_len(context) <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_dns_write_short(&context->ptr, param->key);
|
||||
_dns_write_short(&context->ptr, param->len);
|
||||
switch (param->key) {
|
||||
case DNS_HTTPS_T_MANDATORY:
|
||||
case DNS_HTTPS_T_NO_DEFAULT_ALPN:
|
||||
case DNS_HTTPS_T_ALPN:
|
||||
case DNS_HTTPS_T_PORT:
|
||||
case DNS_HTTPS_T_IPV4HINT:
|
||||
case DNS_HTTPS_T_ECH:
|
||||
case DNS_HTTPS_T_IPV6HINT: {
|
||||
memcpy(context->ptr, param->value, param->len);
|
||||
context->ptr += param->len;
|
||||
} break;
|
||||
default:
|
||||
/* skip unknown key */
|
||||
context->ptr -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_dns_write_short(&rr_len_ptr, context->ptr - rr_start);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_decode_HTTPS(struct dns_context *context, const char *domain, dns_rr_type type, unsigned int ttl,
|
||||
int rr_len)
|
||||
{
|
||||
unsigned char *start = context->ptr;
|
||||
|
||||
struct dns_packet *packet = context->packet;
|
||||
int ret = 0;
|
||||
unsigned short priority;
|
||||
unsigned short key;
|
||||
unsigned short value_len;
|
||||
unsigned char *value = NULL;
|
||||
char target[DNS_MAX_CNAME_LEN] = {0};
|
||||
struct dns_rr_nested param;
|
||||
|
||||
if (rr_len < 2) {
|
||||
tlog(TLOG_DEBUG, "https len is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
priority = _dns_read_short(&context->ptr);
|
||||
ret = _dns_decode_domain(context, target, sizeof(target));
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dns_add_HTTPS_start(¶m, packet, DNS_RRS_AN, domain, ttl, priority, target);
|
||||
|
||||
while (context->ptr - start < rr_len) {
|
||||
if (_dns_left_len(context) < 4) {
|
||||
tlog(TLOG_WARN, "data length is invalid, %d:%d", _dns_left_len(context),
|
||||
(int)(context->ptr - context->data));
|
||||
return -1;
|
||||
}
|
||||
key = _dns_read_short(&context->ptr);
|
||||
value_len = _dns_read_short(&context->ptr);
|
||||
value = context->ptr;
|
||||
|
||||
if (_dns_left_len(context) < value_len) {
|
||||
tlog(TLOG_ERROR, "read https data failed, svcParam key = %d, https_len = %d", key, value_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case DNS_HTTPS_T_MANDATORY:
|
||||
case DNS_HTTPS_T_ALPN:
|
||||
case DNS_HTTPS_T_NO_DEFAULT_ALPN:
|
||||
case DNS_HTTPS_T_PORT:
|
||||
case DNS_HTTPS_T_IPV4HINT:
|
||||
case DNS_HTTPS_T_ECH:
|
||||
case DNS_HTTPS_T_IPV6HINT: {
|
||||
dns_HTTPS_add_raw(¶m, key, value, value_len);
|
||||
} break;
|
||||
default:
|
||||
tlog(TLOG_DEBUG, "DNS HTTPS key = %d not supported", key);
|
||||
break;
|
||||
}
|
||||
|
||||
context->ptr += value_len;
|
||||
}
|
||||
|
||||
dns_add_HTTPS_end(¶m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_decode_qd(struct dns_context *context)
|
||||
{
|
||||
struct dns_packet *packet = context->packet;
|
||||
@@ -1808,6 +2190,19 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
|
||||
dns_set_OPT_payload_size(packet, qclass);
|
||||
} break;
|
||||
case DNS_T_HTTPS: {
|
||||
unsigned char *https_start = context->ptr;
|
||||
ret = _dns_decode_HTTPS(context, domain, type, ttl, rr_len);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_DEBUG, "decode HTTPS failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (context->ptr - https_start != rr_len) {
|
||||
tlog(TLOG_DEBUG, "opt length mismatch, %s\n", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
unsigned char raw_data[1024];
|
||||
if (_dns_left_len(context) < rr_len || rr_len >= (int)sizeof(raw_data)) {
|
||||
@@ -1886,6 +2281,12 @@ static int _dns_encode_an(struct dns_context *context, struct dns_rrs *rrs)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case DNS_T_HTTPS:
|
||||
ret = _dns_encode_HTTPS(context, rrs);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = _dns_encode_raw(context, rrs);
|
||||
if (ret < 0) {
|
||||
|
||||
62
src/dns.h
62
src/dns.h
@@ -73,13 +73,25 @@ typedef enum dns_type {
|
||||
} dns_type_t;
|
||||
|
||||
typedef enum dns_opt_code {
|
||||
DNS_OPT_T_ECS = 8, // OPT ECS
|
||||
DNS_OPT_T_COOKIE = 10, //OPT Cookie
|
||||
DNS_OPT_T_ECS = 8, // OPT ECS
|
||||
DNS_OPT_T_COOKIE = 10, // OPT Cookie
|
||||
DNS_OPT_T_TCP_KEEPALIVE = 11,
|
||||
DNS_OPT_T_PADDING = 12,
|
||||
DNS_OPT_T_ALL = 255
|
||||
} dns_opt_code_t;
|
||||
|
||||
/* https://datatracker.ietf.org/doc/draft-ietf-dnsop-svcb-https/11/ */
|
||||
typedef enum dns_htts_svcparam {
|
||||
DNS_HTTPS_T_MANDATORY = 0,
|
||||
DNS_HTTPS_T_ALPN = 1,
|
||||
DNS_HTTPS_T_NO_DEFAULT_ALPN = 2,
|
||||
DNS_HTTPS_T_PORT = 3,
|
||||
DNS_HTTPS_T_IPV4HINT = 4,
|
||||
DNS_HTTPS_T_ECH = 5,
|
||||
DNS_HTTPS_T_IPV6HINT = 6,
|
||||
DNS_HTTPS_T_ALL = 255
|
||||
} dns_htts_svcparam_t;
|
||||
|
||||
typedef enum dns_opcode {
|
||||
DNS_OP_QUERY = 0,
|
||||
DNS_OP_IQUERY = 1,
|
||||
@@ -184,7 +196,7 @@ struct dns_opt_ecs {
|
||||
unsigned char source_prefix;
|
||||
unsigned char scope_prefix;
|
||||
unsigned char addr[DNS_RR_AAAA_LEN];
|
||||
} __attribute__((packed));;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* OPT COOLIE */
|
||||
struct dns_opt_cookie {
|
||||
@@ -200,9 +212,31 @@ struct dns_opt {
|
||||
unsigned char data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct dns_rr_nested {
|
||||
struct dns_context context;
|
||||
unsigned char *rr_start;
|
||||
unsigned char *rr_len_ptr;
|
||||
unsigned short rr_head_len;
|
||||
dns_rr_type type;
|
||||
};
|
||||
|
||||
struct dns_https_param {
|
||||
unsigned short key;
|
||||
unsigned short len;
|
||||
unsigned char value[0];
|
||||
};
|
||||
|
||||
struct dns_rrs *dns_get_rrs_next(struct dns_packet *packet, struct dns_rrs *rrs);
|
||||
struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, dns_rr_type type, int *count);
|
||||
|
||||
struct dns_rr_nested *dns_add_rr_nested_start(struct dns_rr_nested *rr_nested_buffer, struct dns_packet *packet,
|
||||
dns_rr_type type, dns_type_t rtype, const char *domain, int ttl);
|
||||
int dns_add_rr_nested_end(struct dns_rr_nested *rr_nested, dns_type_t rtype);
|
||||
int dns_add_rr_nested_memcpy(struct dns_rr_nested *rr_nested, void *data, int data_len);
|
||||
|
||||
void *dns_get_rr_nested_start(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, int *ttl, int *rr_len);
|
||||
void *dns_get_rr_nested_next(struct dns_rrs *rrs, void *rr_nested, int rr_nested_len);
|
||||
|
||||
/*
|
||||
* Question
|
||||
*/
|
||||
@@ -215,7 +249,8 @@ int dns_get_domain(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, i
|
||||
int dns_add_CNAME(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, const char *cname);
|
||||
int dns_get_CNAME(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size);
|
||||
|
||||
int dns_add_A(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, unsigned char addr[DNS_RR_A_LEN]);
|
||||
int dns_add_A(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl,
|
||||
unsigned char addr[DNS_RR_A_LEN]);
|
||||
int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_A_LEN]);
|
||||
|
||||
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, char *cname);
|
||||
@@ -240,6 +275,25 @@ int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned shor
|
||||
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);
|
||||
|
||||
int dns_add_HTTPS_start(struct dns_rr_nested *svcparam_buffer, struct dns_packet *packet,
|
||||
dns_rr_type type, const char *domain, int ttl, int priority,
|
||||
const char *target);
|
||||
int dns_HTTPS_add_raw(struct dns_rr_nested *svcparam, unsigned short key, unsigned char *value, unsigned short len);
|
||||
int dns_HTTPS_add_port(struct dns_rr_nested *svcparam, unsigned short port);
|
||||
int dns_HTTPS_add_alpn(struct dns_rr_nested *svcparam, const char *alpn);
|
||||
int dns_HTTPS_add_no_default_alpn(struct dns_rr_nested *svcparam);
|
||||
int dns_HTTPS_add_ipv4hint(struct dns_rr_nested *svcparam, unsigned char addr[][DNS_RR_A_LEN],
|
||||
int addr_num);
|
||||
int dns_HTTPS_add_ipv6hint(struct dns_rr_nested *svcparam, unsigned char addr[][DNS_RR_AAAA_LEN],
|
||||
int addr_num);
|
||||
int dns_HTTPS_add_ech(struct dns_rr_nested *svcparam, void *ech, int ech_len);
|
||||
int dns_add_HTTPS_end(struct dns_rr_nested *svcparam);
|
||||
|
||||
struct dns_https_param *dns_get_HTTPS_svcparm_start(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl,
|
||||
int *priority, char *target, int target_size);
|
||||
struct dns_https_param *dns_get_HTTPS_svcparm_next(struct dns_rrs *rrs, struct dns_https_param *parm);
|
||||
|
||||
/*
|
||||
* Packet operation
|
||||
*/
|
||||
|
||||
56
src/util.c
56
src/util.c
@@ -1373,6 +1373,62 @@ static int _dns_debug_display(struct dns_packet *packet)
|
||||
inet_ntop(AF_INET6, addr, req_host, sizeof(req_host));
|
||||
printf("domain: %s AAAA: %s TTL:%d\n", name, req_host, ttl);
|
||||
} break;
|
||||
case DNS_T_HTTPS: {
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
char target[DNS_MAX_CNAME_LEN] = {0};
|
||||
struct dns_https_param *p = NULL;
|
||||
int priority = 0;
|
||||
|
||||
p = dns_get_HTTPS_svcparm_start(rrs, name, DNS_MAX_CNAME_LEN, &ttl, &priority, target,
|
||||
DNS_MAX_CNAME_LEN);
|
||||
if (p == NULL) {
|
||||
printf("get HTTPS svcparm failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("domain: %s HTTPS: %s TTL: %d priority: %d\n", name, target, ttl, priority);
|
||||
|
||||
for (; p; p = dns_get_HTTPS_svcparm_next(rrs, p)) {
|
||||
switch (p->key) {
|
||||
case DNS_HTTPS_T_MANDATORY: {
|
||||
printf(" HTTPS: mandatory: %s\n", p->value);
|
||||
} break;
|
||||
case DNS_HTTPS_T_ALPN: {
|
||||
printf(" HTTPS: alpn: %s\n", p->value);
|
||||
} break;
|
||||
case DNS_HTTPS_T_NO_DEFAULT_ALPN: {
|
||||
printf(" HTTPS: no_default_alpn: %s\n", p->value);
|
||||
} break;
|
||||
case DNS_HTTPS_T_PORT: {
|
||||
int port = *(unsigned short *)(p->value);
|
||||
printf(" HTTPS: port: %d\n", port);
|
||||
} break;
|
||||
case DNS_HTTPS_T_IPV4HINT: {
|
||||
printf(" HTTPS: ipv4hint: %d\n", p->len / 4);
|
||||
for (int k = 0; k < p->len / 4; k++) {
|
||||
char ip[16] = {0};
|
||||
inet_ntop(AF_INET, p->value + k * 4, ip, sizeof(ip));
|
||||
printf(" ipv4: %s\n", ip);
|
||||
}
|
||||
} break;
|
||||
case DNS_HTTPS_T_ECH: {
|
||||
printf(" HTTPS: ech: ");
|
||||
for (int k = 0; k < p->len; k++) {
|
||||
printf("%02x ", p->value[k]);
|
||||
}
|
||||
printf("\n");
|
||||
} break;
|
||||
case DNS_HTTPS_T_IPV6HINT: {
|
||||
printf(" HTTPS: ipv6hint: %d\n", p->len / 16);
|
||||
for (int k = 0; k < p->len / 16; k++) {
|
||||
char ip[64] = {0};
|
||||
inet_ntop(AF_INET6, p->value + k * 16, ip, sizeof(ip));
|
||||
printf(" ipv6: %s\n", ip);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case DNS_T_NS: {
|
||||
char cname[DNS_MAX_CNAME_LEN];
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
|
||||
Reference in New Issue
Block a user