build: autogenerate exports/libnetapi.syms
[Samba.git] / source / smbd / dnsregister.c
blob2319097ca564bd6371b4541c050b871c0070c7ec
1 /*
2 Unix SMB/CIFS implementation.
3 DNS-SD registration
4 Copyright (C) Rishi Srivatsavai 2007
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <includes.h>
22 /* Uses DNS service discovery (libdns_sd) to
23 * register the SMB service. SMB service is registered
24 * on ".local" domain via Multicast DNS & any
25 * other unicast DNS domains available.
27 * Users use the smbclient -B (Browse) option to
28 * browse for advertised SMB services.
31 #define DNS_REG_RETRY_INTERVAL (5*60) /* in seconds */
33 #ifdef WITH_DNSSD_SUPPORT
35 #include <dns_sd.h>
37 struct dns_reg_state {
38 DNSServiceRef srv_ref;
39 struct timed_event *retry_handler;
42 void dns_register_close(struct dns_reg_state **dns_state_ptr)
44 struct dns_reg_state *dns_state = *dns_state_ptr;
46 if (dns_state == NULL) {
47 return;
50 if (dns_state->srv_ref != NULL) {
51 /* Close connection to the mDNS daemon */
52 DNSServiceRefDeallocate(dns_state->srv_ref);
53 dns_state->srv_ref = NULL;
56 /* Clear event handler */
57 if (dns_state->retry_handler != NULL) {
58 TALLOC_FREE(dns_state->retry_handler);
59 dns_state->retry_handler = NULL;
62 talloc_free(dns_state);
63 *dns_state_ptr = NULL;
66 static void dns_register_smbd_retry(struct event_context *ctx,
67 struct timed_event *te,
68 const struct timeval *now,
69 void *private_data)
71 struct dns_reg_state *dns_state = (struct dns_reg_state *)private_data;
73 /* Clear previous registration state to force new
74 * registration attempt. Clears event handler.
76 dns_register_close(&dns_state);
79 static void schedule_dns_register_smbd_retry(struct dns_reg_state *dns_state,
80 struct timeval *timeout)
82 struct timed_event * event;
84 dns_state->srv_ref = NULL;
85 event= event_add_timed(smbd_event_context(),
86 NULL,
87 timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0),
88 "DNS registration handler",
89 dns_register_smbd_retry,
90 dns_state);
92 dns_state->retry_handler = event;
93 get_timed_events_timeout(smbd_event_context(), timeout);
96 /* Kick off a mDNS request to register the "_smb._tcp" on the specified port.
97 * We really ought to register on all the ports we are listening on. This will
98 * have to be an exercise for some-one who knows the DNS registration API a bit
99 * better.
101 void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
102 unsigned port,
103 int *maxfd,
104 fd_set *listen_set,
105 struct timeval *timeout)
107 int mdnsd_conn_fd;
108 DNSServiceErrorType err;
109 struct dns_reg_state *dns_state = *dns_state_ptr;
111 if (dns_state == NULL) {
112 *dns_state_ptr = dns_state = talloc(NULL, struct dns_reg_state);
113 if (dns_state == NULL) {
114 return;
118 /* Quit if a re-try attempt has been scheduled. */
119 if (dns_state->retry_handler != NULL) {
120 return;
123 /* If a registration is active add conn
124 * fd to select listen_set and return
126 if (dns_state->srv_ref != NULL) {
127 mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
128 FD_SET(mdnsd_conn_fd, listen_set);
129 return;
132 DEBUG(6, ("registering _smb._tcp service on port %d\n", port));
134 /* Register service with DNS. Connects with the mDNS
135 * daemon running on the local system to perform DNS
136 * service registration.
138 err = DNSServiceRegister(&dns_state->srv_ref, 0 /* flags */,
139 kDNSServiceInterfaceIndexAny,
140 NULL /* service name */,
141 "_smb._tcp" /* service type */,
142 NULL /* domain */,
143 "" /* SRV target host name */,
144 htons(port),
145 0 /* TXT record len */,
146 NULL /* TXT record data */,
147 NULL /* callback func */,
148 NULL /* callback context */);
150 if (err != kDNSServiceErr_NoError) {
151 /* Failed to register service. Schedule a re-try attempt.
153 DEBUG(3, ("unable to register with mDNS (err %d)\n", err));
154 schedule_dns_register_smbd_retry(dns_state, timeout);
155 return;
158 mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
159 FD_SET(mdnsd_conn_fd, listen_set);
160 *maxfd = MAX(*maxfd, mdnsd_conn_fd);
161 *timeout = timeval_zero();
165 /* Processes reply from mDNS daemon. Returns true if a reply was received */
166 bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
167 fd_set *lfds, struct timeval *timeout)
169 int mdnsd_conn_fd = -1;
171 if (dns_state->srv_ref == NULL) {
172 return false;
175 mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
177 /* Process reply from daemon. Handles any errors. */
178 if ((mdnsd_conn_fd != -1) && (FD_ISSET(mdnsd_conn_fd,lfds)) ) {
179 DNSServiceErrorType err;
181 err = DNSServiceProcessResult(dns_state->srv_ref);
182 if (err != kDNSServiceErr_NoError) {
183 DEBUG(3, ("failed to process mDNS result (err %d), re-trying\n",
184 err));
185 schedule_dns_register_smbd_retry(dns_state, timeout);
188 return true;
191 return false;
194 #else /* WITH_DNSSD_SUPPORT */
196 void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
197 unsigned port,
198 int *maxfd,
199 fd_set *listen_set,
200 struct timeval *timeout)
203 void dns_register_close(struct dns_reg_state ** dns_state_ptr)
206 bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
207 fd_set *lfds, struct timeval *timeout)
209 return false;
212 #endif /* WITH_DNSSD_SUPPORT */