Merge branch 'master' of https://github.com/sogou/workflow into nossl

This commit is contained in:
Xie Han
2024-04-24 18:14:33 +08:00
3 changed files with 335 additions and 1 deletions

View File

@@ -152,6 +152,109 @@ public:
parser->question.qname = strdup(name.c_str());
}
int add_a_record(int section, const char *name,
uint16_t rclass, uint32_t ttl,
const void *data)
{
struct list_head *list = get_section(section);
if (!list)
return -1;
return dns_add_raw_record(name, DNS_TYPE_A, rclass, ttl, 4, data, list);
}
int add_aaaa_record(int section, const char *name,
uint16_t rclass, uint32_t ttl,
const void *data)
{
struct list_head *list = get_section(section);
if (!list)
return -1;
return dns_add_raw_record(name, DNS_TYPE_AAAA, rclass, ttl,
16, data, list);
}
int add_ns_record(int section, const char *name,
uint16_t rclass, uint32_t ttl,
const char *data)
{
struct list_head *list = get_section(section);
if (!list)
return -1;
return dns_add_str_record(name, DNS_TYPE_NS, rclass, ttl, data, list);
}
int add_cname_record(int section, const char *name,
uint16_t rclass, uint32_t ttl,
const char *data)
{
struct list_head *list = get_section(section);
if (!list)
return -1;
return dns_add_str_record(name, DNS_TYPE_CNAME, rclass, ttl,
data, list);
}
int add_ptr_record(int section, const char *name,
uint16_t rclass, uint32_t ttl,
const char *data)
{
struct list_head *list = get_section(section);
if (!list)
return -1;
return dns_add_str_record(name, DNS_TYPE_PTR, rclass, ttl, data, list);
}
int add_soa_record(int section, const char *name,
uint16_t rclass, uint32_t ttl,
const char *mname, const char *rname,
uint32_t serial, int32_t refresh,
int32_t retry, int32_t expire, uint32_t minimum)
{
struct list_head *list = get_section(section);
if (!list)
return -1;
return dns_add_soa_record(name, rclass, ttl, mname, rname, serial,
refresh, retry, expire, minimum, list);
}
int add_srv_record(int section, const char *name,
uint16_t rclass, uint32_t ttl,
uint16_t priority, uint16_t weight, uint16_t port,
const char *target)
{
struct list_head *list = get_section(section);
if (!list)
return -1;
return dns_add_srv_record(name, rclass, ttl,
priority, weight, port, target, list);
}
int add_mx_record(int section, const char *name,
uint16_t rclass, uint32_t ttl,
int16_t preference, const char *exchange)
{
struct list_head *list = get_section(section);
if (!list)
return -1;
return dns_add_mx_record(name, rclass, ttl, preference, exchange, list);
}
// Inner use only
bool is_single_packet() const
{
@@ -191,6 +294,22 @@ private:
int encode_reply();
int encode_truncation_reply();
struct list_head *get_section(int section)
{
switch (section)
{
case DNS_ANSWER_SECTION:
return &(parser->answer_list);
case DNS_AUTHORITY_SECTION:
return &(parser->authority_list);
case DNS_ADDITIONAL_SECTION:
return &(parser->additional_list);
default:
errno = EINVAL;
return NULL;
}
}
// size of msgbuf, but in network byte order
uint16_t msgsize;
};

View File

@@ -100,11 +100,16 @@ static int __dns_parser_parse_host(char *phost, dns_parser_t *parser)
else if ((len & 0xC0) == 0xC0)
{
pointer = __dns_parser_uint16(*cur) & 0x3FFF;
*cur += 2;
if (pointer >= parser->msgsize)
return -2;
// pointer must point to a prior position
if ((const char *)parser->msgbase + pointer >= *cur)
return -2;
*cur += 2;
// backup cur only when the first pointer occurs
if (curbackup == NULL)
curbackup = *cur;
@@ -909,6 +914,186 @@ int dns_record_cursor_find_cname(const char *name,
return 1;
}
int dns_add_raw_record(const char *name, uint16_t type, uint16_t rclass,
uint32_t ttl, uint16_t rlen, const void *rdata,
struct list_head *list)
{
struct __dns_record_entry *entry;
size_t entry_size = sizeof (struct __dns_record_entry) + rlen;
entry = (struct __dns_record_entry *)malloc(entry_size);
if (!entry)
return -1;
entry->record.name = strdup(name);
if (!entry->record.name)
{
free(entry);
return -1;
}
entry->record.type = type;
entry->record.rclass = rclass;
entry->record.ttl = ttl;
entry->record.rdlength = rlen;
entry->record.rdata = (void *)(entry + 1);
memcpy(entry->record.rdata, rdata, rlen);
list_add_tail(&entry->entry_list, list);
return 0;
}
int dns_add_str_record(const char *name, uint16_t type, uint16_t rclass,
uint32_t ttl, const char *rdata,
struct list_head *list)
{
size_t rlen = strlen(rdata);
// record.rdlength has no meaning for parsed record types, ignore its
// correctness, same for soa/srv/mx record
return dns_add_raw_record(name, type, rclass, ttl, rlen+1, rdata, list);
}
int dns_add_soa_record(const char *name, uint16_t rclass, uint32_t ttl,
const char *mname, const char *rname,
uint32_t serial, int32_t refresh,
int32_t retry, int32_t expire, uint32_t minimum,
struct list_head *list)
{
struct __dns_record_entry *entry;
struct dns_record_soa *soa;
size_t entry_size;
char *pname, *pmname, *prname;
entry_size = sizeof (struct __dns_record_entry) +
sizeof (struct dns_record_soa);
entry = (struct __dns_record_entry *)malloc(entry_size);
if (!entry)
return -1;
entry->record.rdata = (void *)(entry + 1);
entry->record.rdlength = 0;
soa = (struct dns_record_soa *)(entry->record.rdata);
pname = strdup(name);
pmname = strdup(mname);
prname = strdup(rname);
if (!pname || !pmname || !prname)
{
free(pname);
free(pmname);
free(prname);
free(entry);
return -1;
}
soa->mname = pmname;
soa->rname = prname;
soa->serial = serial;
soa->refresh = refresh;
soa->retry = retry;
soa->expire = expire;
soa->minimum = minimum;
entry->record.name = pname;
entry->record.type = DNS_TYPE_SOA;
entry->record.rclass = rclass;
entry->record.ttl = ttl;
list_add_tail(&entry->entry_list, list);
return 0;
}
int dns_add_srv_record(const char *name, uint16_t rclass, uint32_t ttl,
uint16_t priority, uint16_t weight,
uint16_t port, const char *target,
struct list_head *list)
{
struct __dns_record_entry *entry;
struct dns_record_srv *srv;
size_t entry_size;
char *pname, *ptarget;
entry_size = sizeof (struct __dns_record_entry) +
sizeof (struct dns_record_srv);
entry = (struct __dns_record_entry *)malloc(entry_size);
if (!entry)
return -1;
entry->record.rdata = (void *)(entry + 1);
entry->record.rdlength = 0;
srv = (struct dns_record_srv *)(entry->record.rdata);
pname = strdup(name);
ptarget = strdup(target);
if (!pname || !ptarget)
{
free(pname);
free(ptarget);
free(entry);
return -1;
}
srv->priority = priority;
srv->weight = weight;
srv->port = port;
srv->target = ptarget;
entry->record.name = pname;
entry->record.type = DNS_TYPE_SRV;
entry->record.rclass = rclass;
entry->record.ttl = ttl;
list_add_tail(&entry->entry_list, list);
return 0;
}
int dns_add_mx_record(const char *name, uint16_t rclass, uint32_t ttl,
int16_t preference, const char *exchange,
struct list_head *list)
{
struct __dns_record_entry *entry;
struct dns_record_mx *mx;
size_t entry_size;
char *pname, *pexchange;
entry_size = sizeof (struct __dns_record_entry) +
sizeof (struct dns_record_mx);
entry = (struct __dns_record_entry *)malloc(entry_size);
if (!entry)
return -1;
entry->record.rdata = (void *)(entry + 1);
entry->record.rdlength = 0;
mx = (struct dns_record_mx *)(entry->record.rdata);
pname = strdup(name);
pexchange = strdup(exchange);
if (!pname || !pexchange)
{
free(pname);
free(pexchange);
free(entry);
return -1;
}
mx->preference = preference;
mx->exchange = pexchange;
entry->record.name = pname;
entry->record.type = DNS_TYPE_MX;
entry->record.rclass = rclass;
entry->record.ttl = ttl;
list_add_tail(&entry->entry_list, list);
return 0;
}
const char *dns_type2str(int type)
{
switch (type)

View File

@@ -78,6 +78,13 @@ enum
DNS_RCODE_REFUSED
};
enum
{
DNS_ANSWER_SECTION = 1,
DNS_AUTHORITY_SECTION = 2,
DNS_ADDITIONAL_SECTION = 3,
};
/**
* dns_header_t is a struct to describe the header of a dns
* request or response packet, but the byte order is not
@@ -207,6 +214,29 @@ int dns_record_cursor_find_cname(const char *name,
const char **cname,
dns_record_cursor_t *cursor);
int dns_add_raw_record(const char *name, uint16_t type, uint16_t rclass,
uint32_t ttl, uint16_t rlen, const void *rdata,
struct list_head *list);
int dns_add_str_record(const char *name, uint16_t type, uint16_t rclass,
uint32_t ttl, const char *rdata,
struct list_head *list);
int dns_add_soa_record(const char *name, uint16_t rclass, uint32_t ttl,
const char *mname, const char *rname,
uint32_t serial, int32_t refresh,
int32_t retry, int32_t expire, uint32_t minimum,
struct list_head *list);
int dns_add_srv_record(const char *name, uint16_t rclass, uint32_t ttl,
uint16_t priority, uint16_t weight,
uint16_t port, const char *target,
struct list_head *list);
int dns_add_mx_record(const char *name, uint16_t rclass, uint32_t ttl,
int16_t preference, const char *exchange,
struct list_head *list);
const char *dns_type2str(int type);
const char *dns_class2str(int dnsclass);
const char *dns_opcode2str(int opcode);