X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fresolve%2Fresolved-dns-scope.c;h=a39e705a3ba60c39df5d30bf13d3beab231fc6f5;hb=e1c959948c0e31d6997bcdfbabfbd077784b2bae;hp=4e0a74276830f8ca76869158ea429c73b1cb4641;hpb=74b2466e14a1961bf3ac0e8a60cfaceec705bd59;p=elogind.git diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 4e0a74276..a39e705a3 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -19,7 +19,10 @@ along with systemd; If not, see . ***/ +#include + #include "strv.h" +#include "socket-util.h" #include "resolved-dns-domain.h" #include "resolved-dns-scope.h" @@ -92,10 +95,25 @@ int dns_scope_send(DnsScope *s, DnsPacket *p) { srv = dns_scope_get_server(s); if (!srv) - return 0; + return -ESRCH; + + if (s->link) { + if (p->size > s->link->mtu) + return -EMSGSIZE; - if (s->link) ifindex = s->link->ifindex; + } else { + uint32_t mtu; + + mtu = manager_find_mtu(s->manager); + if (mtu > 0) { + if (p->size > mtu) + return -EMSGSIZE; + } + } + + if (p->size > DNS_PACKET_UNICAST_SIZE_MAX) + return -EMSGSIZE; if (srv->family == AF_INET) r = manager_dns_ipv4_send(s->manager, srv, ifindex, p); @@ -110,6 +128,52 @@ int dns_scope_send(DnsScope *s, DnsPacket *p) { return 1; } +int dns_scope_tcp_socket(DnsScope *s) { + _cleanup_close_ int fd = -1; + union sockaddr_union sa = {}; + socklen_t salen; + int one, ifindex, ret; + DnsServer *srv; + int r; + + assert(s); + + srv = dns_scope_get_server(s); + if (!srv) + return -ESRCH; + + if (s->link) + ifindex = s->link->ifindex; + + sa.sa.sa_family = srv->family; + if (srv->family == AF_INET) { + sa.in.sin_port = htobe16(53); + sa.in.sin_addr = srv->address.in; + salen = sizeof(sa.in); + } else if (srv->family == AF_INET6) { + sa.in6.sin6_port = htobe16(53); + sa.in6.sin6_addr = srv->address.in6; + sa.in6.sin6_scope_id = ifindex; + salen = sizeof(sa.in6); + } else + return -EAFNOSUPPORT; + + fd = socket(srv->family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (fd < 0) + return -errno; + + one = 1; + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); + + r = connect(fd, &sa.sa, salen); + if (r < 0 && errno != EINPROGRESS) + return -errno; + + ret = fd; + fd = -1; + return ret; +} + DnsScopeMatch dns_scope_test(DnsScope *s, const char *domain) { char **i;