diff --git a/mio/bin/t01.c b/mio/bin/t01.c index 7fbed9f..d8e3c68 100644 --- a/mio/bin/t01.c +++ b/mio/bin/t01.c @@ -656,6 +656,9 @@ static void on_dnc_resolve(mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum case MIO_DNS_RRT_CNAME: printf ("^^^ GOT REPLY.... CNAME [%s] %d\n", brr->dptr, (int)brr->dlen); goto done; + case MIO_DNS_RRT_MX: + printf ("^^^ GOT REPLY.... MX [%s] %d\n", brr->dptr, (int)brr->dlen); + goto done; case MIO_DNS_RRT_NS: printf ("^^^ GOT REPLY.... NS [%s] %d\n", brr->dptr, (int)brr->dlen); goto done; @@ -955,7 +958,7 @@ for (i = 0; i < 5; i++) mio_bcstrtoskad (mio, "[fe80::c7e2:bd6e:1209:ac1b%eno1]:1153", &servaddr); dnc = mio_svc_dnc_start (mio, &servaddr, MIO_NULL, &send_tmout, &reply_tmout, 2); /* option - send to all, send one by one */ -#if 0 +#if 1 { mio_dns_bqr_t qrs[] = { @@ -969,7 +972,9 @@ for (i = 0; i < 5; i++) { { 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_RRT_AAAA, MIO_DNS_RRC_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_ANSWER, "miflux.com", MIO_DNS_RRT_NS, MIO_DNS_RRC_IN, 86400, 0, "ns1.miflux.com" }, + { MIO_DNS_RR_PART_ANSWER, "miflux.com", MIO_DNS_RRT_NS, MIO_DNS_RRC_IN, 86400, 0, "ns2.miflux.com" }, //, + //{ MIO_DNS_RR_PART_AUTHORITY, "miflux.com", MIO_DNS_RRT_SOA, MIO_DNS_RRC_IN, 86400, 0, "ns2.miflux.com" }, //, //{ MIO_DNS_RR_PART_ANSERT, "www.miflux.com", MIO_DNS_RRT_CNAME, MIO_DNS_RRC_IN, 60, 15, "code.miflux.com" } }; diff --git a/mio/lib/dns.c b/mio/lib/dns.c index 027cfd1..c4246e9 100644 --- a/mio/lib/dns.c +++ b/mio/lib/dns.c @@ -31,10 +31,9 @@ #define DN_AT_END(ptr) (ptr[0] == '\0' || (ptr[0] == '.' && ptr[1] == '\0')) -static mio_oow_t to_dn (const mio_bch_t* str, mio_uint8_t* buf, mio_oow_t bufsz) +static mio_oow_t to_dn (const mio_bch_t* str, mio_uint8_t* buf) { - mio_uint8_t* bp = buf, * be = buf + bufsz; - + mio_uint8_t* bp = buf; /*MIO_ASSERT (MIO_SIZEOF(mio_uint8_t) == MIO_SIZEOF(mio_bch_t));*/ if (str && !DN_AT_END(str)) @@ -46,29 +45,62 @@ static mio_oow_t to_dn (const mio_bch_t* str, mio_uint8_t* buf, mio_oow_t bufsz) do { - if (bp < be) lp = bp++; - else lp = MIO_NULL; + lp = bp++; seg = ++cur; while (*cur != '\0' && *cur != '.') { - if (bp < be) *bp++ = *cur; + *bp++ = *cur; cur++; } len = cur - seg; if (len <= 0 || len > 63) return 0; - if (lp) *lp = (mio_uint8_t)len; + *lp = (mio_uint8_t)len; } while (!DN_AT_END(cur)); } - if (bp < be) *bp++ = 0; + *bp++ = 0; /* the length includes the terminating zero. */ return bp - buf; } +static mio_oow_t to_dn_capa (const mio_bch_t* str) +{ + mio_oow_t capa; + + /*MIO_ASSERT (MIO_SIZEOF(mio_uint8_t) == MIO_SIZEOF(mio_bch_t));*/ + + if (str && !DN_AT_END(str)) + { + mio_oow_t len; + const mio_bch_t* seg; + const mio_bch_t* cur = str - 1; + + do + { + capa++; + + seg = ++cur; + while (*cur != '\0' && *cur != '.') + { + capa++; + cur++; + } + len = cur - seg; + if (len <= 0 || len > 63) return 0; + } + while (!DN_AT_END(cur)); + } + + capa++; + + /* the length includes the terminating zero. */ + return capa; +} + static mio_oow_t dn_length (mio_uint8_t* ptr, mio_oow_t len) { mio_uint8_t* curptr; @@ -261,6 +293,7 @@ static int parse_answer_rr (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos goto verbatim; case MIO_DNS_RRT_CNAME: + case MIO_DNS_RRT_MX: case MIO_DNS_RRT_NS: case MIO_DNS_RRT_PTR: { @@ -432,33 +465,38 @@ void mio_dns_free_packet_info (mio_t* mio, mio_dns_pkt_info_t* pi) /* ----------------------------------------------------------------------- */ -static mio_oow_t encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, mio_dns_rrtr_t* rrtr) +static mio_oow_t encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, void* dptr) { + mio_oow_t xlen; + switch (rr->rrtype) { case MIO_DNS_RRT_A: + xlen = rr->dlen; break; case MIO_DNS_RRT_AAAA: + xlen = rr->dlen; break; /* case MIO_DNS_RRT_WKS: break; */ - case MIO_DNS_RRT_MX: - /* preference, exchange */ - break; - case MIO_DNS_RRT_CNAME: /*case MIO_DNS_RRT_MB: case MIO_DNS_RRT_MD: case MIO_DNS_RRT_MF: case MIO_DNS_RRT_MG: case MIO_DNS_RRT_MR:*/ + case MIO_DNS_RRT_MX: case MIO_DNS_RRT_NS: case MIO_DNS_RRT_PTR: /* just a normal domain name */ - /* TODO: take a null-terminated string and encode it using to_dn() */ + if (dptr) + xlen = to_dn(rr->dptr, dptr); + else + xlen = to_dn_capa(rr->dptr); + if (xlen <= 0) break; #if 0 @@ -471,21 +509,25 @@ static mio_oow_t encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, case MIO_DNS_RRT_MINFO: /* rmailbx, emailbx */ #endif + xlen = rr->dlen; break; case MIO_DNS_RRT_SOA: /* soa */ + xlen = rr->dlen; break; case MIO_DNS_RRT_TXT: case MIO_DNS_RRT_NULL: default: /* TODO: custom transformator? */ - rrtr->dlen = mio_hton16(rr->dlen); - if (rr->dlen > 0) MIO_MEMCPY (rrtr + 1, rr->dptr, rr->dlen); + if (rr->dlen > 0) MIO_MEMCPY (dptr, rr->dptr, rr->dlen); + xlen = rr->dlen; + break; } - return rr->dlen; + if (MIO_UNLIKELY(xlen > MIO_TYPE_MAX(mio_uint16_t))) return 0; + return xlen; } mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, 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_oow_t xtnsize) @@ -503,15 +545,20 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t 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. */ - pktlen += mio_count_bcstr(qr[i].qname) + 2 + MIO_SIZEOF(*qrtr); + pktlen += to_dn_capa(qr[i].qname) + MIO_SIZEOF(*qrtr); } for (i = 0; i < rr_count; i++) { - pktlen += mio_count_bcstr(rr[i].rrname) + 2 + MIO_SIZEOF(*rrtr) + rr[i].dlen; + mio_oow_t rrdata_len; + rrdata_len = encode_rrdata_in_dns_msg(mio, &rr[i], MIO_NULL); + if (MIO_UNLIKELY(rrdata_len <= 0)) + { + /* invalid rrdata */ + mio_seterrnum (mio, MIO_EINVAL); + return MIO_NULL; + } + pktlen += to_dn_capa(rr[i].rrname) + MIO_SIZEOF(*rrtr) + rrdata_len; } edns_dlen = 0; @@ -560,7 +607,7 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t for (i = 0; i < qr_count; i++) { /* dnlen includes the ending */ - dnlen = to_dn(qr[i].qname, dn, mio_count_bcstr(qr[i].qname) + 2); + dnlen = to_dn(qr[i].qname, dn); if (dnlen <= 0) { mio_dns_free_msg (mio, msg); @@ -581,9 +628,9 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t { if (rr[i].part == rr_sect) { - mio_oow_t rdata_len; + mio_oow_t rrdata_len; - dnlen = to_dn(rr[i].rrname, dn, mio_count_bcstr(rr[i].rrname) + 2); + dnlen = to_dn(rr[i].rrname, dn); if (dnlen <= 0) { mio_dns_free_msg (mio, msg); @@ -596,8 +643,10 @@ mio_dns_msg_t* mio_dns_make_msg (mio_t* mio, mio_dns_bhdr_t* bhdr, mio_dns_bqr_t rrtr->rrclass = mio_hton16(rr[i].rrclass); rrtr->ttl = mio_hton32(rr[i].ttl); - rdata_len = encode_rrdata_in_dns_msg(mio, &rr[i], rrtr); - dn = (mio_uint8_t*)(rrtr + 1) + rdata_len; + rrdata_len = encode_rrdata_in_dns_msg(mio, &rr[i], rrtr + 1); + MIO_ASSERT (mio, rrdata_len > 0); + rrtr->dlen = mio_hton16(rrdata_len); + dn = (mio_uint8_t*)(rrtr + 1) + rrdata_len; match_count++; }