]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: scope - write() unicast DNS packets
authorTom Gundersen <teg@jklm.no>
Sat, 25 Jul 2015 03:11:34 +0000 (05:11 +0200)
committerTom Gundersen <teg@jklm.no>
Mon, 27 Jul 2015 18:32:24 +0000 (20:32 +0200)
As we have connect()ed to the desired DNS server, we no longer need to pass
control messages manually when sending packets. Simplify the logic accordingly.

src/resolve/resolved-dns-scope.c
src/resolve/resolved-manager.c
src/resolve/resolved-manager.h

index e8c6108924a2e1070e0b4ae8b4aad626b7f2751a..927a1ddc26d9fc8d16b48de908679ebf22719bdf 100644 (file)
@@ -153,6 +153,10 @@ int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p) {
                 if (p->size + UDP_PACKET_HEADER_SIZE > mtu)
                         return -EMSGSIZE;
 
+                r = manager_write(s->manager, fd, p);
+                if (r < 0)
+                        return r;
+
         } else if (s->protocol == DNS_PROTOCOL_LLMNR) {
 
                 if (DNS_PACKET_QDCOUNT(p) > 1)
@@ -174,13 +178,13 @@ int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p) {
                         return -EAFNOSUPPORT;
                 if (fd < 0)
                         return fd;
+
+                r = manager_send(s->manager, fd, ifindex, family, &addr, port, p);
+                if (r < 0)
+                        return r;
         } else
                 return -EAFNOSUPPORT;
 
-        r = manager_send(s->manager, fd, ifindex, family, &addr, port, p);
-        if (r < 0)
-                return r;
-
         return 1;
 }
 
index 9fda64ba39d518c4c282d7ed7596073ec721e09e..5be01d3cb8a7ae079d56e3ad59476e0099d579e0 100644 (file)
@@ -949,6 +949,42 @@ static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
         }
 }
 
+static int write_loop(int fd, void *message, size_t length) {
+        int r;
+
+        assert(fd >= 0);
+        assert(message);
+
+        for (;;) {
+                if (write(fd, message, length) >= 0)
+                        return 0;
+
+                if (errno == EINTR)
+                        continue;
+
+                if (errno != EAGAIN)
+                        return -errno;
+
+                r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return -ETIMEDOUT;
+        }
+}
+
+int manager_write(Manager *m, int fd, DnsPacket *p) {
+        int r;
+
+        log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
+
+        r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
         union sockaddr_union sa = {
                 .in.sin_family = AF_INET,
index 005f844df246df6232a97ef4776ad6af909ec8e6..53b5acb33cf1082d718e5e307cfa69fddf0d1ef8 100644 (file)
@@ -119,6 +119,7 @@ void manager_next_dns_server(Manager *m);
 
 uint32_t manager_find_mtu(Manager *m);
 
+int manager_write(Manager *m, int fd, DnsPacket *p);
 int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p);
 int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret);