-/* $OpenBSD: frontend.c,v 1.72 2022/03/03 18:54:07 florian Exp $ */
+/* $OpenBSD: frontend.c,v 1.73 2022/03/13 15:14:01 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
struct sldns_buffer *abuf;
struct regional *region;
struct query_info qinfo;
- struct msg_parse *qmsg;
struct edns_data edns;
struct event ev; /* for tcp */
struct event resp_ev; /* for tcp */
struct event tmo_ev; /* for tcp */
uint64_t imsg_id;
+ uint16_t id;
+ uint16_t flags;
int fd;
int tcp;
int dns64_synthesize;
break;
}
- if (answer_header->bogus && !(pq->qmsg->flags &
- BIT_CD)) {
+ if (answer_header->bogus && !(pq->flags & BIT_CD)) {
error_answer(pq, LDNS_RCODE_SERVFAIL);
send_answer(pq);
break;
pq->qbuf = sldns_buffer_new(len);
pq->abuf = sldns_buffer_new(len); /* make sure we can send errors */
pq->region = regional_create();
- pq->qmsg = regional_alloc(pq->region, sizeof(*pq->qmsg));
- if (!pq->qbuf || !pq->abuf || !pq->region || !pq->qmsg) {
+ if (!pq->qbuf || !pq->abuf || !pq->region) {
log_warnx("out of memory");
free_pending_query(pq);
return;
}
- memset(pq->qmsg, 0, sizeof(*pq->qmsg));
sldns_buffer_write(pq->qbuf, udpev->query, len);
sldns_buffer_flip(pq->qbuf);
handle_query(pq);
handle_query(struct pending_query *pq)
{
struct query_imsg query_imsg;
- struct query_info skip;
struct bl_node find;
int rcode;
char *str;
free(str);
}
- if (!query_info_parse(&pq->qinfo, pq->qbuf)) {
- log_warnx("query_info_parse failed");
+ if (sldns_buffer_remaining(pq->qbuf) < LDNS_HEADER_SIZE) {
+ log_warnx("bad query: too short, dropped");
goto drop;
}
- sldns_buffer_rewind(pq->qbuf);
+ pq->id = sldns_buffer_read_u16_at(pq->qbuf, 0);
+ pq->flags = sldns_buffer_read_u16_at(pq->qbuf, 2);
- if (parse_packet(pq->qbuf, pq->qmsg, pq->region) !=
- LDNS_RCODE_NOERROR) {
- log_warnx("parse_packet failed");
+ if (!query_info_parse(&pq->qinfo, pq->qbuf)) {
+ log_warnx("query_info_parse failed");
goto drop;
}
goto send_answer;
}
- sldns_buffer_rewind(pq->qbuf);
- if (!query_info_parse(&skip, pq->qbuf)) {
- error_answer(pq, LDNS_RCODE_SERVFAIL);
- goto send_answer;
- }
rcode = parse_edns_from_query_pkt(pq->qbuf, &pq->edns, NULL, NULL,
pq->region);
if (rcode != LDNS_RCODE_NOERROR) {
}
sldns_buffer_clear(pq->abuf);
- if (reply_info_encode(&pq->qinfo, rinfo, pq->qmsg->id, rinfo->flags,
+ if (reply_info_encode(&pq->qinfo, rinfo, htons(pq->id), rinfo->flags,
pq->abuf, 0, pq->region, pq->tcp ? UINT16_MAX : pq->edns.udp_size,
pq->edns.bits & EDNS_DO, MINIMIZE_ANSWER) == 0)
goto srvfail;
sldns_buffer_clear(pq->abuf);
- if (reply_info_encode(&pq->qinfo, synth_rinfo, pq->qmsg->id,
+ if (reply_info_encode(&pq->qinfo, synth_rinfo, htons(pq->id),
synth_rinfo->flags, pq->abuf, 0, pq->region,
pq->tcp ? UINT16_MAX : pq->edns.udp_size,
pq->edns.bits & EDNS_DO, MINIMIZE_ANSWER) == 0)
resend_dns64_query(struct pending_query *opq) {
struct pending_query *pq;
struct query_imsg query_imsg;
- struct query_info skip;
int rcode;
char dname[LDNS_MAX_DOMAINLEN + 1];
pq->qbuf = sldns_buffer_new(sldns_buffer_capacity(opq->qbuf));
pq->abuf = sldns_buffer_new(sldns_buffer_capacity(opq->abuf));
pq->region = regional_create();
- pq->qmsg = regional_alloc(pq->region, sizeof(*pq->qmsg));
- if (!pq->qbuf || !pq->abuf || !pq->region || !pq->qmsg) {
+ if (!pq->qbuf || !pq->abuf || !pq->region) {
log_warnx("out of memory");
free_pending_query(pq);
free_pending_query(opq);
sldns_buffer_write(pq->qbuf, sldns_buffer_current(opq->qbuf),
sldns_buffer_remaining(opq->qbuf));
sldns_buffer_flip(pq->qbuf);
- memset(pq->qmsg, 0, sizeof(*pq->qmsg));
if (pq->tcp) {
struct timeval timeout = {TCP_TIMEOUT, 0};
evtimer_add(&pq->tmo_ev, &timeout);
}
- if (!query_info_parse(&pq->qinfo, pq->qbuf)) {
- log_warnx("query_info_parse failed");
+ if (sldns_buffer_remaining(pq->qbuf) < LDNS_HEADER_SIZE) {
+ log_warnx("bad query: too short, dropped");
goto drop;
}
- sldns_buffer_rewind(pq->qbuf);
+ pq->id = sldns_buffer_read_u16_at(pq->qbuf, 0);
+ pq->flags = sldns_buffer_read_u16_at(pq->qbuf, 2);
- if (parse_packet(pq->qbuf, pq->qmsg, pq->region) !=
- LDNS_RCODE_NOERROR) {
- log_warnx("parse_packet failed");
+ if (!query_info_parse(&pq->qinfo, pq->qbuf)) {
+ log_warnx("query_info_parse failed");
goto drop;
}
- sldns_buffer_rewind(pq->qbuf);
- if (!query_info_parse(&skip, pq->qbuf)) {
- error_answer(pq, LDNS_RCODE_SERVFAIL);
- goto send_answer;
- }
rcode = parse_edns_from_query_pkt(pq->qbuf, &pq->edns, NULL, NULL,
pq->region);
if (rcode != LDNS_RCODE_NOERROR) {
error_answer(struct pending_query *pq, int rcode)
{
sldns_buffer_clear(pq->abuf);
- error_encode(pq->abuf, rcode, &pq->qinfo, pq->qmsg->id,
- pq->qmsg->flags, pq->edns.edns_present ? &pq->edns : NULL);
+ error_encode(pq->abuf, rcode, &pq->qinfo, htons(pq->id), pq->flags,
+ pq->edns.edns_present ? &pq->edns : NULL);
}
int
pq->tcp = 1;
pq->qbuf = sldns_buffer_new(DEFAULT_TCP_SIZE);
pq->region = regional_create();
- pq->qmsg = regional_alloc(pq->region, sizeof(*pq->qmsg));
- if (!pq->qbuf || !pq->region || !pq->qmsg) {
+ if (!pq->qbuf || !pq->region) {
free_pending_query(pq);
return;
}
- memset(pq->qmsg, 0, sizeof(*pq->qmsg));
-
event_set(&pq->ev, s, EV_READ | EV_PERSIST, tcp_request, pq);
event_add(&pq->ev, NULL);
event_set(&pq->resp_ev, s, EV_WRITE | EV_PERSIST, tcp_response, pq);