resolved: add new accessor dns_stream_take_read_packet() for taking read packet from stream

This ensures the packet is complete when it is taken out, and resets
n_read so that we can start reading the next one.
This commit is contained in:
Lennart Poettering 2018-12-04 20:18:11 +01:00
parent 56e267dee2
commit aa337a5e72
5 changed files with 44 additions and 21 deletions

View File

@ -533,3 +533,19 @@ int dns_stream_write_packet(DnsStream *s, DnsPacket *p) {
return dns_stream_update_io(s);
}
DnsPacket *dns_stream_take_read_packet(DnsStream *s) {
assert(s);
if (!s->read_packet)
return NULL;
if (s->n_read < sizeof(s->read_size))
return NULL;
if (s->n_read < sizeof(s->read_size) + be16toh(s->read_size))
return NULL;
s->n_read = 0;
return TAKE_PTR(s->read_packet);
}

View File

@ -87,3 +87,5 @@ static inline bool DNS_STREAM_QUEUED(DnsStream *s) {
return !!s->write_packet;
}
DnsPacket *dns_stream_take_read_packet(DnsStream *s);

View File

@ -437,13 +437,17 @@ static int manager_dns_stub_udp_fd(Manager *m) {
}
static int on_dns_stub_stream_packet(DnsStream *s) {
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
assert(s);
assert(s->read_packet);
if (dns_packet_validate_query(s->read_packet) > 0) {
log_debug("Got DNS stub TCP query packet for id %u", DNS_PACKET_ID(s->read_packet));
p = dns_stream_take_read_packet(s);
assert(p);
dns_stub_process_query(s->manager, s, s->read_packet);
if (dns_packet_validate_query(p) > 0) {
log_debug("Got DNS stub TCP query packet for id %u", DNS_PACKET_ID(p));
dns_stub_process_query(s->manager, s, p);
} else
log_debug("Invalid DNS stub TCP packet, ignoring.");

View File

@ -532,27 +532,25 @@ static int on_stream_complete(DnsStream *s, int error) {
static int dns_stream_on_packet(DnsStream *s) {
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
int r = 0;
DnsTransaction *t;
assert(s);
/* Take ownership of packet to be able to receive new packets */
p = TAKE_PTR(s->read_packet);
s->n_read = 0;
p = dns_stream_take_read_packet(s);
assert(p);
t = hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
if (t)
return dns_transaction_on_stream_packet(t, p);
/* Ignore incorrect transaction id as transaction can have been canceled */
if (t)
r = dns_transaction_on_stream_packet(t, p);
else {
if (dns_packet_validate_reply(p) <= 0) {
log_debug("Invalid TCP reply packet.");
on_stream_complete(s, 0);
}
return 0;
if (dns_packet_validate_reply(p) <= 0) {
log_debug("Invalid TCP reply packet.");
on_stream_complete(s, 0);
}
return r;
return 0;
}
static int dns_transaction_emit_tcp(DnsTransaction *t) {

View File

@ -260,18 +260,21 @@ int manager_llmnr_ipv6_udp_fd(Manager *m) {
}
static int on_llmnr_stream_packet(DnsStream *s) {
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
DnsScope *scope;
assert(s);
assert(s->read_packet);
scope = manager_find_scope(s->manager, s->read_packet);
p = dns_stream_take_read_packet(s);
assert(p);
scope = manager_find_scope(s->manager, p);
if (!scope)
log_debug("Got LLMNR TCP packet on unknown scope. Ignoring.");
else if (dns_packet_validate_query(s->read_packet) > 0) {
log_debug("Got LLMNR TCP query packet for id %u", DNS_PACKET_ID(s->read_packet));
else if (dns_packet_validate_query(p) > 0) {
log_debug("Got LLMNR TCP query packet for id %u", DNS_PACKET_ID(p));
dns_scope_process_query(scope, s, s->read_packet);
dns_scope_process_query(scope, s, p);
} else
log_debug("Invalid LLMNR TCP packet, ignoring.");