The Samba-Bugzilla – Attachment 11073 Details for
Bug 11283
DNS tcp/odp connections for ADS client are not IPv6 enabled
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch IPv6 enabled DNS connectiosn for ADS client
0001-s3-IPv6-enabled-DNS-connections-for-ADS-client.patch (text/plain), 6.55 KB, created by
David Holder
on 2015-05-20 16:25:33 UTC
(
hide
)
Description:
Patch IPv6 enabled DNS connectiosn for ADS client
Filename:
MIME Type:
Creator:
David Holder
Created:
2015-05-20 16:25:33 UTC
Size:
6.55 KB
patch
obsolete
>From ee02aedadfae80ef7f9b19f16170895bb904633a Mon Sep 17 00:00:00 2001 >From: David Holder <david.holder@erion.co.uk> >Date: Wed, 13 May 2015 15:10:47 +0100 >Subject: [PATCH] s3: IPv6 enabled DNS connections for ADS client > >This patch makes DNS client connections protocol independent. >For example DNS updates. This makes IPv6-only clients possible. > >Signed-off-by: David Holder <david.holder@erion.co.uk> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > lib/addns/dns.h | 2 +- > lib/addns/dnssock.c | 127 +++++++++++++++++++++++++++++++++++----------------- > 2 files changed, 86 insertions(+), 43 deletions(-) > >diff --git a/lib/addns/dns.h b/lib/addns/dns.h >index bf2ade3..de1897b 100644 >--- a/lib/addns/dns.h >+++ b/lib/addns/dns.h >@@ -222,7 +222,7 @@ struct dns_update_request { > struct dns_connection { > int32_t hType; > int s; >- struct sockaddr RecvAddr; >+ struct sockaddr_storage RecvAddr; > }; > > struct dns_buffer { >diff --git a/lib/addns/dnssock.c b/lib/addns/dnssock.c >index 13649b5..b1d794d 100644 >--- a/lib/addns/dnssock.c >+++ b/lib/addns/dnssock.c >@@ -27,6 +27,7 @@ > #include <sys/time.h> > #include <unistd.h> > #include "system/select.h" >+#include "../lib/util/debug.h" > > static int destroy_dns_connection(struct dns_connection *conn) > { >@@ -40,78 +41,118 @@ static DNS_ERROR dns_tcp_open( const char *nameserver, > TALLOC_CTX *mem_ctx, > struct dns_connection **result ) > { >- uint32_t ulAddress; >- struct hostent *pHost; >- struct sockaddr_in s_in; >+ struct addrinfo hints; >+ struct addrinfo *ai_result = NULL; >+ struct addrinfo *rp; > struct dns_connection *conn; >- int res; >+ int ret; >+ char service[16]; >+ >+ snprintf(service, sizeof(service), "%d", DNS_TCP_PORT); > > if (!(conn = talloc(mem_ctx, struct dns_connection))) { > return ERROR_DNS_NO_MEMORY; > } > >- if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) { >- if ( (pHost = gethostbyname( nameserver )) == NULL ) { >- TALLOC_FREE(conn); >- return ERROR_DNS_INVALID_NAME_SERVER; >- } >- memcpy( &ulAddress, pHost->h_addr, pHost->h_length ); >- } >+ 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; > >- conn->s = socket( PF_INET, SOCK_STREAM, 0 ); >- if (conn->s == -1) { >+ ret = getaddrinfo(nameserver, service, &hints, &ai_result); >+ if (ret != 0) { >+ DEBUG(1,("dns_tcp_open: getaddrinfo: %s\n", gai_strerror(ret))); > TALLOC_FREE(conn); >- return ERROR_DNS_CONNECTION_FAILED; >+ return ERROR_DNS_INVALID_NAME_SERVER; > } > >- talloc_set_destructor(conn, destroy_dns_connection); >+ 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; >+ } >+ do { >+ ret = connect(conn->s, rp->ai_addr, rp->ai_addrlen); >+ } while ((ret == -1) && (errno == EINTR)); >+ if (ret != -1) { >+ /* Successful connect */ >+ break; >+ } >+ close(conn->s); >+ } > >- s_in.sin_family = AF_INET; >- s_in.sin_addr.s_addr = ulAddress; >- s_in.sin_port = htons( DNS_TCP_PORT ); >+ freeaddrinfo(ai_result); > >- do { >- res = connect(conn->s, (struct sockaddr*)&s_in, sizeof( s_in )); >- } while ((res == -1) && (errno == EINTR)); >- if (res == -1) { >+ /* Failed to connect with any address */ >+ if (rp == NULL) { > TALLOC_FREE(conn); > return ERROR_DNS_CONNECTION_FAILED; > } > >- conn->hType = DNS_TCP; >+ talloc_set_destructor(conn, destroy_dns_connection); > >+ conn->hType = DNS_TCP; > *result = conn; > return ERROR_DNS_SUCCESS; > } > > /******************************************************************** >-********************************************************************/ >+ * ********************************************************************/ > > static DNS_ERROR dns_udp_open( const char *nameserver, > TALLOC_CTX *mem_ctx, > struct dns_connection **result ) > { >- unsigned long ulAddress; >- struct hostent *pHost; >- struct sockaddr_in RecvAddr; >+ struct addrinfo hints; >+ struct addrinfo *ai_result = NULL; >+ struct addrinfo *rp; >+ struct sockaddr_storage RecvAddr; > struct dns_connection *conn; >+ int 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; > } > >- if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) { >- if ( (pHost = gethostbyname( nameserver )) == NULL ) { >- TALLOC_FREE(conn); >- return ERROR_DNS_INVALID_NAME_SERVER; >+ 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))); >+ TALLOC_FREE(conn); >+ return ERROR_DNS_INVALID_NAME_SERVER; >+ } >+ >+ 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; > } >- memcpy( &ulAddress, pHost->h_addr, pHost->h_length ); >+ close(conn->s); > } > >- /* Create a socket for sending data */ >+ freeaddrinfo(ai_result); > >- conn->s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); >- if (conn->s == -1) { >+ /* Failed to connect with any address */ >+ if (rp == NULL) { > TALLOC_FREE(conn); > return ERROR_DNS_CONNECTION_FAILED; > } >@@ -119,16 +160,18 @@ static DNS_ERROR dns_udp_open( const char *nameserver, > talloc_set_destructor(conn, destroy_dns_connection); > > /* Set up the RecvAddr structure with the IP address of >- the receiver (in this example case "123.456.789.1") >- and the specified port number. */ >+ the receiver and the specified port number. */ > >- ZERO_STRUCT(RecvAddr); >- RecvAddr.sin_family = AF_INET; >- RecvAddr.sin_port = htons( DNS_UDP_PORT ); >- RecvAddr.sin_addr.s_addr = ulAddress; >+ RecvAddrLen = sizeof(RecvAddr); >+ if (getpeername(conn->s, >+ (struct sockaddr *)&RecvAddr, >+ &RecvAddrLen) == -1) { >+ TALLOC_FREE(conn); >+ return ERROR_DNS_CONNECTION_FAILED; >+ } > > conn->hType = DNS_UDP; >- memcpy( &conn->RecvAddr, &RecvAddr, sizeof( struct sockaddr_in ) ); >+ memcpy(&conn->RecvAddr, &RecvAddr, sizeof(struct sockaddr_storage)); > > *result = conn; > return ERROR_DNS_SUCCESS; >-- >2.2.0.rc0.207.ga3a616c >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 11283
:
11073
|
11088
|
11092