From e8effa75e473086b1f21254655ec87675573940c Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Tue, 11 Jul 2017 11:42:15 +0930 Subject: [PATCH] Refactor dns lookups to reuse the code --- overlay_link.c | 42 +++++++++--------------------------------- rhizome_direct_http.c | 25 ++++++++++--------------- socket.c | 27 +++++++++++++++++++++++++++ socket.h | 1 + 4 files changed, 47 insertions(+), 48 deletions(-) diff --git a/overlay_link.c b/overlay_link.c index f32ab06c..1567a73e 100644 --- a/overlay_link.c +++ b/overlay_link.c @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "keyring.h" #include "strbuf_helpers.h" #include "route_link.h" +#include "socket.h" int set_reachable(struct subscriber *subscriber, struct network_destination *destination, struct subscriber *next_hop, @@ -80,29 +81,6 @@ int set_reachable(struct subscriber *subscriber, return 1; } -static int resolve_name(const char *name, struct in_addr *addr){ - // TODO this can block, move to worker thread. - IN(); - int ret=0; - struct addrinfo hint={ - .ai_family=AF_INET, - }; - struct addrinfo *addresses=NULL; - if (getaddrinfo(name, NULL, &hint, &addresses)) - RETURN(WHYF("Failed to resolve %s",name)); - - if (addresses->ai_addr->sa_family==AF_INET){ - *addr = ((struct sockaddr_in *)addresses->ai_addr)->sin_addr; - DEBUGF(overlayrouting, "Resolved %s into %s", name, inet_ntoa(*addr)); - - }else - ret=WHY("Ignoring non IPv4 address"); - - freeaddrinfo(addresses); - RETURN(ret); - OUT(); -} - // load a unicast address from configuration struct network_destination *load_subscriber_address(struct subscriber *subscriber) { @@ -123,19 +101,17 @@ struct network_destination *load_subscriber_address(struct subscriber *subscribe } struct socket_address addr; bzero(&addr, sizeof(addr)); - addr.addrlen = sizeof(addr.inet); - addr.inet.sin_family = AF_INET; - addr.inet.sin_addr = hostc->address; - addr.inet.sin_port = htons(hostc->port); - if (addr.inet.sin_addr.s_addr==INADDR_NONE){ - if (interface || overlay_interface_get_default()){ - if (resolve_name(hostc->host, &addr.inet.sin_addr)) - return NULL; - }else{ - // interface isnt up yet + if (hostc->address.s_addr == INADDR_NONE){ + if (socket_resolve_name(AF_INET, hostc->host, NULL, &addr)==-1){ + // Perhaps the right interface isnt up yet return NULL; } + }else{ + addr.addrlen = sizeof(addr.inet); + addr.inet.sin_family = AF_INET; + addr.inet.sin_addr = hostc->address; } + addr.inet.sin_port = htons(hostc->port); DEBUGF(overlayrouting, "Loaded address %s for %s", alloca_socket_address(&addr), alloca_tohex_sid_t(subscriber->sid)); return create_unicast_destination(&addr, interface); } diff --git a/rhizome_direct_http.c b/rhizome_direct_http.c index eb6d4ecc..eee27f36 100644 --- a/rhizome_direct_http.c +++ b/rhizome_direct_http.c @@ -472,26 +472,21 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r) DEBUGF(rhizome_tx, "Dispatch size_high=%"PRId64,r->cursor->size_high); rhizome_direct_transport_state_http *state = r->transport_specific_state; - int sock=socket(AF_INET, SOCK_STREAM, 0); + struct socket_address addr; + bzero(&addr,sizeof(addr)); + + if (socket_resolve_name(AF_INET, state->host, NULL, &addr)==-1){ + DEBUGF(rhizome_tx, "could not resolve hostname"); + goto end; + } + addr.inet.sin_port=htons(state->port); + + int sock=socket(addr.addr.sa_family, SOCK_STREAM, 0); if (sock==-1) { WHY_perror("socket"); goto end; } - struct hostent *hostent; - hostent = gethostbyname(state->host); - if (!hostent) { - DEBUGF(rhizome_tx, "could not resolve hostname"); - goto end; - } - - struct socket_address addr; - bzero(&addr,sizeof(addr)); - addr.addrlen = sizeof(addr.inet); - addr.inet.sin_family = AF_INET; - addr.inet.sin_port = htons(state->port); - addr.inet.sin_addr = *((struct in_addr *)hostent->h_addr); - if (connect(sock, &addr.addr, addr.addrlen) == -1) { WHYF_perror("connect(%s)", alloca_socket_address(&addr)); close(sock); diff --git a/socket.c b/socket.c index 6758bb18..d0c65ed3 100644 --- a/socket.c +++ b/socket.c @@ -21,6 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#include +#include #include "instance.h" #include "str.h" @@ -354,3 +356,28 @@ ssize_t _recv_message(struct __sourceloc __whence, int fd, struct socket_address data.iov[0].iov_len = buflen; return _recv_message_frag(__whence, fd, address, ttl, &data); } + +int socket_resolve_name(int family, const char *name, const char *service, struct socket_address *address){ + int ret=-1; + struct addrinfo hint={ + .ai_flags = AI_ADDRCONFIG, + .ai_family = family, + }; + struct addrinfo *addresses=NULL; + if (getaddrinfo(name, service, &hint, &addresses)) + return WHYF_perror("Failed to resolve %s",name); + + struct addrinfo *p = addresses; + while(p){ + if (p->ai_addrlen < sizeof(address->raw) && (p->ai_addr->sa_family == AF_INET || p->ai_addr->sa_family == AF_INET6)){ + address->addrlen = p->ai_addrlen; + memcpy(&address->addr, p->ai_addr, p->ai_addrlen); + ret = 0; + break; + } + p = p->ai_next; + } + + freeaddrinfo(addresses); + return ret; +} diff --git a/socket.h b/socket.h index 5eb6746c..133040c1 100644 --- a/socket.h +++ b/socket.h @@ -61,6 +61,7 @@ int _socket_listen(struct __sourceloc, int sock, int backlog); int _socket_set_reuseaddr(struct __sourceloc, int sock, int reuseP); int _socket_set_rcvbufsize(struct __sourceloc, int sock, unsigned buffer_size); int socket_unlink_close(int sock); +int socket_resolve_name(int family, const char *name, const char *service, struct socket_address *address); #define make_local_sockaddr(sockname, fmt,...) _make_local_sockaddr(__WHENCE__, (sockname), (fmt), ##__VA_ARGS__) #define esocket(domain, type, protocol) _esocket(__WHENCE__, (domain), (type), (protocol))