summaryrefslogtreecommitdiff
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
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.
-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);