[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-643-g0de2b3e

James Peach jpeach at samba.org
Fri Dec 14 04:57:37 GMT 2007


The branch, v3-2-test has been updated
       via  0de2b3eb515f2da21ffd1ce54979bb1f8063024b (commit)
       via  1e7241517d1f55d60af22570e0c9feb280e3fdb5 (commit)
      from  27078d1292e8588956ae78e4cddb1bcebbe84478 (commit)

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


- Log -----------------------------------------------------------------
commit 0de2b3eb515f2da21ffd1ce54979bb1f8063024b
Merge: 1e7241517d1f55d60af22570e0c9feb280e3fdb5 27078d1292e8588956ae78e4cddb1bcebbe84478
Author: James Peach <jpeach at samba.org>
Date:   Thu Dec 13 20:56:53 2007 -0800

    Merge branch 'v3-2-test' of git://git.samba.org/samba into v3-2-test

commit 1e7241517d1f55d60af22570e0c9feb280e3fdb5
Author: Rishi Srivatsavai <rishisv at gmail.com>
Date:   Thu Dec 13 20:56:29 2007 -0800

    Register the smb service with mDNS if mSDN is supported.
    
    If mDNS is supported, attempt to register the first port we are
    listening on for the _smb._tcp service. This provides more reliable
    service discovery than NetBIOS browsing.

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

Summary of changes:
 source/Makefile.in        |    1 +
 source/include/includes.h |   14 +++
 source/smbd/dnsregister.c |  212 +++++++++++++++++++++++++++++++++++++++++++++
 source/smbd/server.c      |   50 +++++++++--
 4 files changed, 268 insertions(+), 9 deletions(-)
 create mode 100644 source/smbd/dnsregister.c


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index d26f688..5a8d7e1 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -547,6 +547,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
 	       $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
 	       smbd/dmapi.o \
 	       smbd/file_access.o \
+	       smbd/dnsregister.o \
 	       $(MANGLE_OBJ) @VFS_STATIC@
 
 SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
diff --git a/source/include/includes.h b/source/include/includes.h
index 4e42088..2245174 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -752,6 +752,20 @@ struct printjob;
 
 #include "smb_ldap.h"
 
+struct dns_reg_state;
+
+void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
+		unsigned port,
+		int *maxfd,
+		fd_set *listen_set,
+		struct timeval *timeout);
+
+void dns_register_close(struct dns_reg_state ** dns_state_ptr);
+
+
+bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
+		fd_set *lfds, struct timeval *timeout);
+
 /*
  * Reasons for cache flush.
  */
diff --git a/source/smbd/dnsregister.c b/source/smbd/dnsregister.c
new file mode 100644
index 0000000..fcd97b5
--- /dev/null
+++ b/source/smbd/dnsregister.c
@@ -0,0 +1,212 @@
+/*
+   Unix SMB/CIFS implementation.
+   DNS-SD registration
+   Copyright (C) Rishi Srivatsavai 2007
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <includes.h>
+#include <dns_sd.h>
+
+/* Uses DNS service discovery (libdns_sd) to
+ * register the SMB service. SMB service is registered
+ * on ".local" domain via Multicast DNS & any
+ * other unicast DNS domains available.
+ *
+ * Users use the smbclient -B (Browse) option to
+ * browse for advertised SMB services.
+ */
+
+#define DNS_REG_RETRY_INTERVAL (5*60)  /* in seconds */
+
+struct dns_reg_state {
+	DNSServiceRef srv_ref;
+	struct timed_event *retry_handler;
+};
+
+#ifdef WITH_DNSSD_SUPPORT
+
+void dns_register_close(struct dns_reg_state **dns_state_ptr)
+{
+	int mdnsd_conn_fd;
+	struct dns_reg_state *dns_state = *dns_state_ptr;
+
+	if (dns_state == NULL) {
+		return;
+	}
+
+	if (dns_state->srv_ref != NULL) {
+		/* Close connection to the mDNS daemon */
+		DNSServiceRefDeallocate(dns_state->srv_ref);
+		dns_state->srv_ref = NULL;
+	}
+
+	/* Clear event handler */
+	if (dns_state->retry_handler != NULL) {
+		TALLOC_FREE(dns_state->retry_handler);
+		dns_state->retry_handler = NULL;
+	}
+
+	talloc_free(dns_state);
+	*dns_state_ptr = NULL;
+}
+
+static void dns_register_smbd_retry(struct event_context *ctx,
+                                   struct timed_event *te,
+                                   const struct timeval *now,
+                                   void *private_data)
+{
+	struct dns_reg_state *dns_state = (struct dns_reg_state *)private_data;
+
+	/* Clear previous registration state to force new
+	 * registration attempt. Clears event handler.
+	 */
+	dns_register_close(dns_state);
+}
+
+static void schedule_dns_register_smbd_retry(struct dns_reg_state *dns_state,
+		struct timeval *timeout)
+{
+	struct timed_event * event;
+
+	dns_state->srv_ref = NULL;
+	event= event_add_timed(smbd_event_context(),
+			NULL,
+			timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0),
+			"DNS registration handler",
+			dns_register_smbd_retry,
+			dns_state);
+
+	dns_state->retry_handler = event;
+	get_timed_events_timeout(smbd_event_context(), timeout);
+}
+
+/* Kick off a mDNS request to register the "_smb._tcp" on the specified port.
+ * We really ought to register on all the ports we are listening on. This will
+ * have to be an exercise for some-one who knows the DNS registration API a bit
+ * better.
+ */
+void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
+		unsigned port,
+		int *maxfd,
+		fd_set *listen_set,
+		struct timeval *timeout)
+{
+	int mdnsd_conn_fd;
+	DNSServiceErrorType err;
+	struct dns_reg_state *dns_state = *dns_state_ptr;
+
+	if (dns_state == NULL) {
+		*dns_state_ptr = dns_state = talloc(NULL, struct dns_reg_state);
+		if (dns_state == NULL) {
+			return;
+		}
+	}
+
+	/* Quit if a re-try attempt has been scheduled.  */
+	if (dns_state->retry_handler != NULL) {
+		return;
+	}
+
+	/* If a registration is active add conn
+	 * fd to select listen_set and return
+	 */
+	if (dns_state->srv_ref != NULL) {
+		mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
+		FD_SET(mdnsd_conn_fd, listen_set);
+		return;
+	}
+
+	DEBUG(6, ("registering _smb._tcp service on port %d\n", port));
+
+	/* Register service with DNS. Connects with the mDNS
+	 * daemon running on the local system to perform DNS
+	 * service registration.
+	 */
+	err = DNSServiceRegister(&dns_state->srv_ref, 0 /* flags */,
+			kDNSServiceInterfaceIndexAny,
+			NULL /* service name */,
+			"_smb._tcp" /* service type */,
+			NULL /* domain */,
+			"" /* SRV target host name */,
+			htons(port),
+			0 /* TXT record len */,
+			NULL /* TXT record data */,
+			NULL /* callback func */,
+			NULL /* callback context */);
+
+	if (err != kDNSServiceErr_NoError) {
+		/* Failed to register service. Schedule a re-try attempt.
+		 */
+		DEBUG(3, ("unable to register with mDNS (err %d)\n", err));
+		schedule_dns_register_smbd_retry(dns_state, timeout);
+		return;
+	}
+
+	mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
+	FD_SET(mdnsd_conn_fd, listen_set);
+	*maxfd = MAX(*maxfd, mdnsd_conn_fd);
+	*timeout = timeval_zero();
+
+}
+
+/* Processes reply from mDNS daemon. Returns true if a reply was received */
+bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
+		fd_set *lfds, struct timeval *timeout)
+{
+	int mdnsd_conn_fd = -1;
+
+	if (dns_state->srv_ref == NULL) {
+		return false;
+	}
+
+	mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
+
+	/* Process reply from daemon. Handles any errors. */
+	if ((mdnsd_conn_fd != -1) && (FD_ISSET(mdnsd_conn_fd,lfds)) ) {
+		DNSServiceErrorType err;
+		
+		err = DNSServiceProcessResult(dns_state->srv_ref);
+		if (err != kDNSServiceErr_NoError) {
+			DEBUG(3, ("failed to process mDNS result (err %d), re-trying\n",
+				    err));
+			schedule_dns_register_smbd_retry(dns_state, timeout);
+		}
+
+		return true;
+	}
+
+	return false;
+}
+
+#else /* WITH_DNSSD_SUPPORT */
+
+ void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
+		unsigned port,
+		int *maxfd,
+		fd_set *listen_set,
+		struct timeval *timeout)
+{}
+
+ void dns_register_close(struct dns_reg_state ** dns_state_ptr)
+{}
+
+ bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
+		fd_set *lfds, struct timeval *timeout)
+{
+	return false;
+}
+
+#endif /* WITH_DNSSD_SUPPORT */
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 0aa8dac..41d036a 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -311,6 +311,8 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 	int maxfd = 0;
 	int i;
 	char *ports;
+	struct dns_reg_state * dns_reg = NULL;
+	unsigned dns_port = 0;
 
 	if (!is_daemon) {
 		return open_sockets_inetd();
@@ -372,6 +374,14 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 				if (port == 0 || port > 0xffff) {
 					continue;
 				}
+
+				/* Keep the first port for mDNS service
+				 * registration.
+				 */
+				if (dns_port == 0) {
+					dns_port = port;
+				}
+
 				s = fd_listenset[num_sockets] =
 					open_socket_in(SOCK_STREAM, port, 0,
 							ifss, True);
@@ -436,6 +446,14 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 				if (port == 0 || port > 0xffff) {
 					continue;
 				}
+
+				/* Keep the first port for mDNS service
+				 * registration.
+				 */
+				if (dns_port == 0) {
+					dns_port = port;
+				}
+
 				/* open an incoming socket */
 				if (!interpret_string_addr(&ss, sock_tok,
 						AI_NUMERICHOST|AI_PASSIVE)) {
@@ -543,6 +561,12 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 		FD_ZERO(&w_fds);
 		GetTimeOfDay(&now);
 
+		/* Kick off our mDNS registration. */
+		if (dns_port != 0) {
+			dns_register_smbd(&dns_reg, dns_port, &maxfd,
+					&r_fds, &idle_timeout);
+		}
+
 		event_add_to_select_args(smbd_event_context(), &now,
 					 &r_fds, &w_fds, &idle_timeout,
 					 &maxfd);
@@ -567,6 +591,11 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 			continue;
 		}
 
+		/* process pending nDNS responses */
+		if (dns_register_smbd_reply(dns_reg, &r_fds, &idle_timeout)) {
+			--num;
+		}
+
 		if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
 			continue;
 		}
@@ -624,6 +653,9 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 				for(i = 0; i < num_sockets; i++)
 					close(fd_listenset[i]);
 
+				/* close our mDNS daemon handle */
+				dns_register_close(&dns_reg);
+
 				/* close our standard file
 				   descriptors */
 				close_low_fds(False);
@@ -964,8 +996,6 @@ extern void build_options(bool screen);
 	};
 	TALLOC_CTX *frame = talloc_stackframe(); /* Setup tos. */
 
-	load_case_tables();
-
 	TimeInit();
 
 #ifdef HAVE_SET_AUTH_PARAMETERS
@@ -1002,11 +1032,20 @@ extern void build_options(bool screen);
 	}
 	poptFreeContext(pc);
 
+	if (interactive) {
+		Fork = False;
+		log_stdout = True;
+	}
+
+	setup_logging(argv[0],log_stdout);
+
 	if (print_build_options) {
 		build_options(True); /* Display output to screen as well as debug */
 		exit(0);
 	}
 
+	load_case_tables();
+
 #ifdef HAVE_SETLUID
 	/* needed for SecureWare on SCO */
 	setluid(0);
@@ -1016,11 +1055,6 @@ extern void build_options(bool screen);
 
 	set_remote_machine_name("smbd", False);
 
-	if (interactive) {
-		Fork = False;
-		log_stdout = True;
-	}
-
 	if (interactive && (DEBUGLEVEL >= 9)) {
 		talloc_enable_leak_report();
 	}
@@ -1030,8 +1064,6 @@ extern void build_options(bool screen);
 		exit(1);
 	}
 
-	setup_logging(argv[0],log_stdout);
-
 	/* we want to re-seed early to prevent time delays causing
            client problems at a later date. (tridge) */
 	generate_random_buffer(NULL, 0);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list