resolved-dns-packet.c revision 2e276efc7b0398a3086629a52970bdd4ab7252f9
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier This file is part of systemd.
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier Copyright 2014 Lennart Poettering
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier systemd is free software; you can redistribute it and/or modify it
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier under the terms of the GNU Lesser General Public License as published by
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier the Free Software Foundation; either version 2.1 of the License, or
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier (at your option) any later version.
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier systemd is distributed in the hope that it will be useful, but
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier WITHOUT ANY WARRANTY; without even the implied warranty of
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier Lesser General Public License for more details.
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier You should have received a copy of the GNU Lesser General Public License
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalierint dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier /* round up to next page size */
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
e6b5c5d03cb28d2149dc1c124c2a315911b91f4fRonny Chevalier /* make sure we never allocate more than useful */
return -ENOMEM;
p->allocated = a;
*ret = p;
DnsPacket *p;
DnsPacketHeader *h;
h = DNS_PACKET_HEADER(p);
*ret = p;
return NULL;
p->n_ref++;
assert(p);
free(s);
free(p);
return NULL;
dns_packet_free(p);
p->n_ref--;
return NULL;
assert(p);
return -EBADMSG;
return -EBADMSG;
assert(p);
r = dns_packet_validate(p);
if (DNS_PACKET_OPCODE(p) != 0)
return -EBADMSG;
return -EBADMSG;
assert(p);
r = dns_packet_validate(p);
if (DNS_PACKET_QR(p) != 0)
if (DNS_PACKET_OPCODE(p) != 0)
return -EBADMSG;
if (DNS_PACKET_TC(p))
return -EBADMSG;
return -EBADMSG;
if (DNS_PACKET_ANCOUNT(p) > 0)
return -EBADMSG;
if (DNS_PACKET_NSCOUNT(p) > 0)
return -EBADMSG;
assert(p);
size_t a;
if (a > DNS_PACKET_SIZE_MAX)
a = DNS_PACKET_SIZE_MAX;
return -EMSGSIZE;
if (p->_data) {
return -ENOMEM;
p->_data = d;
if (!p->_data)
return -ENOMEM;
p->allocated = a;
if (start)
if (ret)
Iterator i;
assert(p);
free(s);
assert(p);
memcpy(q, d, l);
assert(p);
((uint8_t*) d)[0] = v;
assert(p);
assert(p);
size_t l;
assert(p);
assert(s);
l = strlen(s);
return -E2BIG;
assert(p);
assert(d);
if (l > DNS_LABEL_MAX)
return -E2BIG;
assert(p);
while (*name) {
size_t n;
goto fail;
goto done;
r = -ENOMEM;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
s = NULL;
done:
if (start)
fail:
assert(p);
assert(k);
goto fail;
goto fail;
goto fail;
if (start)
fail:
assert(p);
goto fail;
goto fail;
goto fail;
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_CNAME:
case DNS_TYPE_HINFO:
goto fail;
case DNS_TYPE_TXT: {
goto fail;
case DNS_TYPE_A:
case DNS_TYPE_AAAA:
case DNS_TYPE_SOA:
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
case DNS_TYPE_MX:
goto fail;
case DNS_TYPE_SRV:
case DNS_TYPE_DNAME:
case DNS_TYPE_SSHFP:
goto fail;
r = ENOSPC;
goto fail;
goto fail;
if (start)
fail:
assert(p);
return -EMSGSIZE;
if (ret)
if (start)
assert(p);
assert(p);
assert(d);
assert(p);
assert(p);
assert(p);
uint8_t c;
assert(p);
goto fail;
goto fail;
if (memchr(d, 0, c)) {
r = -EBADMSG;
goto fail;
t = strndup(d, c);
r = -ENOMEM;
goto fail;
if (!utf8_is_valid(t)) {
free(t);
r = -EBADMSG;
goto fail;
*ret = t;
if (start)
fail:
bool first = true;
assert(p);
uint8_t c, d;
goto fail;
const char *label;
goto fail;
goto fail;
r = -ENOMEM;
goto fail;
if (!first)
first = false;
goto fail;
r = -EBADMSG;
goto fail;
if (after_rindex == 0)
goto fail;
r = -ENOMEM;
goto fail;
ret[n] = 0;
if (after_rindex != 0)
if (start)
fail:
assert(p);
goto fail;
goto fail;
goto fail;
if (!key) {
r = -ENOMEM;
goto fail;
if (start)
fail:
assert(p);
goto fail;
r = -EBADMSG;
goto fail;
if (!rr) {
r = -ENOMEM;
goto fail;
goto fail;
goto fail;
r = -EBADMSG;
goto fail;
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_CNAME:
case DNS_TYPE_HINFO:
goto fail;
case DNS_TYPE_TXT: {
goto fail;
goto fail;
case DNS_TYPE_A:
case DNS_TYPE_AAAA:
case DNS_TYPE_SOA:
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
case DNS_TYPE_MX:
goto fail;
case DNS_TYPE_SRV:
case DNS_TYPE_DNAME:
case DNS_TYPE_SSHFP:
goto fail;
r = -ENOMEM;
goto fail;
goto fail;
r = -EBADMSG;
goto fail;
if (start)
fail:
n = DNS_PACKET_QDCOUNT(p);
if (!question) {
r = -ENOMEM;
goto finish;
goto finish;
goto finish;
n = DNS_PACKET_RRCOUNT(p);
if (!answer) {
r = -ENOMEM;
goto finish;
goto finish;
goto finish;