+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;
+}
+