attempt to support edns0

This commit is contained in:
hyung-hwan 2019-02-16 18:22:32 +00:00
parent 257a3f533c
commit 0760dc1a04
3 changed files with 75 additions and 73 deletions

View File

@ -38,7 +38,7 @@ static mio_oow_t to_dn (const mio_bch_t* str, mio_uint8_t* buf, mio_oow_t bufsz)
/*MIO_ASSERT (MIO_SIZEOF(mio_uint8_t) == MIO_SIZEOF(mio_bch_t));*/ /*MIO_ASSERT (MIO_SIZEOF(mio_uint8_t) == MIO_SIZEOF(mio_bch_t));*/
if (!DN_AT_END(str)) if (str && !DN_AT_END(str))
{ {
mio_uint8_t* lp; mio_uint8_t* lp;
mio_oow_t len; mio_oow_t len;
@ -211,32 +211,34 @@ static void release_req_msg (mio_dnsc_t* dnsc, mio_dns_msg_t* msg)
mio_freemem (mio, msgbuf); mio_freemem (mio, msgbuf);
} }
static mio_dns_msg_t* build_req_msg (mio_dnsc_t* dnsc, mio_dns_bqrr_t* qrr, mio_oow_t qrr_count, mio_dns_brrr_t* rrr, mio_oow_t rrr_count, mio_oow_t* xmsglen) static mio_dns_msg_t* build_req_msg (mio_dnsc_t* dnsc, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count, mio_oow_t* xmsglen)
{ {
mio_t* mio = dnsc->mio; mio_t* mio = dnsc->mio;
mio_oow_t dnlen, msgbufsz, i; mio_oow_t dnlen, msgbufsz, i;
void* msgbuf; void* msgbuf;
mio_dns_msg_t* msg; mio_dns_msg_t* msg;
mio_uint8_t* dn; mio_uint8_t* dn;
mio_dns_qrrtr_t* qrrtr; mio_dns_qrtr_t* qrtr;
mio_dns_rrrtr_t* rrrtr; mio_dns_rrtr_t* rrtr;
int rrr_sect; int rr_sect;
msgbufsz = MIO_SIZEOF(msgbufsz) + MIO_SIZEOF(*msg); msgbufsz = MIO_SIZEOF(msgbufsz) + MIO_SIZEOF(*msg);
for (i = 0; i < qrr_count; i++) for (i = 0; i < qr_count; i++)
{ {
/* <length>segmnet<length>segment<zero>. /* <length>segmnet<length>segment<zero>.
* if the input has the ending period(e.g. mio.lib.), the dn length is namelen + 1. * if the input has the ending period(e.g. mio.lib.), the dn length is namelen + 1.
* if the input doesn't have the ending period(e.g. mio.lib) . the dn length is namelen + 2. */ * if the input doesn't have the ending period(e.g. mio.lib) . the dn length is namelen + 2. */
msgbufsz += mio_count_bcstr(qrr[i].qname) + 2 + MIO_SIZEOF(*qrrtr); msgbufsz += mio_count_bcstr(qr[i].qname) + 2 + MIO_SIZEOF(*qrtr);
} }
for (i = 0; i < rrr_count; i++) for (i = 0; i < rr_count; i++)
{ {
msgbufsz += mio_count_bcstr(rrr[i].qname) + 2 + MIO_SIZEOF(*rrrtr) + rrr[i].dlen; msgbufsz += mio_count_bcstr(rr[i].qname) + 2 + MIO_SIZEOF(*rrtr) + rr[i].dlen;
} }
msgbufsz += 1 + MIO_SIZEOF(*rrtr); /* edns0 OPT RR */
msgbufsz = MIO_ALIGN_POW2(msgbufsz, 64); msgbufsz = MIO_ALIGN_POW2(msgbufsz, 64);
/* TODO: msg buffer reuse */ /* TODO: msg buffer reuse */
@ -247,81 +249,81 @@ static mio_dns_msg_t* build_req_msg (mio_dnsc_t* dnsc, mio_dns_bqrr_t* qrr, mio_
msg = (mio_dns_msg_t*)(msgbuf + MIO_SIZEOF(mio_oow_t)); /* actual message begins the after the size word */ msg = (mio_dns_msg_t*)(msgbuf + MIO_SIZEOF(mio_oow_t)); /* actual message begins the after the size word */
dn = (mio_uint8_t*)(msg + 1); dn = (mio_uint8_t*)(msg + 1);
for (i = 0; i < qrr_count; i++) for (i = 0; i < qr_count; i++)
{ {
/* dnlen includes the ending <zero> */ /* dnlen includes the ending <zero> */
dnlen = to_dn(qrr[i].qname, dn, mio_count_bcstr(qrr[i].qname) + 2); dnlen = to_dn(qr[i].qname, dn, mio_count_bcstr(qr[i].qname) + 2);
if (dnlen <= 0) if (dnlen <= 0)
{ {
release_req_msg (dnsc, msg); release_req_msg (dnsc, msg);
mio_seterrbfmt (mio, MIO_EINVAL, "invalid domain name - %hs", qrr[i].qname); mio_seterrbfmt (mio, MIO_EINVAL, "invalid domain name - %hs", qr[i].qname);
return MIO_NULL; return MIO_NULL;
} }
qrtr = (mio_dns_qrtr_t*)(dn + dnlen);
qrtr->qtype = mio_hton16(qr[i].qtype);
qrtr->qclass = mio_hton16(qr[i].qclass);
qrrtr = (mio_dns_qrrtr_t*)(dn + dnlen); dn = (mio_uint8_t*)(qrtr + 1);
qrrtr->qtype = mio_hton16(qrr[i].qtype);
qrrtr->qclass = mio_hton16(qrr[i].qclass);
dn = (mio_uint8_t*)(qrrtr + 1);
} }
for (rr_sect = MIO_DNS_RRR_PART_ANSWER; rr_sect <= MIO_DNS_RRR_PART_ADDITIONAL;)
for (rrr_sect = MIO_DNS_RRR_PART_ANSWER; rrr_sect <= MIO_DNS_RRR_PART_ADDITIONAL;)
{ {
mio_oow_t match_count = 0; mio_oow_t match_count = 0;
for (i = 0; i < rrr_count; i++) for (i = 0; i < rr_count; i++)
{ {
if (rrr[i].part == rrr_sect) if (rr[i].part == rr_sect)
{ {
dnlen = to_dn(rrr[i].qname, dn, mio_count_bcstr(rrr[i].qname) + 2); dnlen = to_dn(rr[i].qname, dn, mio_count_bcstr(rr[i].qname) + 2);
if (dnlen <= 0) if (dnlen <= 0)
{ {
release_req_msg (dnsc, msg); release_req_msg (dnsc, msg);
mio_seterrbfmt (mio, MIO_EINVAL, "invalid domain name - %hs", rrr[i].qname); mio_seterrbfmt (mio, MIO_EINVAL, "invalid domain name - %hs", rr[i].qname);
return MIO_NULL; return MIO_NULL;
} }
rrrtr = (mio_dns_rrrtr_t*)(dn + dnlen); rrtr = (mio_dns_rrtr_t*)(dn + dnlen);
rrrtr->qtype = mio_hton16(rrr[i].qtype); rrtr->qtype = mio_hton16(rr[i].qtype);
rrrtr->qclass = mio_hton16(rrr[i].qclass); rrtr->qclass = mio_hton16(rr[i].qclass);
rrrtr->ttl = mio_hton32(rrr[i].ttl); rrtr->ttl = mio_hton32(rr[i].ttl);
rrrtr->dlen = mio_hton32(rrr[i].dlen); rrtr->dlen = mio_hton16(rr[i].dlen);
if (rrr[i].dlen > 0) MIO_MEMCPY (rrrtr + 1, rrr[i].dptr, rrr[i].dlen); if (rr[i].dlen > 0) MIO_MEMCPY (rrtr + 1, rr[i].dptr, rr[i].dlen);
dn = (mio_uint8_t*)(rrrtr + 1) + rrr[i].dlen; dn = (mio_uint8_t*)(rrtr + 1) + rr[i].dlen;
match_count++; match_count++;
} }
} }
rrr_sect = rrr_sect + 1; rr_sect = rr_sect + 1;
((mio_dns_msg_alt_t*)msg)->rrcount[rrr_sect] = mio_hton16(match_count); ((mio_dns_msg_alt_t*)msg)->rrcount[rr_sect] = mio_hton16(match_count);
} }
if (rrr_count <= 0) /* add EDNS0 OPT RR */
{ *dn = 0; /* root domain. as if to_dn("") is called */
msg->qr = 0; rrtr = (mio_dns_rrtr_t*)(dn + 1);
msg->opcode = MIO_DNS_OPCODE_QUERY; rrtr->qtype = MIO_CONST_HTON16(MIO_DNS_QTYPE_OPT);
msg->qdcount = mio_hton16(qrr_count); rrtr->qclass = MIO_CONST_HTON16(4096); /* udp payload size - TODO: if answer, copy from request, if not, get it from mio settings???? */
} rrtr->ttl = MIO_CONST_HTON32(0); /* extended rcode, version, flags */
else rrtr->dlen = MIO_CONST_HTON16(0);
{ msg->arcount = mio_hton16((mio_ntoh16(msg->arcount) + 1));
msg->qr = 1; dn = (mio_uint8_t*)(rrtr + 1) + 0;
msg->opcode = MIO_DNS_OPCODE_QUERY;
msg->qdcount = mio_hton16(qrr_count); msg->qr = (rr_count > 0);
} msg->opcode = MIO_DNS_OPCODE_QUERY;
msg->qdcount = mio_hton16(qr_count);
*xmsglen = dn - (mio_uint8_t*)msg; *xmsglen = dn - (mio_uint8_t*)msg;
return msg; /* return the pointer to the beginning of the actual message */ return msg; /* return the pointer to the beginning of the actual message */
} }
static MIO_INLINE int send_req_with_single_rr (mio_dnsc_t* dnsc, mio_dns_bqrr_t* qrr) static MIO_INLINE int send_req_with_single_rr (mio_dnsc_t* dnsc, mio_dns_bqr_t* qr)
{ {
mio_dns_msg_t* msg; mio_dns_msg_t* msg;
mio_oow_t msglen; mio_oow_t msglen;
msg = build_req_msg(dnsc, qrr, 1, MIO_NULL, 0, &msglen); msg = build_req_msg(dnsc, qr, 1, MIO_NULL, 0, &msglen);
if (!msg) return -1; if (!msg) return -1;
msg->rd = 1; msg->rd = 1;
@ -336,21 +338,21 @@ static MIO_INLINE int send_req_with_single_rr (mio_dnsc_t* dnsc, mio_dns_bqrr_t*
return 0; return 0;
} }
int mio_dnsc_sendreq (mio_dnsc_t* dnsc, mio_dns_bqrr_t* qrr, mio_oow_t count) int mio_dnsc_sendreq (mio_dnsc_t* dnsc, mio_dns_bqr_t* qr, mio_oow_t count)
{ {
#if 1 #if 1
mio_oow_t i; mio_oow_t i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
if (send_req_with_single_rr(dnsc, &qrr[i]) <= -1) return -1; if (send_req_with_single_rr(dnsc, &qr[i]) <= -1) return -1;
} }
return 0; return 0;
#else #else
mio_dns_msg_t* msg; mio_dns_msg_t* msg;
mio_oow_t msglen; mio_oow_t msglen;
msg = build_req_msg(dnsc, qrr, count, &msglen); msg = build_req_msg(dnsc, qr, count, &msglen);
if (!msg) return -1; if (!msg) return -1;
msg->rd = 1; msg->rd = 1;
@ -365,12 +367,12 @@ int mio_dnsc_sendreq (mio_dnsc_t* dnsc, mio_dns_bqrr_t* qrr, mio_oow_t count)
#endif #endif
} }
int mio_dnsc_sendrep (mio_dnsc_t* dnsc, mio_dns_bqrr_t* qrr, mio_oow_t qrr_count, mio_dns_brrr_t* rrr, mio_oow_t rrr_count) int mio_dnsc_sendrep (mio_dnsc_t* dnsc, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count)
{ {
mio_dns_msg_t* msg; mio_dns_msg_t* msg;
mio_oow_t msglen; mio_oow_t msglen;
msg = build_req_msg(dnsc, qrr, qrr_count, rrr, rrr_count, &msglen); msg = build_req_msg(dnsc, qr, qr_count, rr, rr_count, &msglen);
if (!msg) return -1; if (!msg) return -1;
msg->rd = 1; msg->rd = 1;

View File

@ -811,7 +811,7 @@ for (i = 0; i < 5; i++)
mio_dnsc_t* dnsc; mio_dnsc_t* dnsc;
dnsc = mio_dnsc_start (mio/*, "8.8.8.8:53,1.1.1.1:53"*/); /* option - send to all, send one by one */ dnsc = mio_dnsc_start (mio/*, "8.8.8.8:53,1.1.1.1:53"*/); /* option - send to all, send one by one */
{ {
mio_dns_bqrr_t qrrs[] = mio_dns_bqr_t qrs[] =
{ {
{ "code.miflux.com", MIO_DNS_QTYPE_A, MIO_DNS_QCLASS_IN }, { "code.miflux.com", MIO_DNS_QTYPE_A, MIO_DNS_QCLASS_IN },
{ "code.miflux.com", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN }, { "code.miflux.com", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN },
@ -819,15 +819,15 @@ for (i = 0; i < 5; i++)
{ "code6.abiyo.net", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN }, { "code6.abiyo.net", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN },
{ "abiyo.net", MIO_DNS_QTYPE_MX, MIO_DNS_QCLASS_IN } { "abiyo.net", MIO_DNS_QTYPE_MX, MIO_DNS_QCLASS_IN }
}; };
mio_dns_brrr_t rrrs[] = mio_dns_brr_t rrs[] =
{ {
{ MIO_DNS_RRR_PART_ANSWER, "code.miflux.com", MIO_DNS_QTYPE_A, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL }, { MIO_DNS_RRR_PART_ANSWER, "code.miflux.com", MIO_DNS_QTYPE_A, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL },
{ MIO_DNS_RRR_PART_ANSWER, "code.miflux.com", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL }, { MIO_DNS_RRR_PART_ANSWER, "code.miflux.com", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL },
{ MIO_DNS_RRR_PART_AUTHORITY, "dns.miflux.com", MIO_DNS_QTYPE_NS, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL } { MIO_DNS_RRR_PART_AUTHORITY, "dns.miflux.com", MIO_DNS_QTYPE_NS, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL }
}; };
mio_dnsc_sendreq (dnsc, qrrs, MIO_COUNTOF(qrrs)); mio_dnsc_sendreq (dnsc, qrs, MIO_COUNTOF(qrs));
mio_dnsc_sendrep (dnsc, qrrs, MIO_COUNTOF(qrrs), rrrs, MIO_COUNTOF(rrrs)); mio_dnsc_sendrep (dnsc, qrs, MIO_COUNTOF(qrs), rrs, MIO_COUNTOF(rrs));
} }
mio_loop (mio); mio_loop (mio);

View File

@ -81,6 +81,7 @@ enum mio_dns_qtype_t
MIO_DNS_QTYPE_SRV = 33, MIO_DNS_QTYPE_SRV = 33,
MIO_DNS_QTYPE_OPT = 41, MIO_DNS_QTYPE_OPT = 41,
MIO_DNS_QTYPE_RRSIG = 46, MIO_DNS_QTYPE_RRSIG = 46,
MIO_DNS_QTYPE_AFXR = 252, /* entire zone transfer */
MIO_DNS_QTYPE_ANY = 255 MIO_DNS_QTYPE_ANY = 255
}; };
typedef enum mio_dns_qtype_t mio_dns_qtype_t; typedef enum mio_dns_qtype_t mio_dns_qtype_t;
@ -147,16 +148,16 @@ typedef struct mio_dns_msg_alt_t mio_dns_msg_alt_t;
*/ */
/* trailing part after the domain name in a resource record in a question */ /* trailing part after the domain name in a resource record in a question */
struct mio_dns_qrrtr_t struct mio_dns_qrtr_t
{ {
/* qname upto 64 bytes */ /* qname upto 64 bytes */
mio_uint16_t qtype; mio_uint16_t qtype;
mio_uint16_t qclass; mio_uint16_t qclass;
}; };
typedef struct mio_dns_qrrtr_t mio_dns_qrrtr_t; typedef struct mio_dns_qrtr_t mio_dns_qrtr_t;
/* trailing part after the domain name in a resource record in an answer */ /* trailing part after the domain name in a resource record in an answer */
struct mio_dns_rrrtr_t struct mio_dns_rrtr_t
{ {
/* qname upto 64 bytes */ /* qname upto 64 bytes */
mio_uint16_t qtype; mio_uint16_t qtype;
@ -165,33 +166,32 @@ struct mio_dns_rrrtr_t
mio_uint16_t dlen; /* data length */ mio_uint16_t dlen; /* data length */
/* actual data if if dlen > 0 */ /* actual data if if dlen > 0 */
}; };
typedef struct mio_dns_rrrtr_t mio_dns_rrrtr_t; typedef struct mio_dns_rrtr_t mio_dns_rrtr_t;
#include <mio-upac.h> #include <mio-upac.h>
typedef struct mio_dnss_t mio_dnss_t; typedef struct mio_dnss_t mio_dnss_t;
typedef struct mio_dnsc_t mio_dnsc_t; typedef struct mio_dnsc_t mio_dnsc_t;
struct mio_dns_bqrr_t struct mio_dns_bqr_t
{ {
mio_bch_t* qname; mio_bch_t* qname;
mio_uint16_t qtype; mio_uint16_t qtype;
mio_uint16_t qclass; mio_uint16_t qclass;
}; };
typedef struct mio_dns_bqrr_t mio_dns_bqrr_t; typedef struct mio_dns_bqr_t mio_dns_bqr_t;
enum mio_dns_rrr_part_t enum mio_dns_rr_part_t
{ {
MIO_DNS_RRR_PART_ANSWER, MIO_DNS_RRR_PART_ANSWER,
MIO_DNS_RRR_PART_AUTHORITY, MIO_DNS_RRR_PART_AUTHORITY,
MIO_DNS_RRR_PART_ADDITIONAL MIO_DNS_RRR_PART_ADDITIONAL
}; };
typedef enum mio_dns_rrr_part_t mio_dns_rrr_part_t; typedef enum mio_dns_rr_part_t mio_dns_rr_part_t;
struct mio_dns_brrr_t struct mio_dns_brr_t
{ {
mio_dns_rrr_part_t part; mio_dns_rr_part_t part;
mio_bch_t* qname; mio_bch_t* qname;
mio_uint16_t qtype; mio_uint16_t qtype;
mio_uint16_t qclass; mio_uint16_t qclass;
@ -199,7 +199,7 @@ struct mio_dns_brrr_t
mio_uint16_t dlen; mio_uint16_t dlen;
void* dptr; void* dptr;
}; };
typedef struct mio_dns_brrr_t mio_dns_brrr_t; typedef struct mio_dns_brr_t mio_dns_brr_t;
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
@ -215,16 +215,16 @@ MIO_EXPORT void mio_dnsc_stop (
MIO_EXPORT int mio_dnsc_sendreq ( MIO_EXPORT int mio_dnsc_sendreq (
mio_dnsc_t* dnsc, mio_dnsc_t* dnsc,
mio_dns_bqrr_t* qrr, mio_dns_bqr_t* qr,
mio_oow_t qrr_count mio_oow_t qr_count
); );
MIO_EXPORT int mio_dnsc_sendrep ( MIO_EXPORT int mio_dnsc_sendrep (
mio_dnsc_t* dnsc, mio_dnsc_t* dnsc,
mio_dns_bqrr_t* qrr, mio_dns_bqr_t* qr,
mio_oow_t qrr_count, mio_oow_t qr_count,
mio_dns_brrr_t* rrr, mio_dns_brr_t* rr,
mio_oow_t rrr_count mio_oow_t rr_count
); );
#if defined(__cplusplus) #if defined(__cplusplus)