summaryrefslogtreecommitdiff
path: root/lib/addns
diff options
context:
space:
mode:
authorRichard Sharpe <rsharpe@nutanix.com>2016-04-22 18:48:58 -0700
committerVolker Lendecke <vl@samba.org>2016-04-26 01:20:25 +0200
commit81ca7eac3dd45ba245de2526187f76c665aae11e (patch)
tree7dce92f77b40376030c4a972474930a675814dec /lib/addns
parent53e0860122c3fa6b9fe80b5693c7b1eee2ad605d (diff)
downloadsamba-81ca7eac3dd45ba245de2526187f76c665aae11e.tar.gz
Refactor the dns_open_connection code so that duplicate code is removed and ensure that EINTR is handled in the UDP path.
Signed-off-by: Richard Sharpe <rsharpe@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org>
Diffstat (limited to 'lib/addns')
-rw-r--r--lib/addns/dnssock.c94
1 files changed, 39 insertions, 55 deletions
diff --git a/lib/addns/dnssock.c b/lib/addns/dnssock.c
index a45e3255a54..ec42b7ca689 100644
--- a/lib/addns/dnssock.c
+++ b/lib/addns/dnssock.c
@@ -37,30 +37,22 @@ static int destroy_dns_connection(struct dns_connection *conn)
/********************************************************************
********************************************************************/
-static DNS_ERROR dns_tcp_open( const char *nameserver,
- TALLOC_CTX *mem_ctx,
- struct dns_connection **result )
+static DNS_ERROR dns_open_helper(const char *nameserver,
+ const char *service,
+ struct addrinfo *hints,
+ TALLOC_CTX *mem_ctx,
+ struct dns_connection **ret_conn)
{
- struct addrinfo hints;
- struct addrinfo *ai_result = NULL;
- struct addrinfo *rp;
- struct dns_connection *conn;
int ret;
- char service[16];
-
- snprintf(service, sizeof(service), "%d", DNS_TCP_PORT);
+ struct addrinfo *rp;
+ struct addrinfo *ai_result = NULL;
+ struct dns_connection *conn = NULL;
if (!(conn = talloc(mem_ctx, struct dns_connection))) {
return ERROR_DNS_NO_MEMORY;
}
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = 0;
- hints.ai_protocol = IPPROTO_TCP;
-
- ret = getaddrinfo(nameserver, service, &hints, &ai_result);
+ ret = getaddrinfo(nameserver, service, hints, &ai_result);
if (ret != 0) {
DEBUG(1,("dns_tcp_open: getaddrinfo: %s\n", gai_strerror(ret)));
TALLOC_FREE(conn);
@@ -86,7 +78,6 @@ static DNS_ERROR dns_tcp_open( const char *nameserver,
freeaddrinfo(ai_result);
- /* Failed to connect with any address */
if (rp == NULL) {
TALLOC_FREE(conn);
return ERROR_DNS_CONNECTION_FAILED;
@@ -94,6 +85,32 @@ static DNS_ERROR dns_tcp_open( const char *nameserver,
talloc_set_destructor(conn, destroy_dns_connection);
+ *ret_conn = conn;
+ return ERROR_DNS_SUCCESS;
+}
+
+static DNS_ERROR dns_tcp_open( const char *nameserver,
+ TALLOC_CTX *mem_ctx,
+ struct dns_connection **result )
+{
+ struct addrinfo hints;
+ struct dns_connection *conn;
+ DNS_ERROR dns_ret;
+ char service[16];
+
+ snprintf(service, sizeof(service), "%d", DNS_TCP_PORT);
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ dns_ret = dns_open_helper(nameserver, service, &hints, mem_ctx, &conn);
+ if (!ERR_DNS_IS_OK(dns_ret)) {
+ return dns_ret;
+ }
+
conn->hType = DNS_TCP;
*result = conn;
return ERROR_DNS_SUCCESS;
@@ -107,58 +124,26 @@ static DNS_ERROR dns_udp_open( const char *nameserver,
struct dns_connection **result )
{
struct addrinfo hints;
- struct addrinfo *ai_result = NULL;
- struct addrinfo *rp;
struct sockaddr_storage RecvAddr;
struct dns_connection *conn;
- int ret;
+ DNS_ERROR dns_ret;
socklen_t RecvAddrLen;
char service[16];
snprintf(service, sizeof(service), "%d", DNS_UDP_PORT);
- if (!(conn = talloc(NULL, struct dns_connection))) {
- return ERROR_DNS_NO_MEMORY;
- }
-
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = 0;
hints.ai_protocol = IPPROTO_UDP;
- ret = getaddrinfo(nameserver, service, &hints, &ai_result);
- if (ret != 0) {
- DEBUG(1,("dns_ucp_open:getaddrinfo: %s\n", gai_strerror(ret)));
+ dns_ret = dns_open_helper(nameserver, service, &hints, mem_ctx, &conn);
+ if (!ERR_DNS_IS_OK(dns_ret)) {
TALLOC_FREE(conn);
- return ERROR_DNS_INVALID_NAME_SERVER;
+ return dns_ret;
}
- for (rp = ai_result; rp != NULL; rp = rp->ai_next) {
- conn->s = socket(rp->ai_family,
- rp->ai_socktype,
- rp->ai_protocol);
- if (conn->s == -1) {
- continue;
- }
- ret = connect(conn->s, rp->ai_addr, rp->ai_addrlen);
- if (ret != -1) {
- /* Successful connect */
- break;
- }
- close(conn->s);
- }
-
- freeaddrinfo(ai_result);
-
- /* Failed to connect with any address */
- if (rp == NULL) {
- TALLOC_FREE(conn);
- return ERROR_DNS_CONNECTION_FAILED;
- }
-
- talloc_set_destructor(conn, destroy_dns_connection);
-
/* Set up the RecvAddr structure with the IP address of
the receiver and the specified port number. */
@@ -166,7 +151,6 @@ static DNS_ERROR dns_udp_open( const char *nameserver,
if (getpeername(conn->s,
(struct sockaddr *)&RecvAddr,
&RecvAddrLen) == -1) {
- TALLOC_FREE(conn);
return ERROR_DNS_CONNECTION_FAILED;
}