fixed a parsing bug of a compressed domain name placed at the end of the packet
This commit is contained in:
		@ -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 */
 | 
			
		||||
@ -508,6 +534,41 @@ static int encode_rrdata_in_dns_msg (mio_t* mio, const mio_dns_brr_t* rr, mio_ui
 | 
			
		||||
	#endif
 | 
			
		||||
			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:
 | 
			
		||||
		{
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user