From 0760dc1a041a2f00cf928b174226bfa08536b5f7 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 16 Feb 2019 18:22:32 +0000 Subject: [PATCH] attempt to support edns0 --- mio/lib/dns.c | 104 +++++++++++++++++++++++----------------------- mio/lib/main.c | 8 ++-- mio/lib/mio-dns.h | 36 ++++++++-------- 3 files changed, 75 insertions(+), 73 deletions(-) diff --git a/mio/lib/dns.c b/mio/lib/dns.c index 9a58caa..d85d639 100644 --- a/mio/lib/dns.c +++ b/mio/lib/dns.c @@ -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));*/ - if (!DN_AT_END(str)) + if (str && !DN_AT_END(str)) { mio_uint8_t* lp; 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); } -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_oow_t dnlen, msgbufsz, i; void* msgbuf; mio_dns_msg_t* msg; mio_uint8_t* dn; - mio_dns_qrrtr_t* qrrtr; - mio_dns_rrrtr_t* rrrtr; - int rrr_sect; + mio_dns_qrtr_t* qrtr; + mio_dns_rrtr_t* rrtr; + int rr_sect; msgbufsz = MIO_SIZEOF(msgbufsz) + MIO_SIZEOF(*msg); - for (i = 0; i < qrr_count; i++) + for (i = 0; i < qr_count; i++) { /* segmnetsegment. * 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. */ - 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); /* 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 */ dn = (mio_uint8_t*)(msg + 1); - for (i = 0; i < qrr_count; i++) + for (i = 0; i < qr_count; i++) { /* dnlen includes the ending */ - 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) { 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; + } + 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); - qrrtr->qtype = mio_hton16(qrr[i].qtype); - qrrtr->qclass = mio_hton16(qrr[i].qclass); - - dn = (mio_uint8_t*)(qrrtr + 1); + dn = (mio_uint8_t*)(qrtr + 1); } - - for (rrr_sect = MIO_DNS_RRR_PART_ANSWER; rrr_sect <= MIO_DNS_RRR_PART_ADDITIONAL;) + for (rr_sect = MIO_DNS_RRR_PART_ANSWER; rr_sect <= MIO_DNS_RRR_PART_ADDITIONAL;) { 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) { 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; } - rrrtr = (mio_dns_rrrtr_t*)(dn + dnlen); - rrrtr->qtype = mio_hton16(rrr[i].qtype); - rrrtr->qclass = mio_hton16(rrr[i].qclass); - rrrtr->ttl = mio_hton32(rrr[i].ttl); - rrrtr->dlen = mio_hton32(rrr[i].dlen); - if (rrr[i].dlen > 0) MIO_MEMCPY (rrrtr + 1, rrr[i].dptr, rrr[i].dlen); + rrtr = (mio_dns_rrtr_t*)(dn + dnlen); + rrtr->qtype = mio_hton16(rr[i].qtype); + rrtr->qclass = mio_hton16(rr[i].qclass); + rrtr->ttl = mio_hton32(rr[i].ttl); + rrtr->dlen = mio_hton16(rr[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++; } } - rrr_sect = rrr_sect + 1; - ((mio_dns_msg_alt_t*)msg)->rrcount[rrr_sect] = mio_hton16(match_count); + rr_sect = rr_sect + 1; + ((mio_dns_msg_alt_t*)msg)->rrcount[rr_sect] = mio_hton16(match_count); } - if (rrr_count <= 0) - { - msg->qr = 0; - msg->opcode = MIO_DNS_OPCODE_QUERY; - msg->qdcount = mio_hton16(qrr_count); - } - else - { - msg->qr = 1; - msg->opcode = MIO_DNS_OPCODE_QUERY; - msg->qdcount = mio_hton16(qrr_count); - } + /* add EDNS0 OPT RR */ + *dn = 0; /* root domain. as if to_dn("") is called */ + rrtr = (mio_dns_rrtr_t*)(dn + 1); + rrtr->qtype = MIO_CONST_HTON16(MIO_DNS_QTYPE_OPT); + 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 */ + rrtr->dlen = MIO_CONST_HTON16(0); + msg->arcount = mio_hton16((mio_ntoh16(msg->arcount) + 1)); + dn = (mio_uint8_t*)(rrtr + 1) + 0; + + msg->qr = (rr_count > 0); + msg->opcode = MIO_DNS_OPCODE_QUERY; + msg->qdcount = mio_hton16(qr_count); *xmsglen = dn - (mio_uint8_t*)msg; 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_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; 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; } -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 mio_oow_t 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; #else mio_dns_msg_t* msg; mio_oow_t msglen; - msg = build_req_msg(dnsc, qrr, count, &msglen); + msg = build_req_msg(dnsc, qr, count, &msglen); if (!msg) return -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 } -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_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; msg->rd = 1; diff --git a/mio/lib/main.c b/mio/lib/main.c index a86b30c..ddcd368 100644 --- a/mio/lib/main.c +++ b/mio/lib/main.c @@ -811,7 +811,7 @@ for (i = 0; i < 5; i++) 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 */ { - 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_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 }, { "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_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_dnsc_sendreq (dnsc, qrrs, MIO_COUNTOF(qrrs)); - mio_dnsc_sendrep (dnsc, qrrs, MIO_COUNTOF(qrrs), rrrs, MIO_COUNTOF(rrrs)); + mio_dnsc_sendreq (dnsc, qrs, MIO_COUNTOF(qrs)); + mio_dnsc_sendrep (dnsc, qrs, MIO_COUNTOF(qrs), rrs, MIO_COUNTOF(rrs)); } mio_loop (mio); diff --git a/mio/lib/mio-dns.h b/mio/lib/mio-dns.h index 3c7d912..97e0812 100644 --- a/mio/lib/mio-dns.h +++ b/mio/lib/mio-dns.h @@ -81,6 +81,7 @@ enum mio_dns_qtype_t MIO_DNS_QTYPE_SRV = 33, MIO_DNS_QTYPE_OPT = 41, MIO_DNS_QTYPE_RRSIG = 46, + MIO_DNS_QTYPE_AFXR = 252, /* entire zone transfer */ MIO_DNS_QTYPE_ANY = 255 }; 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 */ -struct mio_dns_qrrtr_t +struct mio_dns_qrtr_t { /* qname upto 64 bytes */ mio_uint16_t qtype; 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 */ -struct mio_dns_rrrtr_t +struct mio_dns_rrtr_t { /* qname upto 64 bytes */ mio_uint16_t qtype; @@ -165,33 +166,32 @@ struct mio_dns_rrrtr_t mio_uint16_t dlen; /* data length */ /* 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 typedef struct mio_dnss_t mio_dnss_t; typedef struct mio_dnsc_t mio_dnsc_t; -struct mio_dns_bqrr_t +struct mio_dns_bqr_t { mio_bch_t* qname; mio_uint16_t qtype; 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_AUTHORITY, 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_uint16_t qtype; mio_uint16_t qclass; @@ -199,7 +199,7 @@ struct mio_dns_brrr_t mio_uint16_t dlen; 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) extern "C" { @@ -215,16 +215,16 @@ MIO_EXPORT void mio_dnsc_stop ( MIO_EXPORT int mio_dnsc_sendreq ( mio_dnsc_t* dnsc, - mio_dns_bqrr_t* qrr, - mio_oow_t qrr_count + mio_dns_bqr_t* qr, + mio_oow_t qr_count ); MIO_EXPORT 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 + mio_dns_bqr_t* qr, + mio_oow_t qr_count, + mio_dns_brr_t* rr, + mio_oow_t rr_count ); #if defined(__cplusplus)