svn commit: samba r17795 - in branches: SAMBA_3_0/source/include SAMBA_3_0/source/libads SAMBA_3_0/source/libsmb SAMBA_3_0_23/source/include SAMBA_3_0_23/source/libads SAMBA_3_0_23/source/libsmb

jerry at samba.org jerry at samba.org
Thu Aug 24 12:14:01 GMT 2006


Author: jerry
Date: 2006-08-24 12:13:57 +0000 (Thu, 24 Aug 2006)
New Revision: 17795

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17795

Log:
Finally track down the "ads_connect: Interrupted system call"
error.  Fix our DNS SRV lookup code to deal with multi-homed hosts.
We were noly remembering one IP address per host from the Additional
records section in the SRV response which could have been an unreachable
address.


Modified:
   branches/SAMBA_3_0/source/include/ads_dns.h
   branches/SAMBA_3_0/source/libads/dns.c
   branches/SAMBA_3_0/source/libsmb/namequery.c
   branches/SAMBA_3_0_23/source/include/ads_dns.h
   branches/SAMBA_3_0_23/source/libads/dns.c
   branches/SAMBA_3_0_23/source/libsmb/namequery.c


Changeset:
Modified: branches/SAMBA_3_0/source/include/ads_dns.h
===================================================================
--- branches/SAMBA_3_0/source/include/ads_dns.h	2006-08-24 12:13:41 UTC (rev 17794)
+++ branches/SAMBA_3_0/source/include/ads_dns.h	2006-08-24 12:13:57 UTC (rev 17795)
@@ -47,10 +47,11 @@
 	uint16 priority;
 	uint16 weight;
 	uint16 port;
-	struct in_addr ip;
+	size_t num_ips;
+	struct in_addr *ips;	/* support multi-homed hosts */
 };
 
-/* SRV records */
+/* NS records */
 
 struct dns_rr_ns {
 	const char *hostname;

Modified: branches/SAMBA_3_0/source/libads/dns.c
===================================================================
--- branches/SAMBA_3_0/source/libads/dns.c	2006-08-24 12:13:41 UTC (rev 17794)
+++ branches/SAMBA_3_0/source/libads/dns.c	2006-08-24 12:13:57 UTC (rev 17795)
@@ -398,14 +398,45 @@
 		}
 
 		/* only interested in A records as a shortcut for having to come 
-		   back later and lookup the name */
+		   back later and lookup the name.  For multi-homed hosts, the 
+		   number of additional records and exceed the number of answer 
+		   records. */
+		  
 
 		if ( (rr.type != T_A) || (rr.rdatalen != 4) ) 
 			continue;
 
+		/* FIX ME!!! Should this be a list of IP addresses for 
+		   each host? */ 
+		   
 		for ( i=0; i<idx; i++ ) {
 			if ( strcmp( rr.hostname, dcs[i].hostname ) == 0 ) {
-				uint8 *buf = (uint8*)&dcs[i].ip.s_addr;
+				int num_ips = dcs[i].num_ips;
+				uint8 *buf;
+				struct in_addr *tmp_ips;
+
+				/* allocate new memory */
+				
+				if ( dcs[i].num_ips == 0 ) {
+					if ( (dcs[i].ips = TALLOC_ARRAY( dcs, 
+						struct in_addr, 1 )) == NULL ) 
+					{
+						return NT_STATUS_NO_MEMORY;
+					}
+				} else {
+					if ( (tmp_ips = TALLOC_REALLOC_ARRAY( dcs, dcs[i].ips,
+						struct in_addr, dcs[i].num_ips+1)) == NULL ) 
+					{
+						return NT_STATUS_NO_MEMORY;
+					}
+					
+					dcs[i].ips = tmp_ips;
+				}
+				dcs[i].num_ips++;
+				
+				/* copy the new IP address */
+				
+				buf = (uint8*)&dcs[i].ips[num_ips].s_addr;
 				memcpy( buf, rr.rdata, 4 );
 			}
 		}

Modified: branches/SAMBA_3_0/source/libsmb/namequery.c
===================================================================
--- branches/SAMBA_3_0/source/libsmb/namequery.c	2006-08-24 12:13:41 UTC (rev 17794)
+++ branches/SAMBA_3_0/source/libsmb/namequery.c	2006-08-24 12:13:57 UTC (rev 17795)
@@ -1024,11 +1024,12 @@
 static BOOL resolve_ads(const char *name, int name_type,
                          struct ip_service **return_iplist, int *return_count)
 {
-	int 			i = 0;
+	int 			i, j;
 	NTSTATUS  		status;
 	TALLOC_CTX		*ctx;
 	struct dns_rr_srv	*dcs = NULL;
 	int			numdcs = 0;
+	int			numaddrs = 0;
 
 	if ( name_type != 0x1c )
 		return False;
@@ -1045,25 +1046,45 @@
 	if ( !NT_STATUS_IS_OK( status ) ) {
 		return False;
 	}
+
+	for (i=0;i<numdcs;i++) {
+		numaddrs += MAX(dcs[i].num_ips,1);
+	}
 		
-	if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numdcs)) == NULL ) {
-		DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numdcs ));
+	if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
+		DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
 		return False;
 	}
+	
+	/* now unroll the list of IP addresses */
 
 	*return_count = 0;
-
-	for (i=0;i<numdcs;i++) {
+	i = 0;
+	j = 0;
+	while ( i < numdcs && (*return_count<numaddrs) ) {
 		struct ip_service *r = &(*return_iplist)[*return_count];
 
-		/* use the IP address from the SRV structure if we have one */
-		if ( is_zero_ip( dcs[i].ip ) )
-			r->ip   = *interpret_addr2(dcs[i].hostname);
-		else
-			r->ip = dcs[i].ip;
-
 		r->port = dcs[i].port;
+		
+		/* If we don't have an IP list for a name, lookup it up */
+		
+		if ( !dcs[i].ips ) {
+			r->ip = *interpret_addr2(dcs[i].hostname);
+			i++;
+			j = 0;
+		} else {
+			/* use the IP addresses from the SRV sresponse */
 			
+			if ( j >= dcs[i].num_ips ) {
+				i++;
+				j = 0;
+				continue;
+			}
+			
+			r->ip = dcs[i].ips[j];
+			j++;
+		}
+			
 		/* make sure it is a valid IP.  I considered checking the negative
 		   connection cache, but this is the wrong place for it.  Maybe only
 		   as a hac.  After think about it, if all of the IP addresses retuend
@@ -1358,7 +1379,6 @@
 
 	*ordered = False;
 
-
 	/* if we are restricted to solely using DNS for looking
 	   up a domain controller, make sure that host lookups
 	   are enabled for the 'name resolve order'.  If host lookups
@@ -1374,9 +1394,9 @@
 			/* DNS SRV lookups used by the ads resolver
 			   are already sorted by priority and weight */
 			*ordered = True;
+		} else {
+                        fstrcpy( resolve_order, "NULL" );
 		}
-		else
-			fstrcpy( resolve_order, "NULL" );
 	}
 
 	/* fetch the server we have affinity for.  Add the 

Modified: branches/SAMBA_3_0_23/source/include/ads_dns.h
===================================================================
--- branches/SAMBA_3_0_23/source/include/ads_dns.h	2006-08-24 12:13:41 UTC (rev 17794)
+++ branches/SAMBA_3_0_23/source/include/ads_dns.h	2006-08-24 12:13:57 UTC (rev 17795)
@@ -46,8 +46,9 @@
 	const char *hostname;
 	uint16 priority;
 	uint16 weight;
-	uint16 port;
-	struct in_addr ip;
+	size_t num_ips;
+	struct in_addr *ips;    /* support multi-homed hosts */
+
 };
 
 

Modified: branches/SAMBA_3_0_23/source/libads/dns.c
===================================================================
--- branches/SAMBA_3_0_23/source/libads/dns.c	2006-08-24 12:13:41 UTC (rev 17794)
+++ branches/SAMBA_3_0_23/source/libads/dns.c	2006-08-24 12:13:57 UTC (rev 17795)
@@ -334,14 +334,45 @@
 		}
 
 		/* only interested in A records as a shortcut for having to come 
-		   back later and lookup the name */
+		   back later and lookup the name.  For multi-homed hosts, the 
+		   number of additional records and exceed the number of answer 
+		   records. */
+		  
 
 		if ( (rr.type != T_A) || (rr.rdatalen != 4) ) 
 			continue;
 
+		/* FIX ME!!! Should this be a list of IP addresses for 
+		   each host? */ 
+		   
 		for ( i=0; i<idx; i++ ) {
 			if ( strcmp( rr.hostname, dcs[i].hostname ) == 0 ) {
-				uint8 *buf = (uint8*)&dcs[i].ip.s_addr;
+				int num_ips = dcs[i].num_ips;
+				uint8 *buf;
+				struct in_addr *tmp_ips;
+
+				/* allocate new memory */
+				
+				if ( dcs[i].num_ips == 0 ) {
+					if ( (dcs[i].ips = TALLOC_ARRAY( dcs, 
+						struct in_addr, 1 )) == NULL ) 
+					{
+						return NT_STATUS_NO_MEMORY;
+					}
+				} else {
+					if ( (tmp_ips = TALLOC_REALLOC_ARRAY( dcs, dcs[i].ips,
+						struct in_addr, dcs[i].num_ips+1)) == NULL ) 
+					{
+						return NT_STATUS_NO_MEMORY;
+					}
+					
+					dcs[i].ips = tmp_ips;
+				}
+				dcs[i].num_ips++;
+				
+				/* copy the new IP address */
+				
+				buf = (uint8*)&dcs[i].ips[num_ips].s_addr;
 				memcpy( buf, rr.rdata, 4 );
 			}
 		}

Modified: branches/SAMBA_3_0_23/source/libsmb/namequery.c
===================================================================
--- branches/SAMBA_3_0_23/source/libsmb/namequery.c	2006-08-24 12:13:41 UTC (rev 17794)
+++ branches/SAMBA_3_0_23/source/libsmb/namequery.c	2006-08-24 12:13:57 UTC (rev 17795)
@@ -1024,11 +1024,12 @@
 static BOOL resolve_ads(const char *name, int name_type,
                          struct ip_service **return_iplist, int *return_count)
 {
-	int 			i = 0;
+	int 			i, j;
 	NTSTATUS  		status;
 	TALLOC_CTX		*ctx;
 	struct dns_rr_srv	*dcs = NULL;
 	int			numdcs = 0;
+	int			numaddrs = 0;
 
 	if ( name_type != 0x1c )
 		return False;
@@ -1045,25 +1046,45 @@
 	if ( !NT_STATUS_IS_OK( status ) ) {
 		return False;
 	}
+
+	for (i=0;i<numdcs;i++) {
+		numaddrs += MAX(dcs[i].num_ips,1);
+	}
 		
-	if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numdcs)) == NULL ) {
-		DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numdcs ));
+	if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
+		DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
 		return False;
 	}
+	
+	/* now unroll the list of IP addresses */
 
 	*return_count = 0;
-
-	for (i=0;i<numdcs;i++) {
+	i = 0;
+	j = 0;
+	while ( i < numdcs && (*return_count<numaddrs) ) {
 		struct ip_service *r = &(*return_iplist)[*return_count];
 
-		/* use the IP address from the SRV structure if we have one */
-		if ( is_zero_ip( dcs[i].ip ) )
-			r->ip   = *interpret_addr2(dcs[i].hostname);
-		else
-			r->ip = dcs[i].ip;
-
 		r->port = dcs[i].port;
+		
+		/* If we don't have an IP list for a name, lookup it up */
+		
+		if ( !dcs[i].ips ) {
+			r->ip = *interpret_addr2(dcs[i].hostname);
+			i++;
+			j = 0;
+		} else {
+			/* use the IP addresses from the SRV sresponse */
 			
+			if ( j >= dcs[i].num_ips ) {
+				i++;
+				j = 0;
+				continue;
+			}
+			
+			r->ip = dcs[i].ips[j];
+			j++;
+		}
+			
 		/* make sure it is a valid IP.  I considered checking the negative
 		   connection cache, but this is the wrong place for it.  Maybe only
 		   as a hac.  After think about it, if all of the IP addresses retuend
@@ -1358,7 +1379,6 @@
 
 	*ordered = False;
 
-
 	/* if we are restricted to solely using DNS for looking
 	   up a domain controller, make sure that host lookups
 	   are enabled for the 'name resolve order'.  If host lookups
@@ -1374,9 +1394,9 @@
 			/* DNS SRV lookups used by the ads resolver
 			   are already sorted by priority and weight */
 			*ordered = True;
+		} else {
+                        fstrcpy( resolve_order, "NULL" );
 		}
-		else
-			fstrcpy( resolve_order, "NULL" );
 	}
 
 	/* fetch the server we have affinity for.  Add the 



More information about the samba-cvs mailing list