void truncation_check(evldns_server_request *srq) { ldns_pkt *req = srq->request; ldns_pkt *resp = srq->response; unsigned int bufsize = 512; /* if it's TCP, business as usual */ if (srq->is_tcp) { return; } /* otherwise, convert to wire format, if necessary */ if (!srq->wire_response) { (void) ldns_pkt2wire(&srq->wire_response, resp, &srq->wire_resplen); } /* if it's under the RFC 1035 limit, we're OK */ if (srq->wire_resplen <= bufsize) { return; } /* if the client used EDNS, use that new bufsize */ if (ldns_pkt_edns(req)) { unsigned int ednssize = ldns_pkt_edns_udp_size(req); if (ednssize > bufsize) { bufsize = ednssize; } /* it fits - we're OK */ if (srq->wire_resplen <= bufsize) { return; } } /* * if we got here, it didn't fit - throw away the * existing wire buffer and the non-question sections */ free(srq->wire_response); LDNS_rr_list_empty_rr_list(ldns_pkt_additional(resp)); LDNS_rr_list_empty_rr_list(ldns_pkt_authority(resp)); LDNS_rr_list_empty_rr_list(ldns_pkt_answer(resp)); /* set the TC bit and reset section counts */ ldns_pkt_set_tc(resp, true); ldns_pkt_set_ancount(resp, 0); ldns_pkt_set_nscount(resp, 0); ldns_pkt_set_arcount(resp, 0); /* and convert to wire format again */ (void) ldns_pkt2wire(&srq->wire_response, resp, &srq->wire_resplen); }
/** parse REPLY line */ static void replyline(char* line, ldns_pkt *reply) { char* parse = line; while(*parse) { if(isendline(*parse)) return; /* opcodes */ if(str_keyword(&parse, "QUERY")) { ldns_pkt_set_opcode(reply, LDNS_PACKET_QUERY); } else if(str_keyword(&parse, "IQUERY")) { ldns_pkt_set_opcode(reply, LDNS_PACKET_IQUERY); } else if(str_keyword(&parse, "STATUS")) { ldns_pkt_set_opcode(reply, LDNS_PACKET_STATUS); } else if(str_keyword(&parse, "NOTIFY")) { ldns_pkt_set_opcode(reply, LDNS_PACKET_NOTIFY); } else if(str_keyword(&parse, "UPDATE")) { ldns_pkt_set_opcode(reply, LDNS_PACKET_UPDATE); /* rcodes */ } else if(str_keyword(&parse, "NOERROR")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_NOERROR); } else if(str_keyword(&parse, "FORMERR")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_FORMERR); } else if(str_keyword(&parse, "SERVFAIL")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_SERVFAIL); } else if(str_keyword(&parse, "NXDOMAIN")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_NXDOMAIN); } else if(str_keyword(&parse, "NOTIMPL")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTIMPL); } else if(str_keyword(&parse, "REFUSED")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_REFUSED); } else if(str_keyword(&parse, "YXDOMAIN")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_YXDOMAIN); } else if(str_keyword(&parse, "YXRRSET")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_YXRRSET); } else if(str_keyword(&parse, "NXRRSET")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_NXRRSET); } else if(str_keyword(&parse, "NOTAUTH")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTAUTH); } else if(str_keyword(&parse, "NOTZONE")) { ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTZONE); /* flags */ } else if(str_keyword(&parse, "QR")) { ldns_pkt_set_qr(reply, true); } else if(str_keyword(&parse, "AA")) { ldns_pkt_set_aa(reply, true); } else if(str_keyword(&parse, "TC")) { ldns_pkt_set_tc(reply, true); } else if(str_keyword(&parse, "RD")) { ldns_pkt_set_rd(reply, true); } else if(str_keyword(&parse, "CD")) { ldns_pkt_set_cd(reply, true); } else if(str_keyword(&parse, "RA")) { ldns_pkt_set_ra(reply, true); } else if(str_keyword(&parse, "AD")) { ldns_pkt_set_ad(reply, true); } else if(str_keyword(&parse, "DO")) { ldns_pkt_set_edns_udp_size(reply, 4096); ldns_pkt_set_edns_do(reply, true); } else { error("could not parse REPLY: '%s'", parse); } } }