From fe478e954d98ab5f79fc4ded7fb64ef1c30e5b17 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 1 Jul 2020 15:54:23 +0000 Subject: [PATCH] work in progress - implementing the dns cookie support in mio_svc_dnc_resolve() --- mio/bin/t01.c | 2 +- mio/lib/dns-cli.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- mio/lib/dns.c | 3 ++- mio/lib/mio-dns.h | 4 +++- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/mio/bin/t01.c b/mio/bin/t01.c index 56a9b04..a5e2c1f 100644 --- a/mio/bin/t01.c +++ b/mio/bin/t01.c @@ -1281,7 +1281,7 @@ if (!mio_svc_dnc_resolve(dnc, "b.wild.com", MIO_DNS_RRT_A, MIO_SVC_DNC_RESOLVE_F printf ("resolve attempt failure ---> a.wild.com\n"); } -if (!mio_svc_dnc_resolve(dnc, "www.microsoft.com", MIO_DNS_RRT_CNAME, 0, on_dnc_resolve, 0)) +if (!mio_svc_dnc_resolve(dnc, "www.microsoft.com", MIO_DNS_RRT_CNAME, MIO_SVC_DNC_RESOLVE_FLAG_COOKIE, on_dnc_resolve, 0)) { printf ("resolve attempt failure ---> www.microsoft.com\n"); } diff --git a/mio/lib/dns-cli.c b/mio/lib/dns-cli.c index f053af5..a7e079b 100644 --- a/mio/lib/dns-cli.c +++ b/mio/lib/dns-cli.c @@ -862,7 +862,7 @@ static void on_dnc_resolve (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnu if (!(reqmsgxtn->flags & MIO_SVC_DNC_RESOLVE_FLAG_BRIEF)) { /* the full reply packet is requested. no transformation is required */ - if (reqmsgxtn->on_resolve) reqmsgxtn->on_resolve(dnc, reqmsg, status, data, dlen); + if (reqmsgxtn->on_resolve) reqmsgxtn->on_resolve (dnc, reqmsg, status, data, dlen); return; } @@ -965,7 +965,7 @@ mio_dns_msg_t* mio_svc_dnc_resolve (mio_svc_dnc_t* dnc, const mio_bch_t* qname, MIO_DNS_RCODE_NOERROR /* rcode */ }; - static mio_dns_bedns_t qedns = + mio_dns_bedns_t qedns = { 4096, /* uplen */ @@ -976,6 +976,8 @@ mio_dns_msg_t* mio_svc_dnc_resolve (mio_svc_dnc_t* dnc, const mio_bch_t* qname, MIO_NULL }; + mio_dns_beopt_t beopt_cookie; + mio_dns_bqr_t qr; mio_dns_msg_t* reqmsg; dnc_dns_msg_resolve_xtn_t* resolxtn; @@ -984,11 +986,49 @@ mio_dns_msg_t* mio_svc_dnc_resolve (mio_svc_dnc_t* dnc, const mio_bch_t* qname, qr.qtype = qtype; qr.qclass = MIO_DNS_RRC_IN; + if (resolve_flags & MIO_SVC_DNC_RESOLVE_FLAG_COOKIE) + { + static mio_uint8_t dummy[48]; + beopt_cookie.code = MIO_DNS_EOPT_COOKIE; + beopt_cookie.dlen = MIO_COUNTOF(dummy); + beopt_cookie.dptr = dummy; + + qedns.beonum = 1; + qedns.beoptr = &beopt_cookie; + } + reqmsg = make_dns_msg(dnc, &qhdr, &qr, 1, MIO_NULL, 0, &qedns, on_dnc_resolve, MIO_SIZEOF(*resolxtn) + xtnsize); if (reqmsg) { int send_flags; + if (resolve_flags & MIO_SVC_DNC_RESOLVE_FLAG_COOKIE) + { + /* ASSUMPTIONS: + * the eopt entries are at the back of the packet. + * only 1 eopt entry(MIO_DNS_EOPT_COOKIE) has been added. + * + * manipulate the data length of the EDNS0 RR and COOKIE option + * as if the server cookie data has not been added. + */ + mio_dns_rrtr_t* edns_rrtr; + mio_dns_eopt_t* eopt; + +/* TODO: generate the client cookie and copy it */ +/* if the server cookie is available, copy it to the packet. but the server cookike may still be shorter than 40. so some manipulation is still needed + * if not, manipualte the length like below */ + edns_rrtr = (mio_dns_rrtr_t*)((mio_uint8_t*)mio_dns_msg_to_pkt(reqmsg) + reqmsg->ednsrrtroff); + reqmsg->pktlen -= 40; /* maximum server cookie space */ + + MIO_ASSERT (dnc->mio, edns_rrtr->rrtype == MIO_CONST_HTON16(MIO_DNS_RRT_OPT)); + MIO_ASSERT (dnc->mio, edns_rrtr->dlen == MIO_CONST_HTON16(52)); + + edns_rrtr->dlen = MIO_CONST_HTON16(12); + eopt = (mio_dns_eopt_t*)(edns_rrtr + 1); + MIO_ASSERT (dnc->mio, eopt->dlen == MIO_CONST_HTON16(48)); + eopt->dlen = MIO_CONST_HTON16(8); + } + resolxtn = dnc_dns_msg_resolve_getxtn(reqmsg); resolxtn->on_resolve = on_resolve; resolxtn->qtype = qtype; diff --git a/mio/lib/dns.c b/mio/lib/dns.c index ee53a23..03c55cf 100644 --- a/mio/lib/dns.c +++ b/mio/lib/dns.c @@ -746,7 +746,7 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t /* TODO: msg buffer reuse */ msg = mio_callocmem(mio, msgbufsz); - if (!msg) return MIO_NULL; + if (MIO_UNLIKELY(!msg)) return MIO_NULL; msg->msglen = msgbufsz; /* record the instance size */ msg->pktalilen = MIO_ALIGN_POW2(pktlen, MIO_SIZEOF_VOID_P); @@ -812,6 +812,7 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t beopt = edns->beoptr; eopt = (mio_dns_eopt_t*)dn; + msg->ednsrrtroff = (mio_uint8_t*)rrtr - (mio_uint8_t*)pkt; for (i = 0; i < edns->beonum; i++) { diff --git a/mio/lib/mio-dns.h b/mio/lib/mio-dns.h index a839091..d83c9a5 100644 --- a/mio/lib/mio-dns.h +++ b/mio/lib/mio-dns.h @@ -162,6 +162,7 @@ typedef struct mio_dns_msg_t mio_dns_msg_t; struct mio_dns_msg_t { mio_oow_t msglen; + mio_oow_t ednsrrtroff; /* offset to trailing data after the name in the dns0 RR*/ mio_oow_t pktlen; mio_oow_t pktalilen; }; @@ -405,8 +406,9 @@ enum mio_svc_dnc_resolve_flag_t /* the following flag bits are resolver specific. it must not overlap with send flag bits */ MIO_SVC_DNC_RESOLVE_FLAG_BRIEF = (1 << 8), + MIO_SVC_DNC_RESOLVE_FLAG_COOKIE = (1 << 9), - MIO_SVC_DNC_RESOLVE_FLAG_ALL = (MIO_SVC_DNC_RESOLVE_FLAG_PREFER_TCP | MIO_SVC_DNC_RESOLVE_FLAG_TCP_IF_TC | MIO_SVC_DNC_RESOLVE_FLAG_BRIEF) + MIO_SVC_DNC_RESOLVE_FLAG_ALL = (MIO_SVC_DNC_RESOLVE_FLAG_PREFER_TCP | MIO_SVC_DNC_RESOLVE_FLAG_TCP_IF_TC | MIO_SVC_DNC_RESOLVE_FLAG_BRIEF | MIO_SVC_DNC_RESOLVE_FLAG_COOKIE) }; typedef enum mio_svc_dnc_resolve_flag_t mio_svc_dnc_resolve_flag_t;