summaryrefslogtreecommitdiff
path: root/src/resolve
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-07-25 05:11:34 +0200
committerTom Gundersen <teg@jklm.no>2015-07-27 20:32:24 +0200
commit72290734be81e83e6ef9520c07692f68095eb5b2 (patch)
tree5fc7f00f41012d8396f1ee5064e75aa690d1e482 /src/resolve
parent471d40d92fc8e7b452dff99a156f9e0b520ded20 (diff)
resolved: scope - write() unicast DNS packets
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.
Diffstat (limited to 'src/resolve')
-rw-r--r--src/resolve/resolved-dns-scope.c12
-rw-r--r--src/resolve/resolved-manager.c36
-rw-r--r--src/resolve/resolved-manager.h1
3 files changed, 45 insertions, 4 deletions
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index e8c6108924..927a1ddc26 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -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;
}
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 9fda64ba39..5be01d3cb8 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -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,
diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h
index 005f844df2..53b5acb33c 100644
--- a/src/resolve/resolved-manager.h
+++ b/src/resolve/resolved-manager.h
@@ -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);