[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-606-g5c7f762

Jeremy Allison jra at samba.org
Wed Dec 12 17:43:26 GMT 2007


The branch, v3-2-test has been updated
       via  5c7f7629a97ef0929e00e52f1fae4386c984000b (commit)
      from  aabe9b33fcaed8af98b1ed6b736253e196d87d48 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 5c7f7629a97ef0929e00e52f1fae4386c984000b
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Dec 12 09:42:58 2007 -0800

    Allow cliconnect to loop through multiple ip addresses
    for a server. We should have been doing this for a while,
    but it's more critical with IPv6.
    Original patch fixed up by James.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source/libsmb/cliconnect.c |   72 ++++++++++++++++++++++++++------------
 source/libsmb/namequery.c  |   81 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 130 insertions(+), 23 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index fdf7491..45c2020 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -1424,7 +1424,11 @@ NTSTATUS cli_connect(struct cli_state *cli,
 
 {
 	int name_type = 0x20;
-	char *p;
+	TALLOC_CTX *frame = talloc_stackframe();
+	unsigned int num_addrs = 0;
+	unsigned int i = 0;
+	struct sockaddr_storage *ss_arr = NULL;
+	char *p = NULL;
 
 	/* reasonable default hostname */
 	if (!host) {
@@ -1440,44 +1444,66 @@ NTSTATUS cli_connect(struct cli_state *cli,
 	}
 
 	if (!dest_ss || is_zero_addr(dest_ss)) {
-                if (!resolve_name(cli->desthost, &cli->dest_ss, name_type)) {
+		NTSTATUS status =resolve_name_list(frame,
+					cli->desthost,
+					name_type,
+					&ss_arr,
+					&num_addrs);
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(frame);
 			return NT_STATUS_BAD_NETWORK_NAME;
                 }
-		if (dest_ss) {
-			*dest_ss = cli->dest_ss;
-		}
 	} else {
-		cli->dest_ss = *dest_ss;
+		num_addrs = 1;
+		ss_arr = TALLOC_P(frame, struct sockaddr_storage);
+		if (!ss_arr) {
+			TALLOC_FREE(frame);
+			return NT_STATUS_NO_MEMORY;
+		}
+		*ss_arr = *dest_ss;
 	}
 
-	if (getenv("LIBSMB_PROG")) {
-		cli->fd = sock_exec(getenv("LIBSMB_PROG"));
-	} else {
-		/* try 445 first, then 139 */
-		uint16_t port = cli->port?cli->port:445;
-		cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
-					  port, cli->timeout);
-		if (cli->fd == -1 && cli->port == 0) {
-			port = 139;
+	for (i = 0; i < num_addrs; i++) {
+		cli->dest_ss = ss_arr[i];
+		if (getenv("LIBSMB_PROG")) {
+			cli->fd = sock_exec(getenv("LIBSMB_PROG"));
+		} else {
+			/* try 445 first, then 139 */
+			uint16_t port = cli->port?cli->port:445;
 			cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
 						  port, cli->timeout);
+			if (cli->fd == -1 && cli->port == 0) {
+				port = 139;
+				cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
+							  port, cli->timeout);
+			}
+			if (cli->fd != -1) {
+				cli->port = port;
+			}
 		}
-		if (cli->fd != -1) {
-			cli->port = port;
+		if (cli->fd == -1) {
+			char addr[INET6_ADDRSTRLEN];
+			print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
+			DEBUG(2,("Error connecting to %s (%s)\n",
+				 dest_ss?addr:host,strerror(errno)));
+		} else {
+			/* Exit from loop on first connection. */
+			break;
 		}
 	}
+
 	if (cli->fd == -1) {
-		char addr[INET6_ADDRSTRLEN];
-		if (dest_ss) {
-			print_sockaddr(addr, sizeof(addr), dest_ss);
-		}
-		DEBUG(1,("Error connecting to %s (%s)\n",
-			 dest_ss?addr:host,strerror(errno)));
+		TALLOC_FREE(frame);
 		return map_nt_error_from_unix(errno);
 	}
 
+	if (dest_ss) {
+		*dest_ss = cli->dest_ss;
+	}
+
 	set_socket_options(cli->fd, lp_socket_options());
 
+	TALLOC_FREE(frame);
 	return NT_STATUS_OK;
 }
 
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index 819147d..853fe97 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -1654,6 +1654,87 @@ bool resolve_name(const char *name,
 }
 
 /********************************************************
+ Internal interface to resolve a name into a list of IP addresses.
+ Use this function if the string is either an IP address, DNS
+ or host name or NetBIOS name. This uses the name switch in the
+ smb.conf to determine the order of name resolution.
+*********************************************************/
+
+NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
+		const char *name,
+		int name_type,
+		struct sockaddr_storage **return_ss_arr,
+		unsigned int *p_num_entries)
+{
+	struct ip_service *ss_list = NULL;
+	char *sitename = NULL;
+	int count = 0;
+	int i;
+	unsigned int num_entries;
+	NTSTATUS status;
+
+	*p_num_entries = 0;
+	*return_ss_arr = NULL;
+
+	if (is_ipaddress(name)) {
+		*return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
+		if (!*return_ss_arr) {
+			return NT_STATUS_NO_MEMORY;
+		}
+		if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
+			TALLOC_FREE(*return_ss_arr);
+			return NT_STATUS_BAD_NETWORK_NAME;
+		}
+		*p_num_entries = 1;
+		return NT_STATUS_OK;
+	}
+
+	sitename = sitename_fetch(lp_realm()); /* wild guess */
+
+	status = internal_resolve_name(name, name_type, sitename,
+						  &ss_list, &count,
+						  lp_name_resolve_order());
+	SAFE_FREE(sitename);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/* only return valid addresses for TCP connections */
+	for (i=0, num_entries = 0; i<count; i++) {
+		if (!is_zero_addr(&ss_list[i].ss) &&
+				!is_broadcast_addr(&ss_list[i].ss)) {
+			num_entries++;
+		}
+	}
+	if (num_entries == 0) {
+		SAFE_FREE(ss_list);
+		return NT_STATUS_BAD_NETWORK_NAME;
+	}
+
+	*return_ss_arr = TALLOC_ARRAY(ctx,
+				struct sockaddr_storage,
+				num_entries);
+	if (!(*return_ss_arr)) {
+		SAFE_FREE(ss_list);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	for (i=0, num_entries = 0; i<count; i++) {
+		if (!is_zero_addr(&ss_list[i].ss) &&
+				!is_broadcast_addr(&ss_list[i].ss)) {
+			(*return_ss_arr)[num_entries++] = ss_list[i].ss;
+		}
+	}
+
+	status = NT_STATUS_OK;
+	*p_num_entries = num_entries;
+
+	SAFE_FREE(ss_list);
+	return NT_STATUS_OK;
+}
+
+/********************************************************
  Find the IP address of the master browser or DMB for a workgroup.
 *********************************************************/
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list