The Samba-Bugzilla – Attachment 2391 Details for
Bug 4510
DNS service discovery support in samba
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
PATCH for service discovery support in samba via DNS
smbdiff (text/plain), 12.21 KB, created by
Rishi Srivatsavai
on 2007-04-17 15:01:24 UTC
(
hide
)
Description:
PATCH for service discovery support in samba via DNS
Filename:
MIME Type:
Creator:
Rishi Srivatsavai
Created:
2007-04-17 15:01:24 UTC
Size:
12.21 KB
patch
obsolete
>Index: smbd/server.c >=================================================================== >--- smbd/server.c (revision 22320) >+++ smbd/server.c (working copy) >@@ -296,6 +296,120 @@ > return num_children < max_processes; > } > >+ >+#ifdef HAVE_LIBDNS_SD >+ >+/* 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. >+ */ >+ >+ >+static void dns_register_close(struct dns_reg_state *regstateptr) >+{ >+ int mdnsd_conn_fd; >+ >+ if (regstateptr == NULL) >+ return; >+ >+ if (regstateptr->regsrvref != NULL) { >+ /* Close connection to the mDNS daemon */ >+ DNSServiceRefDeallocate(regstateptr->regsrvref); >+ regstateptr->regsrvref = NULL; >+ } >+ >+ /* Clear event handler */ >+ if (regstateptr->dnsregretryhandler != NULL) { >+ TALLOC_FREE(regstateptr->dnsregretryhandler); >+ regstateptr->dnsregretryhandler = 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 *regstateptr = (struct dns_reg_state *)private_data; >+ /* Clear previous registration state to force new >+ * registration attempt. Clears event handler. */ >+ dns_register_close(regstateptr); >+} >+ >+static void schedule_dns_register_smbd_retry(struct dns_reg_state *regstateptr) >+{ >+ regstateptr->regsrvref = NULL; >+ regstateptr->dnsregretryhandler = event_add_timed( >+ smbd_event_context(), >+ NULL, timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0), >+ "DNS registration handler", >+ dns_register_smbd_retry, regstateptr); >+} >+ >+ >+ >+static void dns_register_smbd(struct dns_reg_state *regstateptr, int *maxfd, fd_set *listen_set) >+{ >+ int mdnsd_conn_fd; >+ >+ /* Quit if a re-try attempt has been scheduled. */ >+ if (regstateptr->dnsregretryhandler != NULL) >+ return; >+ >+ /* If a registration is active add conn >+ * fd to select listen_set and return */ >+ if (regstateptr->regsrvref != NULL) { >+ mdnsd_conn_fd = DNSServiceRefSockFD(regstateptr->regsrvref); >+ FD_SET(mdnsd_conn_fd, listen_set); >+ return; >+ } >+ >+ /* Register service with DNS. Connects with the mDNS >+ * daemon running on the local system to perform DNS >+ * service registration. >+ */ >+ if (!DNSServiceRegister(®stateptr->regsrvref, 0, >+ kDNSServiceInterfaceIndexAny, "", "_smb._tcp", "", "", >+ htons(139), 0, NULL, NULL, NULL)) { >+ mdnsd_conn_fd = DNSServiceRefSockFD(regstateptr->regsrvref); >+ FD_SET(mdnsd_conn_fd, listen_set); >+ *maxfd = MAX(*maxfd, mdnsd_conn_fd); >+ } else { >+ /* Failed to register service. Schedule a re-try attempt. >+ */ >+ DEBUG(3,("dns_sd: could not register with mDNS daemon.\n")); >+ schedule_dns_register_smbd_retry(regstateptr); >+ } >+} >+ >+/* Processes reply from mDNS daemon. Returns True if a reply was received */ >+static BOOL dns_register_smbd_reply(struct dns_reg_state *regstateptr, fd_set *lfds) >+{ >+ int mdnsd_conn_fd = -1; >+ >+ if (regstateptr->regsrvref != NULL) { >+ mdnsd_conn_fd = DNSServiceRefSockFD(regstateptr->regsrvref); >+ /* Process reply from daemon. Handles any errors. */ >+ if( (mdnsd_conn_fd != -1) && (FD_ISSET(mdnsd_conn_fd, lfds)) ) { >+ if ( DNSServiceProcessResult(regstateptr->regsrvref) != kDNSServiceErr_NoError) { >+ DEBUG(3,("dns_sd: mdns process result returned error. Keep re-trying.\n")); >+ schedule_dns_register_smbd_retry(regstateptr); >+ } >+ return True; >+ } >+ } >+ return False; >+} >+ >+#endif /* HAVE_LIBDNS_SD */ >+ >+ >+ > /**************************************************************************** > Open the socket communication. > ****************************************************************************/ >@@ -311,6 +425,11 @@ > int i; > char *ports; > >+#ifdef HAVE_LIBDNS_SD >+ struct dns_reg_state dnsregptr; >+ (void) memset(&dnsregptr, 0, sizeof(struct dns_reg_state)); >+#endif >+ > if (!is_daemon) { > return open_sockets_inetd(); > } >@@ -459,6 +578,7 @@ > while (1) { > fd_set lfds; > int num; >+ struct timeval tmo; > > /* Free up temporary memory from the main smbd. */ > lp_TALLOC_FREE(); >@@ -477,9 +597,16 @@ > > memcpy((char *)&lfds, (char *)&listen_set, > sizeof(listen_set)); >+ >+#ifdef HAVE_LIBDNS_SD >+ dns_register_smbd(&dnsregptr, &maxfd, &lfds); >+#endif >+ >+ if (get_timed_events_timeout(smbd_event_context(), &tmo) != NULL) >+ num = sys_select(maxfd+1,&lfds,NULL,NULL,&tmo); >+ else >+ num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL); > >- num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL); >- > if (num == -1 && errno == EINTR) { > if (got_sig_term) { > exit_server_cleanly(NULL); >@@ -495,7 +622,15 @@ > > continue; > } >- >+ >+#ifdef HAVE_LIBDNS_SD >+ if (dns_register_smbd_reply(&dnsregptr, &lfds) && ((--num) == 0)) >+ continue; >+#endif >+ >+ /* Process expired events */ >+ run_events(smbd_event_context(), 0, NULL, NULL); >+ > /* check if we need to reload services */ > check_reload(time(NULL)); > >@@ -546,6 +681,11 @@ > /* close the listening socket(s) */ > for(i = 0; i < num_sockets; i++) > close(fd_listenset[i]); >+ >+#ifdef HAVE_LIBDNS_SD >+ /* close socket to mDNS daemon */ >+ dns_register_close(&dnsregptr); >+#endif > > /* close our standard file > descriptors */ >Index: include/includes.h >=================================================================== >--- include/includes.h (revision 22320) >+++ include/includes.h (working copy) >@@ -1250,4 +1250,13 @@ > #include "libnscd.h" > #endif > >+#ifdef HAVE_LIBDNS_SD >+#include "dns_sd.h" >+#define DNS_REG_RETRY_INTERVAL 5*60 /* in seconds */ >+struct dns_reg_state { >+ DNSServiceRef regsrvref; >+ struct timed_event *dnsregretryhandler; >+}; >+#endif /* HAVE_LIBDNS_SD */ >+ > #endif /* _INCLUDES_H */ >Index: client/client.c >=================================================================== >--- client/client.c (revision 22320) >+++ client/client.c (working copy) >@@ -3909,6 +3909,9 @@ > { "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" }, > { "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" }, > { "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" }, >+#ifdef HAVE_LIBDNS_SD >+ { "browse", 'B', POPT_ARG_NONE, NULL, 'B', "Browse SMB servers using DNS" }, >+#endif /*HAVE_LIBDNS_SD */ > POPT_COMMON_SAMBA > POPT_COMMON_CONNECTION > POPT_COMMON_CREDENTIALS >@@ -4040,6 +4043,11 @@ > case 'g': > grepable=True; > break; >+#ifdef HAVE_LIBDNS_SD >+ case 'B': >+ return(do_smb_browse()); >+#endif /* HAVE_LIBDNS_SD */ >+ > } > } > >Index: client/dnsbrowse.c >=================================================================== >--- client/dnsbrowse.c (revision 0) >+++ client/dnsbrowse.c (revision 0) >@@ -0,0 +1,214 @@ >+/* >+ Unix SMB/CIFS implementation. >+ SMB client >+ Copyright (C) Andrew Tridgell 1994-1998 >+ Copyright (C) Simo Sorce 2001-2002 >+ Copyright (C) Jelmer Vernooij 2003 >+ Copyright (C) Gerald (Jerry) Carter 2004 >+ Copyright (C) Kalim Moghul 2005 >+ >+ 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 2 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, write to the Free Software >+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. >+*/ >+ >+#include "includes.h" >+ >+#ifdef HAVE_LIBDNS_SD >+ >+/* Holds service instances found during DNS browse */ >+struct mdns_smbsrv_result >+{ >+ char *serviceName; >+ char *regType; >+ char *domain; >+ uint32_t ifIndex; >+ struct mdns_smbsrv_result *nextResult; >+}; >+ >+/* Maintains state during DNS browse */ >+struct mdns_browse_state >+{ >+ struct mdns_smbsrv_result *listhead; /* Browse result list head */ >+ int browseDone; >+ >+}; >+ >+ >+static void >+do_smb_resolve_reply (DNSServiceRef sdRef, DNSServiceFlags flags, >+ uint32_t interfaceIndex, DNSServiceErrorType errorCode, >+ const char *fullname, const char *hosttarget, uint16_t port, >+ uint16_t txtLen, const unsigned char *txtRecord, void *context) >+{ >+ printf("SMB service available on %s\n", hosttarget); >+} >+ >+ >+static void >+do_smb_resolve(struct mdns_smbsrv_result *browsesrv) >+{ >+ DNSServiceRef mdns_conn_sdref = NULL; >+ int mdnsfd; >+ int fdsetsz; >+ int ret; >+ fd_set *fdset = NULL; >+ struct timeval tv; >+ >+ if(DNSServiceResolve(&mdns_conn_sdref, NULL, browsesrv->ifIndex, >+ browsesrv->serviceName, browsesrv->regType, browsesrv->domain, >+ do_smb_resolve_reply, NULL) != kDNSServiceErr_NoError) >+ return; >+ >+ mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref); >+ for (;;) { >+ if (fdset != NULL) >+ free(fdset); >+ >+ fdsetsz = howmany(mdnsfd+1, NFDBITS) * sizeof(fd_mask); >+ fdset = (fd_set *)malloc(fdsetsz); >+ (void) memset(fdset, 0, fdsetsz); >+ FD_SET(mdnsfd, fdset); >+ >+ tv.tv_sec = 1; >+ tv.tv_usec = 0; >+ >+ /* Wait until response received from mDNS daemon */ >+ ret = select(mdnsfd+1, fdset, NULL, NULL, &tv); >+ if (ret <= 0 && errno != EINTR) >+ break; >+ >+ if (FD_ISSET(mdnsfd, fdset)) { >+ /* Invoke callback function */ >+ DNSServiceProcessResult(mdns_conn_sdref); >+ break; >+ } >+ } >+ >+ free(fdset); >+ DNSServiceRefDeallocate(mdns_conn_sdref); >+} >+ >+ >+static void >+do_smb_browse_reply(DNSServiceRef sdRef, DNSServiceFlags flags, >+ uint32_t interfaceIndex, DNSServiceErrorType errorCode, >+ const char *serviceName, const char *regtype, >+ const char *replyDomain, void *context) >+{ >+ struct mdns_browse_state *bstatep = (struct mdns_browse_state *)context; >+ struct mdns_smbsrv_result *bresult; >+ >+ if (bstatep == NULL) >+ return; >+ >+ if (errorCode != kDNSServiceErr_NoError) { >+ bstatep->browseDone = 1; >+ return; >+ } >+ >+ if (flags & kDNSServiceFlagsMoreComing) >+ bstatep->browseDone = 0; >+ else >+ bstatep->browseDone = 1; >+ >+ if (!(flags & kDNSServiceFlagsAdd)) >+ return; >+ >+ bresult = (struct mdns_smbsrv_result *)calloc(1, sizeof(struct mdns_smbsrv_result)); >+ if (bresult == NULL) >+ return; >+ >+ if (bstatep->listhead != NULL) >+ bresult->nextResult = bstatep->listhead; >+ bresult->serviceName = strdup(serviceName); >+ bresult->regType = strdup(regtype); >+ bresult->domain = strdup(replyDomain); >+ bresult->ifIndex = interfaceIndex; >+ bstatep->listhead = bresult; >+} >+ >+ >+int do_smb_browse(void) >+{ >+ int mdnsfd; >+ int fdsetsz; >+ int ret; >+ fd_set *fdset = NULL; >+ struct mdns_browse_state bstate; >+ struct mdns_smbsrv_result *resptr; >+ struct timeval tv; >+ DNSServiceRef mdns_conn_sdref = NULL; >+ >+ (void) memset(&bstate, 0, sizeof(struct mdns_browse_state)); >+ >+ if(DNSServiceBrowse(&mdns_conn_sdref, 0, 0, "_smb._tcp", "", >+ do_smb_browse_reply, &bstate) != kDNSServiceErr_NoError) >+ { >+ d_printf("Error connecting to the Multicast DNS daemon\n"); >+ return 1; >+ } >+ >+ mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref); >+ for (;;) { >+ if (fdset != NULL) >+ free(fdset); >+ >+ fdsetsz = howmany(mdnsfd+1, NFDBITS) * sizeof(fd_mask); >+ fdset = (fd_set *)malloc(fdsetsz); >+ (void) memset(fdset, 0, fdsetsz); >+ FD_SET(mdnsfd, fdset); >+ >+ tv.tv_sec = 1; >+ tv.tv_usec = 0; >+ >+ /* Wait until response received from mDNS daemon */ >+ ret = select(mdnsfd+1, fdset, NULL, NULL, &tv); >+ if (ret <= 0 && errno != EINTR) >+ break; >+ >+ if (FD_ISSET(mdnsfd, fdset)) { >+ /* Invoke callback function */ >+ if (DNSServiceProcessResult(mdns_conn_sdref)) >+ break; >+ if (bstate.browseDone) >+ break; >+ } >+ } >+ >+ free(fdset); >+ DNSServiceRefDeallocate(mdns_conn_sdref); >+ >+ if (bstate.listhead != NULL) { >+ resptr = bstate.listhead; >+ while (resptr != NULL) { >+ struct mdns_smbsrv_result *oldresptr; >+ oldresptr = resptr; >+ >+ /* Resolve smb service instance */ >+ do_smb_resolve(resptr); >+ >+ /* Free result structure */ >+ free(resptr->domain); >+ free(resptr->serviceName); >+ free(resptr->regType); >+ resptr = resptr->nextResult; >+ free(oldresptr); >+ } >+ } >+ return 0; >+} >+ >+#endif /* HAVE_LIBDNS_SD */ >+ >+
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 4510
:
2391
|
2859
|
2934