fixed a parsing bug of a compressed domain name placed at the end of the packet

This commit is contained in:
hyung-hwan 2020-04-28 11:27:24 +00:00
parent a0545235dd
commit c52ce87aa4
2 changed files with 77 additions and 15 deletions

View File

@ -168,11 +168,12 @@ static int parse_domain_name (mio_t* mio, mio_dns_pkt_info_t* pi)
if (MIO_UNLIKELY(pi->_ptr >= pi->_end)) goto oops;
offset = ((seglen & 0x3F) << 8) | *pi->_ptr++;
if (MIO_UNLIKELY(pi->_ptr >= pi->_end)) goto oops;
/*if (MIO_UNLIKELY(pi->_ptr >= pi->_end)) goto oops; <- this condition can be true if the function is called for the domain name at the back of the last RR */
seglen = pi->_start[offset];
if (seglen >= 64) goto oops; /* the pointed position must not contain another pointer */
if (!xptr) xptr = pi->_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 pointer again. so xptr, once set, must not be set again */
pi->_ptr = &pi->_start[offset + 1];
if (MIO_UNLIKELY(pi->_ptr >= pi->_end)) goto oops;
@ -293,7 +294,6 @@ 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:
{
@ -305,6 +305,37 @@ static int parse_answer_rr (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos
break;
}
case MIO_DNS_RRT_MX:
{
#if !defined(MIO_BUILD_RELEASE)
mio_uint8_t* xptr = pi->_ptr;
#endif
mio_dns_brrd_mx_t* mx;
pi->_rrdlen += MIO_SIZEOF(*mx);
if (MIO_UNLIKELY(pi->_end - pi->_ptr < 2)) goto oops;
if (pi->_rrdptr)
{
mx = (mio_dns_brrd_soa_t*)pi->_rrdptr;
pi->_rrdptr += MIO_SIZEOF(*mx);
MIO_MEMCPY (&mx->preference, pi->_ptr, 2); pi->_ptr += 2;
mx->preference = mio_ntoh16(mx->preference);
mx->exchange = (mio_bch_t*)pi->_rrdptr;
if (parse_domain_name(mio, pi) <= -1) goto oops;
}
else
{
pi->_ptr += 2;
if (parse_domain_name(mio, pi) <= -1) goto oops;
}
MIO_ASSERT (mio, pi->_ptr == xptr + dlen);
break;
}
case MIO_DNS_RRT_SOA:
{
#if !defined(MIO_BUILD_RELEASE)
@ -365,6 +396,7 @@ static int parse_answer_rr (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos
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;
default: goto oops;
}
brr[pos].part = rr_part;
@ -480,12 +512,6 @@ static int encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, mio_ui
goto verbatim;
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 */
@ -509,6 +535,41 @@ static int encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, mio_ui
xlen = rr->dlen;
break;
/*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:
{
mio_dns_brrd_mx_t* mx;
mio_oow_t tmp;
if (MIO_UNLIKELY(rr->dlen != MIO_SIZEOF(mio_dns_brrd_mx_t))) goto inval;
mx = (mio_dns_brrd_mx_t*)rr->dptr;
xlen = 0;
if (dptr)
{
mio_uint16_t ti;
ti = mio_hton16(mx->preference);
MIO_MEMCPY((mio_uint8_t*)dptr + xlen, &ti, MIO_SIZEOF(ti)); xlen += MIO_SIZEOF(ti);
tmp = to_dn(mx->exchange, (mio_uint8_t*)dptr + xlen);
if (MIO_UNLIKELY(tmp <= 0)) goto inval;
xlen += tmp;
}
else
{
xlen += 2;
tmp = to_dn_capa(mx->exchange);
if (MIO_UNLIKELY(tmp <= 0)) goto inval;
xlen += tmp;
}
break;
}
case MIO_DNS_RRT_SOA:
{
/* soa */
@ -531,15 +592,15 @@ static int encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, mio_ui
if (MIO_UNLIKELY(tmp <= 0)) goto inval;
xlen += tmp;
ti = mio_ntoh32(soa->serial);
ti = mio_hton32(soa->serial);
MIO_MEMCPY((mio_uint8_t*)dptr + xlen, &ti, MIO_SIZEOF(ti)); xlen += MIO_SIZEOF(ti);
ti = mio_ntoh32(soa->refresh);
ti = mio_hton32(soa->refresh);
MIO_MEMCPY((mio_uint8_t*)dptr + xlen, &ti, MIO_SIZEOF(ti)); xlen += MIO_SIZEOF(ti);
ti = mio_ntoh32(soa->retry);
ti = mio_hton32(soa->retry);
MIO_MEMCPY((mio_uint8_t*)dptr + xlen, &ti, MIO_SIZEOF(ti)); xlen += MIO_SIZEOF(ti);
ti = mio_ntoh32(soa->expire);
ti = mio_hton32(soa->expire);
MIO_MEMCPY((mio_uint8_t*)dptr + xlen, &ti, MIO_SIZEOF(ti)); xlen += MIO_SIZEOF(ti);
ti = mio_ntoh32(soa->minimum);
ti = mio_hton32(soa->minimum);
MIO_MEMCPY((mio_uint8_t*)dptr + xlen, &ti, MIO_SIZEOF(ti)); xlen += MIO_SIZEOF(ti);
}
else

View File

@ -317,6 +317,7 @@ struct mio_dns_brrd_cname_t
};
typedef struct mio_dns_brrd_cname_t mio_dns_brc_cname_t;
#endif
/* 3.3.9 MX RDATA format */
struct mio_dns_brrd_mx_t
@ -325,8 +326,8 @@ struct mio_dns_brrd_mx_t
mio_bch_t* exchange;
};
typedef struct mio_dns_brrd_mx_t mio_dns_brrd_mx_t;
#endif
/* 3.3.13. SOA RDATA format */
struct mio_dns_brrd_soa_t
{
mio_bch_t* mname;