added some code to implement dns packet parser

This commit is contained in:
hyung-hwan 2020-02-13 09:31:02 +00:00
parent 192e64b65c
commit 4e6a1b7d85
4 changed files with 420 additions and 207 deletions

View File

@ -606,19 +606,37 @@ static int setup_ping4_tester (mio_t* mio)
static void on_dnc_resolve(mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum_t status, const void* data, mio_oow_t dlen) static void on_dnc_resolve(mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum_t status, const void* data, mio_oow_t dlen)
{ {
mio_dns_pkt_info_t* pi = MIO_NULL;
if (status == MIO_ENOERR) if (status == MIO_ENOERR)
{ {
mio_uint32_t i;
printf ("XXXXXXXXXXXXXXXXx RECEIVED XXXXXXXXXXXXXXXXXXXXXXXXX\n"); printf ("XXXXXXXXXXXXXXXXx RECEIVED XXXXXXXXXXXXXXXXXXXXXXXXX\n");
pi = mio_dns_make_packet_info(mio_svc_dnc_getmio(dnc), data, dlen);
if (!pi) goto no_valid_reply;
//mio_dns_parse_packet (dnc, mio_dns_msg_to_pkt(reqmsg), if (pi->hdr.rcode != MIO_DNS_RCODE_NOERROR) goto no_valid_reply;
mio_dns_bdns_t bdns;
mio_dns_parse_packet (dnc, data, dlen, &bdns);
if (pi->ancount < 0) goto no_valid_reply;
for (i = 0; i < pi->ancount; i++)
{
if (pi->rr.an[i].rrtype == MIO_DNS_RRT_A)
{
printf ("GOT THE RIGHT ANSSER .... \n");
goto done;
}
}
goto no_valid_reply;
} }
else else
{ {
no_valid_reply:
printf ("XXXXXXXXXXXXXXXXx NO REPLY XXXXXXXXXXXXXXXXXXXXXXXXX\n"); printf ("XXXXXXXXXXXXXXXXx NO REPLY XXXXXXXXXXXXXXXXXXXXXXXXX\n");
} }
done:
if (pi) mio_dns_free_packet_info(mio_svc_dnc_getmio(dnc), pi);
} }
/* ========================================================================= */ /* ========================================================================= */
@ -839,18 +857,18 @@ for (i = 0; i < 5; i++)
{ {
mio_dns_bqr_t qrs[] = mio_dns_bqr_t qrs[] =
{ {
{ "code.miflux.com", MIO_DNS_QTYPE_A, MIO_DNS_QCLASS_IN }, { "code.miflux.com", MIO_DNS_RRT_A, MIO_DNS_RRC_IN },
{ "code.miflux.com", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN }, { "code.miflux.com", MIO_DNS_RRT_AAAA, MIO_DNS_RRC_IN },
{ "code.abiyo.net", MIO_DNS_QTYPE_A, MIO_DNS_QCLASS_IN }, { "code.abiyo.net", MIO_DNS_RRT_A, MIO_DNS_RRC_IN },
{ "code6.abiyo.net", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN }, { "code6.abiyo.net", MIO_DNS_RRT_AAAA, MIO_DNS_RRC_IN },
{ "abiyo.net", MIO_DNS_QTYPE_MX, MIO_DNS_QCLASS_IN } { "abiyo.net", MIO_DNS_RRT_MX, MIO_DNS_RRC_IN }
}; };
mio_dns_brr_t rrs[] = mio_dns_brr_t rrs[] =
{ {
{ MIO_DNS_RR_PART_ANSWER, "code.miflux.com", MIO_DNS_QTYPE_A, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL }, { MIO_DNS_RR_PART_ANSWER, "code.miflux.com", MIO_DNS_RRT_A, MIO_DNS_RRC_IN, 86400, 0, MIO_NULL },
{ MIO_DNS_RR_PART_ANSWER, "code.miflux.com", MIO_DNS_QTYPE_AAAA, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL }, { MIO_DNS_RR_PART_ANSWER, "code.miflux.com", MIO_DNS_RRT_AAAA, MIO_DNS_RRC_IN, 86400, 0, MIO_NULL },
{ MIO_DNS_RR_PART_AUTHORITY, "dns.miflux.com", MIO_DNS_QTYPE_NS, MIO_DNS_QCLASS_IN, 86400, 0, MIO_NULL }//, { MIO_DNS_RR_PART_AUTHORITY, "dns.miflux.com", MIO_DNS_RRT_NS, MIO_DNS_RRC_IN, 86400, 0, MIO_NULL }//,
//{ MIO_DNS_RR_PART_ANSERT, "www.miflux.com", MIO_DNS_QTYPE_CNAME, MIO_DNS_QCLASS_IN, 60, 15, "code.miflux.com" } //{ MIO_DNS_RR_PART_ANSERT, "www.miflux.com", MIO_DNS_RRT_CNAME, MIO_DNS_RRC_IN, 60, 15, "code.miflux.com" }
}; };
mio_dns_beopt_t beopt[] = mio_dns_beopt_t beopt[] =
@ -870,7 +888,7 @@ for (i = 0; i < 5; i++)
beopt beopt
}; };
mio_dns_bdns_t qhdr = mio_dns_bhdr_t qhdr =
{ {
-1, /* id */ -1, /* id */
0, /* qr */ 0, /* qr */
@ -884,7 +902,7 @@ for (i = 0; i < 5; i++)
MIO_DNS_RCODE_NOERROR /* rcode */ MIO_DNS_RCODE_NOERROR /* rcode */
}; };
mio_dns_bdns_t rhdr = mio_dns_bhdr_t rhdr =
{ {
0x1234, /* id */ 0x1234, /* id */
1, /* qr */ 1, /* qr */
@ -903,7 +921,7 @@ for (i = 0; i < 5; i++)
mio_svc_dnc_sendmsg (dnc, &rhdr, qrs, MIO_COUNTOF(qrs), rrs, MIO_COUNTOF(rrs), &qedns, MIO_NULL); mio_svc_dnc_sendmsg (dnc, &rhdr, qrs, MIO_COUNTOF(qrs), rrs, MIO_COUNTOF(rrs), &qedns, MIO_NULL);
} }
if (mio_svc_dnc_resolve(dnc, "www.microsoft.com", MIO_DNS_QTYPE_A, on_dnc_resolve) <= -1) if (mio_svc_dnc_resolve(dnc, "www.microsoft.com", MIO_DNS_RRT_A, on_dnc_resolve) <= -1)
{ {
printf ("resolve attempt failure ---> code.miflux.com\n"); printf ("resolve attempt failure ---> code.miflux.com\n");
} }

View File

@ -153,51 +153,51 @@ MIO_DEBUG1 (mio, "releasing dns msg %d\n", (int)mio_ntoh16(dns_msg_to_pkt(msg)->
static mio_oow_t encode_rdata_in_dns_msg (mio_svc_dnc_t* dnc, const mio_dns_brr_t* rr, mio_dns_rrtr_t* rrtr) static mio_oow_t encode_rdata_in_dns_msg (mio_svc_dnc_t* dnc, const mio_dns_brr_t* rr, mio_dns_rrtr_t* rrtr)
{ {
switch (rr->qtype) switch (rr->rrtype)
{ {
case MIO_DNS_QTYPE_A: case MIO_DNS_RRT_A:
break; break;
case MIO_DNS_QTYPE_AAAA: case MIO_DNS_RRT_AAAA:
break; break;
/* /*
case MIO_DNS_QTYPE_WKS: case MIO_DNS_RRT_WKS:
break; */ break; */
case MIO_DNS_QTYPE_MX: case MIO_DNS_RRT_MX:
/* preference, exchange */ /* preference, exchange */
break; break;
case MIO_DNS_QTYPE_CNAME: case MIO_DNS_RRT_CNAME:
/*case MIO_DNS_QTYPE_MB: /*case MIO_DNS_RRT_MB:
case MIO_DNS_QTYPE_MD: case MIO_DNS_RRT_MD:
case MIO_DNS_QTYPE_MF: case MIO_DNS_RRT_MF:
case MIO_DNS_QTYPE_MG: case MIO_DNS_RRT_MG:
case MIO_DNS_QTYPE_MR:*/ case MIO_DNS_RRT_MR:*/
case MIO_DNS_QTYPE_NS: case MIO_DNS_RRT_NS:
case MIO_DNS_QTYPE_PTR: case MIO_DNS_RRT_PTR:
/* just a normal domain name */ /* just a normal domain name */
break; break;
#if 0 #if 0
case MIO_DNS_QTYPE_HINFO: case MIO_DNS_RRT_HINFO:
/* cpu, os */ /* cpu, os */
break; break;
#endif #endif
#if 0 #if 0
case MIO_DNS_QTYPE_MINFO: case MIO_DNS_RRT_MINFO:
/* rmailbx, emailbx */ /* rmailbx, emailbx */
#endif #endif
break; break;
case MIO_DNS_QTYPE_SOA: case MIO_DNS_RRT_SOA:
/* soa */ /* soa */
break; break;
case MIO_DNS_QTYPE_TXT: case MIO_DNS_RRT_TXT:
case MIO_DNS_QTYPE_NULL: case MIO_DNS_RRT_NULL:
default: default:
/* TODO: custom transformator? */ /* TODO: custom transformator? */
rrtr->dlen = mio_hton16(rr->dlen); rrtr->dlen = mio_hton16(rr->dlen);
@ -207,7 +207,7 @@ static mio_oow_t encode_rdata_in_dns_msg (mio_svc_dnc_t* dnc, const mio_dns_brr_
return rr->dlen; return rr->dlen;
} }
static mio_dns_msg_t* build_dns_msg (mio_svc_dnc_t* dnc, mio_dns_bdns_t* bdns, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count, mio_dns_bedns_t* edns, void* ctx) static mio_dns_msg_t* build_dns_msg (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count, mio_dns_bedns_t* edns, void* ctx)
{ {
mio_t* mio = dnc->mio; mio_t* mio = dnc->mio;
mio_oow_t dnlen, msgbufsz, i; mio_oow_t dnlen, msgbufsz, i;
@ -231,7 +231,7 @@ static mio_dns_msg_t* build_dns_msg (mio_svc_dnc_t* dnc, mio_dns_bdns_t* bdns, m
for (i = 0; i < rr_count; i++) for (i = 0; i < rr_count; i++)
{ {
msgbufsz += mio_count_bcstr(rr[i].qname) + 2 + MIO_SIZEOF(*rrtr) + rr[i].dlen; msgbufsz += mio_count_bcstr(rr[i].rrname) + 2 + MIO_SIZEOF(*rrtr) + rr[i].dlen;
} }
edns_dlen = 0; edns_dlen = 0;
@ -305,17 +305,17 @@ static mio_dns_msg_t* build_dns_msg (mio_svc_dnc_t* dnc, mio_dns_bdns_t* bdns, m
{ {
mio_oow_t rdata_len; mio_oow_t rdata_len;
dnlen = to_dn((mio_svc_dns_t*)dnc, rr[i].qname, dn, mio_count_bcstr(rr[i].qname) + 2); dnlen = to_dn((mio_svc_dns_t*)dnc, rr[i].rrname, dn, mio_count_bcstr(rr[i].rrname) + 2);
if (dnlen <= 0) if (dnlen <= 0)
{ {
release_dns_msg (dnc, msg); release_dns_msg (dnc, msg);
mio_seterrbfmt (mio, MIO_EINVAL, "invalid domain name - %hs", rr[i].qname); mio_seterrbfmt (mio, MIO_EINVAL, "invalid domain name - %hs", rr[i].rrname);
return MIO_NULL; return MIO_NULL;
} }
rrtr = (mio_dns_rrtr_t*)(dn + dnlen); rrtr = (mio_dns_rrtr_t*)(dn + dnlen);
rrtr->qtype = mio_hton16(rr[i].qtype); rrtr->rrtype = mio_hton16(rr[i].rrtype);
rrtr->qclass = mio_hton16(rr[i].qclass); rrtr->rrclass = mio_hton16(rr[i].rrclass);
rrtr->ttl = mio_hton32(rr[i].ttl); rrtr->ttl = mio_hton32(rr[i].ttl);
rdata_len = encode_rdata_in_dns_msg(dnc, &rr[i], rrtr); rdata_len = encode_rdata_in_dns_msg(dnc, &rr[i], rrtr);
@ -337,8 +337,8 @@ static mio_dns_msg_t* build_dns_msg (mio_svc_dnc_t* dnc, mio_dns_bdns_t* bdns, m
/* add EDNS0 OPT RR */ /* add EDNS0 OPT RR */
*dn = 0; /* root domain. as if to_dn("") is called */ *dn = 0; /* root domain. as if to_dn("") is called */
rrtr = (mio_dns_rrtr_t*)(dn + 1); rrtr = (mio_dns_rrtr_t*)(dn + 1);
rrtr->qtype = MIO_CONST_HTON16(MIO_DNS_QTYPE_OPT); rrtr->rrtype = MIO_CONST_HTON16(MIO_DNS_RRT_OPT);
rrtr->qclass = mio_hton16(edns->uplen); rrtr->rrclass = mio_hton16(edns->uplen);
rrtr->ttl = mio_hton32(MIO_DNS_EDNS_MAKE_TTL(bdns->rcode, edns->version, edns->dnssecok)); rrtr->ttl = mio_hton32(MIO_DNS_EDNS_MAKE_TTL(bdns->rcode, edns->version, edns->dnssecok));
rrtr->dlen = mio_hton16((mio_uint16_t)edns_dlen); rrtr->dlen = mio_hton16((mio_uint16_t)edns_dlen);
dn = (mio_uint8_t*)(rrtr + 1); dn = (mio_uint8_t*)(rrtr + 1);
@ -482,6 +482,7 @@ MIO_DEBUG1 (mio, "sent dns message %d\n", (int)mio_ntoh16(dns_msg_to_pkt(msg)->i
msg->rtmridx = mio_instmrjob(mio, &tmrjob); msg->rtmridx = mio_instmrjob(mio, &tmrjob);
if (msg->rtmridx == MIO_TMRIDX_INVALID) if (msg->rtmridx == MIO_TMRIDX_INVALID)
{ {
/* call the callback to indicate this operation failure in the middle of transaction */
if (MIO_LIKELY(msg->ctx)) if (MIO_LIKELY(msg->ctx))
((mio_svc_dnc_on_reply_t)msg->ctx) (dnc, msg, mio_geterrnum(mio), MIO_NULL, 0); ((mio_svc_dnc_on_reply_t)msg->ctx) (dnc, msg, mio_geterrnum(mio), MIO_NULL, 0);
release_dns_msg (dnc, msg); release_dns_msg (dnc, msg);
@ -571,7 +572,7 @@ void mio_svc_dnc_stop (mio_svc_dnc_t* dnc)
} }
int mio_svc_dnc_sendmsg (mio_svc_dnc_t* dnc, mio_dns_bdns_t* bdns, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count, mio_dns_bedns_t* edns, mio_svc_dnc_on_reply_t on_reply) int mio_svc_dnc_sendmsg (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_brr_t* rr, mio_oow_t rr_count, mio_dns_bedns_t* edns, mio_svc_dnc_on_reply_t on_reply)
{ {
/* send a request or a response */ /* send a request or a response */
mio_dns_msg_t* msg; mio_dns_msg_t* msg;
@ -589,10 +590,17 @@ int mio_svc_dnc_sendmsg (mio_svc_dnc_t* dnc, mio_dns_bdns_t* bdns, mio_dns_bqr_t
return 0; return 0;
} }
int mio_svc_dnc_sendreq (mio_svc_dnc_t* dnc, mio_dns_bdns_t* bdns, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_bedns_t* edns, mio_svc_dnc_on_reply_t on_reply) int mio_svc_dnc_sendreq (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mio_dns_bqr_t* qr, mio_oow_t qr_count, mio_dns_bedns_t* edns, mio_svc_dnc_on_reply_t on_reply)
{ {
/* send requests without resource record */ /* send requests without resource record */
mio_oow_t i; mio_oow_t i;
if (bdns->rcode != MIO_DNS_RCODE_NOERROR)
{
mio_seterrnum (dnc->mio, MIO_EINVAL);
return -1;
}
for (i = 0; i < qr_count; i++) for (i = 0; i < qr_count; i++)
{ {
if (mio_svc_dnc_sendmsg(dnc, bdns, &qr[i], 1, MIO_NULL, 0, edns, on_reply) <= -1) return -1; if (mio_svc_dnc_sendmsg(dnc, bdns, &qr[i], 1, MIO_NULL, 0, edns, on_reply) <= -1) return -1;
@ -600,9 +608,9 @@ int mio_svc_dnc_sendreq (mio_svc_dnc_t* dnc, mio_dns_bdns_t* bdns, mio_dns_bqr_t
return 0; return 0;
} }
int mio_svc_dnc_resolve (mio_svc_dnc_t* dnc, const mio_bch_t* qname, mio_dns_qtype_t qtype, mio_svc_dnc_on_reply_t on_reply) int mio_svc_dnc_resolve (mio_svc_dnc_t* dnc, const mio_bch_t* qname, mio_dns_rrt_t qtype, mio_svc_dnc_on_reply_t on_reply)
{ {
static mio_dns_bdns_t qhdr = static mio_dns_bhdr_t qhdr =
{ {
-1, /* id */ -1, /* id */
0, /* qr */ 0, /* qr */
@ -631,7 +639,7 @@ int mio_svc_dnc_resolve (mio_svc_dnc_t* dnc, const mio_bch_t* qname, mio_dns_qty
qr.qname = (mio_bch_t*)qname; qr.qname = (mio_bch_t*)qname;
qr.qtype = qtype; qr.qtype = qtype;
qr.qclass = MIO_DNS_QCLASS_IN; qr.qclass = MIO_DNS_RRC_IN;
return mio_svc_dnc_sendreq(dnc, &qhdr, &qr, 1, &qedns, on_reply); return mio_svc_dnc_sendreq(dnc, &qhdr, &qr, 1, &qedns, on_reply);
} }
@ -639,43 +647,56 @@ int mio_svc_dnc_resolve (mio_svc_dnc_t* dnc, const mio_bch_t* qname, mio_dns_qty
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static mio_uint8_t* parse_domain_name (mio_t* mio, mio_uint8_t* ptr, mio_uint8_t* pktstart, mio_uint8_t* pktend) static int parse_domain_name (mio_t* mio, mio_dns_pkt_info_t* pi)
{ {
mio_oow_t totlen, seglen; mio_oow_t seglen;
mio_uint8_t* xptr; mio_uint8_t* xptr;
if (ptr >= pktend) goto oops; if (MIO_UNLIKELY(pi->ptr >= pi->end)) goto oops;
xptr = MIO_NULL; xptr = MIO_NULL;
totlen = 0;
printf ("\t"); printf ("\t");
while ((seglen = *ptr++) > 0) if ((seglen = *pi->ptr++) == 0)
{
printf ("\n");
if (pi->rrdptr) pi->rrdptr[0] = '\0';
pi->rrdlen++; /* for a terminating null */
return 0;
}
do
{ {
if (MIO_LIKELY(seglen < 64)) if (MIO_LIKELY(seglen < 64))
{ {
/* normal. 00XXXXXXXX */ /* normal. 00XXXXXXXX */
normal: normal:
printf ("[%.*s]", (int)seglen, ptr); printf ("[%.*s]", (int)seglen, pi->ptr);
totlen += seglen; if (pi->rrdptr)
ptr += seglen; {
if (MIO_UNLIKELY(ptr >= pktend)) goto oops; MIO_MEMCPY (pi->rrdptr, pi->ptr, seglen);
pi->rrdptr += seglen + 1; /* +1 for '.' */
pi->rrdptr[-1] = '.';
}
pi->rrdlen += seglen + 1; /* +1 for '.' */
pi->ptr += seglen;
if (MIO_UNLIKELY(pi->ptr >= pi->end)) goto oops;
} }
else if (seglen >= 192) else if (seglen >= 192)
{ {
/* compressed. 11XXXXXXXX XXXXXXXX */ /* compressed. 11XXXXXXXX XXXXXXXX */
mio_oow_t offset; mio_oow_t offset;
if (MIO_UNLIKELY(ptr >= pktend)) goto oops; /* check before ptr++ in the next line */ if (MIO_UNLIKELY(pi->ptr >= pi->end)) goto oops;
offset = ((seglen & 0x3F) << 8) | *ptr++; offset = ((seglen & 0x3F) << 8) | *pi->ptr++;
if (MIO_UNLIKELY(&pktstart[offset] >= pktend)) goto oops; if (MIO_UNLIKELY(pi->ptr >= pi->end)) goto oops;
seglen = pktstart[offset]; seglen = pi->start[offset];
if (seglen >= 64) goto oops; /* the pointed position must not contain another pointer */ if (seglen >= 64) goto oops; /* the pointed position must not contain another pointer */
if (!xptr) xptr = ptr; /* some later parts can also be a poitner again. so xptr, once set, must not be set again */ if (!xptr) xptr = pi->ptr; /* some later parts can also be a poitner again. so xptr, once set, must not be set again */
ptr = &pktstart[offset + 1]; pi->ptr = &pi->start[offset + 1];
if (MIO_UNLIKELY(ptr >= pktend)) goto oops; if (MIO_UNLIKELY(pi->ptr >= pi->end)) goto oops;
goto normal; goto normal;
} }
@ -690,69 +711,103 @@ printf ("[%.*s]", (int)seglen, ptr);
goto oops; goto oops;
} }
} }
while ((seglen = *pi->ptr++) > 0);
printf ("\n"); printf ("\n");
return xptr? xptr: ptr; if (pi->rrdptr) pi->rrdptr[-1] = '\0';
if (xptr) pi->ptr = xptr;
return 0;
oops: oops:
mio_seterrbfmt (mio, MIO_EINVAL, "invalid packet"); mio_seterrnum (mio, MIO_EINVAL);
return MIO_NULL; return -1;
} }
static mio_uint8_t* parse_question (mio_t* mio, mio_uint8_t* ptr, mio_uint8_t* pktstart, mio_uint8_t* pktend) static int parse_question (mio_t* mio, mio_oow_t pos, mio_dns_pkt_info_t* pi)
{ {
mio_dns_qrtr_t* qrtr; mio_dns_qrtr_t* qrtr;
mio_uint8_t* xrrdptr;
ptr = parse_domain_name(mio, ptr, pktstart, pktend); xrrdptr = pi->rrdptr;
if (!ptr) return MIO_NULL; if (parse_domain_name(mio, pi) <= -1) return -1;
qrtr = (mio_dns_qrtr_t*)ptr; qrtr = (mio_dns_qrtr_t*)pi->ptr;
ptr += MIO_SIZEOF(*qrtr); pi->ptr += MIO_SIZEOF(*qrtr);
if (MIO_UNLIKELY(ptr >= pktend)) goto oops; pi->rrdlen += MIO_SIZEOF(*qrtr);
if (MIO_UNLIKELY(pi->ptr >= pi->end)) goto oops;
return ptr; if (pi->rrdptr)
{
mio_dns_bqr_t* bqr;
bqr = pi->rr.qd;
bqr[pos].qname = (mio_bch_t*)xrrdptr;
bqr[pos].qtype = mio_ntoh16(qrtr->qtype);
bqr[pos].qclass = mio_ntoh16(qrtr->qclass);
}
return 0;
oops: oops:
mio_seterrbfmt (mio, MIO_EINVAL, "invalid packet"); mio_seterrnum (mio, MIO_EINVAL);
return MIO_NULL; return -1;
} }
static mio_uint8_t* parse_answer (mio_t* mio, mio_uint8_t* ptr, mio_uint8_t* pktstart, mio_uint8_t* pktend) static int parse_answer (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos, mio_dns_pkt_info_t* pi)
{ {
mio_dns_rrtr_t* rrtr; mio_dns_rrtr_t* rrtr;
mio_uint16_t qtype, dlen; mio_uint16_t qtype, dlen;
mio_oow_t remsize; mio_oow_t remsize;
mio_uint8_t* xrrdptr;
//printf ("pktstart = %p pktend = %p, ptr = %p\n", pktstart, pktend, ptr); xrrdptr = pi->rrdptr;
ptr = parse_domain_name(mio, ptr, pktstart, pktend); if (parse_domain_name(mio, pi) <= -1) return -1;
if (!ptr) return MIO_NULL;
rrtr = (mio_dns_rrtr_t*)ptr; rrtr = (mio_dns_rrtr_t*)pi->ptr;
if (MIO_UNLIKELY(pktend - ptr < MIO_SIZEOF(*rrtr))) goto oops; if (MIO_UNLIKELY(pi->end - pi->ptr < MIO_SIZEOF(*rrtr))) goto oops;
ptr += MIO_SIZEOF(*rrtr); pi->ptr += MIO_SIZEOF(*rrtr);
dlen = mio_ntoh16(rrtr->dlen); dlen = mio_ntoh16(rrtr->dlen);
if (MIO_UNLIKELY(pktend - ptr < dlen)) goto oops; if (MIO_UNLIKELY(pi->end - pi->ptr < dlen)) goto oops;
//printf ("rrtr->dlen => %d\n", dlen);
qtype = mio_ntoh16(rrtr->qtype); qtype = mio_ntoh16(rrtr->rrtype);
remsize = pktend - ptr; remsize = pi->end - pi->ptr;
if (pi->rrdptr)
{
/* store information about the actual record */
mio_dns_brr_t* brr;
switch (rr_part)
{
case MIO_DNS_RR_PART_ANSWER: brr = pi->rr.an; break;
case MIO_DNS_RR_PART_AUTHORITY: brr = pi->rr.ns; break;
case MIO_DNS_RR_PART_ADDITIONAL: brr = pi->rr.ar; break;
}
brr[pos].part = rr_part;
brr[pos].rrname = (mio_bch_t*)xrrdptr;
brr[pos].rrtype = mio_ntoh16(rrtr->rrtype);
brr[pos].rrclass = mio_ntoh16(rrtr->rrclass);
brr[pos].ttl = mio_ntoh32(rrtr->ttl);
brr[pos].dptr = pi->rrdptr;
brr[pos].dlen = dlen;
}
switch (qtype) switch (qtype)
{ {
case MIO_DNS_QTYPE_OPT: case MIO_DNS_RRT_OPT:
{ {
/* RFC 6891 /* RFC 6891
The extended RCODE and flags, which OPT stores in the RR Time to Live The extended RCODE and flags, which OPT stores in the RR Time to Live
(TTL) field, are structured as follows: (TTL) field, are structured as follows:
+0 (MSB) +1 (LSB)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0: | EXTENDED-RCODE | VERSION | 0: | EXTENDED-RCODE | VERSION |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2: | DO| Z | 2: | DO| Z |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
*
EXTENDED-RCODE EXTENDED-RCODE
Forms the upper 8 bits of extended 12-bit RCODE (together with the Forms the upper 8 bits of extended 12-bit RCODE (together with the
4 bits defined in [RFC1035]. Note that EXTENDED-RCODE value 0 4 bits defined in [RFC1035]. Note that EXTENDED-RCODE value 0
@ -760,96 +815,146 @@ static mio_uint8_t* parse_answer (mio_t* mio, mio_uint8_t* ptr, mio_uint8_t* pkt
15). 15).
*/ */
printf ("OPT RR included....>>>>>>>>>>>>>>>>>>>>>>>>%d\n", (rrtr->ttl >> 24)); /* TODO: do i need to check if rrname is <ROOT>? */
/*rcode |= (rrtr->ttl >> 24);*/ pi->edns.exist = 1;
if (((rrtr->ttl >> 16) & 0xFF) != 0) goto oops; /* version not 0 */ pi->edns.uplen = mio_ntoh16(rrtr->rrclass);
/* dnsok -> ((rrtr->ttl & 0x8000) >> 15) */ pi->hdr.rcode |= (rrtr->ttl >> 24);
pi->edns.version = (rrtr->ttl >> 16) & 0xFF;
pi->edns.dnssecok = ((rrtr->ttl & 0x8000) >> 15);
/*if ((rrtr->ttl & 0x7FFF) != 0) goto oops;*/ /* Z not 0 - ignore this for now */ /*if ((rrtr->ttl & 0x7FFF) != 0) goto oops;*/ /* Z not 0 - ignore this for now */
break; break;
} }
case MIO_DNS_QTYPE_A: case MIO_DNS_RRT_A:
if (MIO_UNLIKELY(remsize < 4)) goto oops; if (MIO_UNLIKELY(remsize < 4)) goto oops;
break; break;
case MIO_DNS_QTYPE_AAAA: case MIO_DNS_RRT_AAAA:
if (MIO_UNLIKELY(remsize < 16)) goto oops; if (MIO_UNLIKELY(remsize < 16)) goto oops;
break; break;
case MIO_DNS_QTYPE_CNAME:
{
mio_uint8_t* xptr;
printf ("\t");
xptr = parse_domain_name(mio, ptr, pktstart, pktend);
if (!xptr) return MIO_NULL;
MIO_ASSERT (mio, xptr == ptr + dlen); case MIO_DNS_RRT_CNAME:
{
#if !defined(MIO_BUILD_RELEASE)
mio_uint8_t* xptr = pi->ptr;
#endif
printf ("\t");
if (parse_domain_name(mio, pi) <= -1) return -1;
MIO_ASSERT (mio, pi->ptr == xptr + dlen);
dlen = 0; /* to skip additional update on pi->ptr and data copy before return */
break; break;
} }
} }
ptr += dlen; if (dlen > 0)
return ptr;
oops:
mio_seterrbfmt (mio, MIO_EINVAL, "invalid packet");
return MIO_NULL;
}
int mio_dns_parse_packet (mio_svc_dnc_t* dnc, mio_dns_pkt_t* pkt, mio_oow_t len, mio_dns_bdns_t* bdns)
{
mio_t* mio = dnc->mio;
mio_uint16_t i, rrc;
mio_uint8_t* ptr;
mio_uint8_t* pktend = (mio_uint8_t*)pkt + len;
MIO_ASSERT (mio, len >= MIO_SIZEOF(*pkt));
bdns->id = mio_ntoh16(pkt->id);
bdns->qr = pkt->qr & 0x01;
bdns->opcode = pkt->opcode & 0x0F;
bdns->aa = pkt->aa & 0x01;
bdns->tc = pkt->tc & 0x01;
bdns->rd = pkt->rd & 0x01;
bdns->ra = pkt->ra & 0x01;
bdns->ad = pkt->ad & 0x01;
bdns->cd = pkt->cd & 0x01;
bdns->rcode = pkt->rcode & 0x0F;
ptr = (mio_uint8_t*)(pkt + 1);
rrc = mio_ntoh16(pkt->qdcount);
printf ("question %d\n", rrc);
for (i = 0; i < rrc; i++)
{ {
ptr = parse_question(mio, ptr, (mio_uint8_t*)pkt, pktend); pi->ptr += dlen;
if (!ptr) return -1; pi->rrdlen += dlen;
} if (pi->rrdptr) MIO_MEMCPY (pi->rrdptr, rrtr + 1, dlen); /* copy actual data */
rrc = mio_ntoh16(pkt->ancount);
printf ("answer %d\n", rrc);
for (i = 0; i < rrc; i++)
{
ptr = parse_answer(mio, ptr, (mio_uint8_t*)pkt, pktend);
if (!ptr) return -1;
}
rrc = mio_ntoh16(pkt->nscount);
printf ("authority %d\n", rrc);
for (i = 0; i < rrc; i++)
{
ptr = parse_answer(mio, ptr, (mio_uint8_t*)pkt, pktend);
if (!ptr) return -1;
}
rrc = mio_ntoh16(pkt->arcount);
printf ("additional %d\n", rrc);
for (i = 0; i < rrc; i++)
{
ptr = parse_answer(mio, ptr, (mio_uint8_t*)pkt, pktend);
if (!ptr) return -1;
} }
return 0; return 0;
oops:
mio_seterrnum (mio, MIO_EINVAL);
return -1;
}
mio_dns_pkt_info_t* mio_dns_make_packet_info (mio_t* mio, const mio_dns_pkt_t* pkt, mio_oow_t len)
{
mio_uint16_t i;
mio_dns_pkt_info_t pib, * pii;
MIO_ASSERT (mio, len >= MIO_SIZEOF(*pkt));
MIO_MEMSET (&pib, 0, MIO_SIZEOF(pib));
pii = &pib;
redo:
pii->start = (mio_uint8_t*)pkt;
pii->end = (mio_uint8_t*)pkt + len;
pii->ptr = (mio_uint8_t*)(pkt + 1);
pii->hdr.id = mio_ntoh16(pkt->id);
pii->hdr.qr = pkt->qr & 0x01;
pii->hdr.opcode = pkt->opcode & 0x0F;
pii->hdr.aa = pkt->aa & 0x01;
pii->hdr.tc = pkt->tc & 0x01;
pii->hdr.rd = pkt->rd & 0x01;
pii->hdr.ra = pkt->ra & 0x01;
pii->hdr.ad = pkt->ad & 0x01;
pii->hdr.cd = pkt->cd & 0x01;
pii->hdr.rcode = pkt->rcode & 0x0F;
pii->qdcount = mio_ntoh16(pkt->qdcount);
pii->ancount = mio_ntoh16(pkt->ancount);
pii->nscount = mio_ntoh16(pkt->nscount);
pii->arcount = mio_ntoh16(pkt->arcount);
for (i = 0; i < pii->qdcount; i++)
{
if (parse_question(mio, i, pii) <= -1) goto oops;
}
for (i = 0; i < pii->ancount; i++)
{
if (parse_answer(mio, MIO_DNS_RR_PART_ANSWER, i, pii) <= -1) goto oops;
}
for (i = 0; i < pii->nscount; i++)
{
if (parse_answer(mio, MIO_DNS_RR_PART_AUTHORITY, i, pii) <= -1) goto oops;
}
for (i = 0; i < pii->arcount; i++)
{
if (parse_answer(mio, MIO_DNS_RR_PART_ADDITIONAL, i, pii) <= -1) goto oops;
}
if (pii == &pib)
{
/* TODO: buffer management... */
pii = (mio_dns_pkt_info_t*)mio_callocmem(mio, MIO_SIZEOF(*pii) + (MIO_SIZEOF(mio_dns_bqr_t) * pib.qdcount) + (MIO_SIZEOF(mio_dns_brr_t) * (pib.ancount + pib.nscount + pib.arcount)) + pib.rrdlen);
if (!pii) goto oops;
pii->rr.qd = (mio_dns_bqr_t*)(&pii[1]);
pii->rr.an = (mio_dns_brr_t*)&pii->rr.qd[pib.qdcount];
pii->rr.ns = (mio_dns_brr_t*)&pii->rr.an[pib.ancount];
pii->rr.ar = (mio_dns_brr_t*)&pii->rr.ns[pib.nscount];
pii->rrdptr = (mio_uint8_t*)&pii->rr.ar[pib.arcount];
goto redo;
}
printf (">>>>>>>> RRDLEN = %d\n", (int)pii->rrdlen);
printf (">>>>>>>> RCODE %d EDNS exist %d uplen %d version %d dnssecok %d\n", pii->hdr.rcode, pii->edns.exist, pii->edns.uplen, pii->edns.version, pii->edns.dnssecok);
for (i = 0; i < pii->qdcount; i++)
{
printf ("qd %d -> %s %d\n", i, pii->rr.qd[i].qname, pii->rr.qd[i].qtype);
}
for (i = 0; i < pii->ancount; i++)
{
printf ("an %d -> %s %d\n", i, pii->rr.an[i].rrname, pii->rr.an[i].rrtype);
}
for (i = 0; i < pii->nscount; i++)
{
printf ("ns %d -> %s %d\n", i, pii->rr.ns[i].rrname, pii->rr.ns[i].rrtype);
}
for (i = 0; i < pii->arcount; i++)
{
printf ("ar %d -> %s %d\n", i, pii->rr.ar[i].rrname, pii->rr.ar[i].rrtype);
}
return pii;
oops:
if (pii && pii != &pib) mio_freemem (mio, pii);
return MIO_NULL;
}
void mio_dns_free_packet_info (mio_t* mio, mio_dns_pkt_info_t* pi)
{
/* TODO: better management */
return mio_freemem (mio, pi);
} }

View File

@ -55,6 +55,10 @@ enum mio_dns_rcode_t
MIO_DNS_RCODE_NXRRSET = 8, /* RR set exists when it should not */ MIO_DNS_RCODE_NXRRSET = 8, /* RR set exists when it should not */
MIO_DNS_RCODE_NOTAUTH = 9, /* not authorized or server not authoritative for zone*/ MIO_DNS_RCODE_NOTAUTH = 9, /* not authorized or server not authoritative for zone*/
MIO_DNS_RCODE_NOTZONE = 10, /* name not contained in zone */ MIO_DNS_RCODE_NOTZONE = 10, /* name not contained in zone */
/* the standard rcode field is 4 bit long. so the max is 15. */
/* items belows require EDNS0 */
MIO_DNS_RCODE_BADVERS = 16, MIO_DNS_RCODE_BADVERS = 16,
MIO_DNS_RCODE_BADSIG = 17, MIO_DNS_RCODE_BADSIG = 17,
MIO_DNS_RCODE_BADTIME = 18, MIO_DNS_RCODE_BADTIME = 18,
@ -66,35 +70,64 @@ enum mio_dns_rcode_t
}; };
typedef enum mio_dns_rcode_t mio_dns_rcode_t; typedef enum mio_dns_rcode_t mio_dns_rcode_t;
enum mio_dns_qtype_t
{
MIO_DNS_QTYPE_A = 1,
MIO_DNS_QTYPE_NS = 2,
MIO_DNS_QTYPE_CNAME = 5,
MIO_DNS_QTYPE_SOA = 6,
MIO_DNS_QTYPE_NULL = 10,
MIO_DNS_QTYPE_PTR = 12,
MIO_DNS_QTYPE_MX = 15,
MIO_DNS_QTYPE_TXT = 16,
MIO_DNS_QTYPE_AAAA = 28,
MIO_DNS_QTYPE_EID = 31,
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;
enum mio_dns_qclass_t enum mio_dns_rrt_t
{ {
MIO_DNS_QCLASS_IN = 1, /* internet */ /*
MIO_DNS_QCLASS_CH = 3, /* chaos */ * [RFC1035]
MIO_DNS_QCLASS_HS = 4, /* hesiod */ * TYPE fields are used in resource records. Note that these types are a
MIO_DNS_QCLASS_NONE = 254, * subset of QTYPEs.
MIO_DNS_QCLASS_ANY = 255 */
MIO_DNS_RRT_A = 1,
MIO_DNS_RRT_NS = 2,
MIO_DNS_RRT_CNAME = 5,
MIO_DNS_RRT_SOA = 6,
MIO_DNS_RRT_NULL = 10,
MIO_DNS_RRT_PTR = 12,
MIO_DNS_RRT_MX = 15,
MIO_DNS_RRT_TXT = 16,
MIO_DNS_RRT_AAAA = 28,
MIO_DNS_RRT_EID = 31,
MIO_DNS_RRT_SRV = 33,
MIO_DNS_RRT_OPT = 41,
MIO_DNS_RRT_RRSIG = 46,
/*
* [RFC1035]
* QTYPE fields appear in the question part of a query. QTYPES are a
* superset of TYPEs, hence all TYPEs are valid QTYPEs. In addition, the
* following QTYPEs are defined:
*/
MIO_DNS_RRT_Q_AFXR = 252, /* A request for a transfer of an entire zone */
MIO_DNS_RRT_Q_MAILB = 253, /* A request for mailbox-related records (MB, MG or MR) */
MIO_DNS_RRT_Q_MAILA = 254, /* A request for mail agent RRs (Obsolete - see MX) */
MIO_DNS_RRT_Q_ANY = 255 /* A request for all records */
}; };
typedef enum mio_dns_qclass_t mio_dns_qclass_t; typedef enum mio_dns_rrt_t mio_dns_rrt_t;
/*
* CLASS fields appear in resource records. The following CLASS mnemonics
* and values are defined:
*/
enum mio_dns_rrc_t
{
MIO_DNS_RRC_IN = 1, /* internet */
MIO_DNS_RRC_CH = 3, /* chaos */
MIO_DNS_RRC_HS = 4, /* Hesiod [Dyer 87] */
MIO_DNS_RRC_NONE = 254,
/*
*
* QCLASS fields appear in the question section of a query. QCLASS values
* are a superset of CLASS values; every CLASS is a valid QCLASS. In
* addition to CLASS values, the following QCLASSes are defined:
*/
MIO_DNS_RRC_Q_ANY = 255
};
typedef enum mio_dns_rrc_t mio_dns_rrc_t;
enum mio_dns_eopt_code_t enum mio_dns_eopt_code_t
{ {
@ -188,8 +221,8 @@ typedef struct mio_dns_qrtr_t mio_dns_qrtr_t;
struct mio_dns_rrtr_t struct mio_dns_rrtr_t
{ {
/* qname upto 64 bytes */ /* qname upto 64 bytes */
mio_uint16_t qtype; mio_uint16_t rrtype;
mio_uint16_t qclass; mio_uint16_t rrclass;
mio_uint32_t ttl; mio_uint32_t ttl;
mio_uint16_t dlen; /* data length */ mio_uint16_t dlen; /* data length */
/* actual data if if dlen > 0 */ /* actual data if if dlen > 0 */
@ -214,8 +247,8 @@ typedef struct mio_dns_eopt_t mio_dns_eopt_t;
(((rd) & 0x01) << 8) | (((ra) & 0x01) << 7) | (((ad) & 0x01) << 5) | (((cd) & 0x01) << 4) | ((rcode) & 0x0F)) (((rd) & 0x01) << 8) | (((ra) & 0x01) << 7) | (((ad) & 0x01) << 5) | (((cd) & 0x01) << 4) | ((rcode) & 0x0F))
*/ */
/* breakdown of the dns message id and flags */ /* breakdown of the dns message id and flags. it excludes rr count fields.*/
struct mio_dns_bdns_t struct mio_dns_bhdr_t
{ {
int id; /* auto-assign if negative. */ int id; /* auto-assign if negative. */
@ -230,7 +263,7 @@ struct mio_dns_bdns_t
mio_uint8_t cd; /* checking disabled - dnssec */ mio_uint8_t cd; /* checking disabled - dnssec */
mio_uint8_t rcode; /* reply code - for reply only */ mio_uint8_t rcode; /* reply code - for reply only */
}; };
typedef struct mio_dns_bdns_t mio_dns_bdns_t; typedef struct mio_dns_bhdr_t mio_dns_bhdr_t;
/* breakdown of question record */ /* breakdown of question record */
struct mio_dns_bqr_t struct mio_dns_bqr_t
@ -254,9 +287,9 @@ typedef enum mio_dns_rr_part_t mio_dns_rr_part_t;
struct mio_dns_brr_t struct mio_dns_brr_t
{ {
mio_dns_rr_part_t part; mio_dns_rr_part_t part;
mio_bch_t* qname; mio_bch_t* rrname;
mio_uint16_t qtype; mio_uint16_t rrtype;
mio_uint16_t qclass; mio_uint16_t rrclass;
mio_uint32_t ttl; mio_uint32_t ttl;
mio_uint16_t dlen; mio_uint16_t dlen;
void* dptr; void* dptr;
@ -326,8 +359,9 @@ typedef struct mio_dns_bedns_t mio_dns_bedns_t;
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
typedef struct mio_svc_dns_t mio_svc_dns_t; typedef struct mio_svc_dns_t mio_svc_dns_t; /* server service */
typedef struct mio_svc_dnc_t mio_svc_dnc_t; typedef struct mio_svc_dnc_t mio_svc_dnc_t; /* client service */
typedef struct mio_svc_dnr_t mio_svc_dnr_t; /* recursor service */
typedef void (*mio_svc_dnc_on_reply_t) ( typedef void (*mio_svc_dnc_on_reply_t) (
mio_svc_dnc_t* dnc, mio_svc_dnc_t* dnc,
@ -337,6 +371,53 @@ typedef void (*mio_svc_dnc_on_reply_t) (
mio_oow_t len mio_oow_t len
); );
#define mio_svc_dns_getmio(svc) mio_svc_getmio(svc)
#define mio_svc_dnc_getmio(svc) mio_svc_getmio(svc)
#define mio_svc_dnr_getmio(svc) mio_svc_getmio(svc)
/* ---------------------------------------------------------------- */
struct mio_dns_pkt_info_t
{
mio_uint8_t* start;
mio_uint8_t* end;
mio_uint8_t* ptr;
mio_oow_t rrdlen; /* length needed to store RRs decoded */
mio_uint8_t* rrdptr;
/* data information composed */
mio_dns_bhdr_t hdr;
struct
{
int exist;
mio_uint16_t uplen; /* udp payload len - will be placed in the qclass field of RR. */
mio_uint8_t version;
mio_uint8_t dnssecok;
} edns;
mio_uint16_t qdcount; /* number of questions */
mio_uint16_t ancount; /* number of answers (answer part) */
mio_uint16_t nscount; /* number of name servers (authority part. only NS types) */
mio_uint16_t arcount; /* number of additional resource (additional part) */
struct
{
mio_dns_bqr_t* qd;
mio_dns_brr_t* an;
mio_dns_brr_t* ns;
mio_dns_brr_t* ar;
} rr;
};
typedef struct mio_dns_pkt_info_t mio_dns_pkt_info_t;
/* ---------------------------------------------------------------- */
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
@ -351,7 +432,7 @@ MIO_EXPORT void mio_svc_dnc_stop (
MIO_EXPORT int mio_svc_dnc_sendreq ( MIO_EXPORT int mio_svc_dnc_sendreq (
mio_svc_dnc_t* dnc, mio_svc_dnc_t* dnc,
mio_dns_bdns_t* bdns, mio_dns_bhdr_t* bdns,
mio_dns_bqr_t* qr, mio_dns_bqr_t* qr,
mio_oow_t qr_count, mio_oow_t qr_count,
mio_dns_bedns_t* edns, mio_dns_bedns_t* edns,
@ -360,7 +441,7 @@ MIO_EXPORT int mio_svc_dnc_sendreq (
MIO_EXPORT int mio_svc_dnc_sendmsg ( MIO_EXPORT int mio_svc_dnc_sendmsg (
mio_svc_dnc_t* dnc, mio_svc_dnc_t* dnc,
mio_dns_bdns_t* bdns, mio_dns_bhdr_t* bdns,
mio_dns_bqr_t* qr, mio_dns_bqr_t* qr,
mio_oow_t qr_count, mio_oow_t qr_count,
mio_dns_brr_t* rr, mio_dns_brr_t* rr,
@ -372,17 +453,25 @@ MIO_EXPORT int mio_svc_dnc_sendmsg (
MIO_EXPORT int mio_svc_dnc_resolve ( MIO_EXPORT int mio_svc_dnc_resolve (
mio_svc_dnc_t* dnc, mio_svc_dnc_t* dnc,
const mio_bch_t* qname, const mio_bch_t* qname,
mio_dns_qtype_t qtype, mio_dns_rrt_t qtype,
mio_svc_dnc_on_reply_t on_reply mio_svc_dnc_on_reply_t on_reply
); );
MIO_EXPORT int mio_dns_parse_packet ( /* ---------------------------------------------------------------- */
mio_svc_dnc_t* dnc,
mio_dns_pkt_t* pkt, MIO_EXPORT mio_dns_pkt_info_t* mio_dns_make_packet_info (
mio_oow_t len, mio_t* mio,
mio_dns_bdns_t* bdns const mio_dns_pkt_t* pkt,
mio_oow_t len
); );
MIO_EXPORT void mio_dns_free_packet_info (
mio_t* mio,
mio_dns_pkt_info_t* pi
);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif

View File

@ -422,6 +422,7 @@ struct mio_svc_t
else (mio)->actsvc.tail = (svc)->svc_prev; \ else (mio)->actsvc.tail = (svc)->svc_prev; \
} while (0) } while (0)
#define mio_svc_getmio(svc) (((mio_svc_t*)(svc))->mio)
/* ========================================================================= /* =========================================================================
* MIO LOGGING * MIO LOGGING