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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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

Reply via email to