source: branches/samba-3.3.x/source/smbd/dnsregister.c@ 221

Last change on this file since 221 was 221, checked in by Herwig Bauernfeind, 16 years ago

Update Samba 3.3 to 3.3.1

File size: 5.8 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 DNS-SD registration
4 Copyright (C) Rishi Srivatsavai 2007
5
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.
10
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.
15
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/>.
18*/
19
20#include <includes.h>
21
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.
26 *
27 * Users use the smbclient -B (Browse) option to
28 * browse for advertised SMB services.
29 */
30
31#define DNS_REG_RETRY_INTERVAL (5*60) /* in seconds */
32
33#ifdef WITH_DNSSD_SUPPORT
34
35#include <dns_sd.h>
36
37struct dns_reg_state {
38 DNSServiceRef srv_ref;
39 struct timed_event *retry_handler;
40};
41
42void dns_register_close(struct dns_reg_state **dns_state_ptr)
43{
44 struct dns_reg_state *dns_state = *dns_state_ptr;
45
46 if (dns_state == NULL) {
47 return;
48 }
49
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;
54 }
55
56 /* Clear event handler */
57 if (dns_state->retry_handler != NULL) {
58 TALLOC_FREE(dns_state->retry_handler);
59 dns_state->retry_handler = NULL;
60 }
61
62 talloc_free(dns_state);
63 *dns_state_ptr = NULL;
64}
65
66static void dns_register_smbd_retry(struct event_context *ctx,
67 struct timed_event *te,
68 struct timeval now,
69 void *private_data)
70{
71 struct dns_reg_state *dns_state = (struct dns_reg_state *)private_data;
72
73 /* Clear previous registration state to force new
74 * registration attempt. Clears event handler.
75 */
76 dns_register_close(&dns_state);
77}
78
79static void schedule_dns_register_smbd_retry(struct dns_reg_state *dns_state,
80 struct timeval *timeout)
81{
82 struct timed_event * event;
83
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_register_smbd_retry,
89 dns_state);
90
91 dns_state->retry_handler = event;
92 get_timed_events_timeout(smbd_event_context(), timeout);
93}
94
95/* Kick off a mDNS request to register the "_smb._tcp" on the specified port.
96 * We really ought to register on all the ports we are listening on. This will
97 * have to be an exercise for some-one who knows the DNS registration API a bit
98 * better.
99 */
100void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
101 unsigned port,
102 int *maxfd,
103 fd_set *listen_set,
104 struct timeval *timeout)
105{
106 int mdnsd_conn_fd;
107 DNSServiceErrorType err;
108 struct dns_reg_state *dns_state = *dns_state_ptr;
109
110 if (dns_state == NULL) {
111 *dns_state_ptr = dns_state = talloc(NULL, struct dns_reg_state);
112 if (dns_state == NULL) {
113 return;
114 }
115 }
116
117 /* Quit if a re-try attempt has been scheduled. */
118 if (dns_state->retry_handler != NULL) {
119 return;
120 }
121
122 /* If a registration is active add conn
123 * fd to select listen_set and return
124 */
125 if (dns_state->srv_ref != NULL) {
126 mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
127 FD_SET(mdnsd_conn_fd, listen_set);
128 return;
129 }
130
131 DEBUG(6, ("registering _smb._tcp service on port %d\n", port));
132
133 /* Register service with DNS. Connects with the mDNS
134 * daemon running on the local system to perform DNS
135 * service registration.
136 */
137 err = DNSServiceRegister(&dns_state->srv_ref, 0 /* flags */,
138 kDNSServiceInterfaceIndexAny,
139 NULL /* service name */,
140 "_smb._tcp" /* service type */,
141 NULL /* domain */,
142 "" /* SRV target host name */,
143 htons(port),
144 0 /* TXT record len */,
145 NULL /* TXT record data */,
146 NULL /* callback func */,
147 NULL /* callback context */);
148
149 if (err != kDNSServiceErr_NoError) {
150 /* Failed to register service. Schedule a re-try attempt.
151 */
152 DEBUG(3, ("unable to register with mDNS (err %d)\n", err));
153 schedule_dns_register_smbd_retry(dns_state, timeout);
154 return;
155 }
156
157 mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
158 FD_SET(mdnsd_conn_fd, listen_set);
159 *maxfd = MAX(*maxfd, mdnsd_conn_fd);
160 *timeout = timeval_zero();
161
162}
163
164/* Processes reply from mDNS daemon. Returns true if a reply was received */
165bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
166 fd_set *lfds, struct timeval *timeout)
167{
168 int mdnsd_conn_fd = -1;
169
170 if (dns_state->srv_ref == NULL) {
171 return false;
172 }
173
174 mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
175
176 /* Process reply from daemon. Handles any errors. */
177 if ((mdnsd_conn_fd != -1) && (FD_ISSET(mdnsd_conn_fd,lfds)) ) {
178 DNSServiceErrorType err;
179
180 err = DNSServiceProcessResult(dns_state->srv_ref);
181 if (err != kDNSServiceErr_NoError) {
182 DEBUG(3, ("failed to process mDNS result (err %d), re-trying\n",
183 err));
184 schedule_dns_register_smbd_retry(dns_state, timeout);
185 }
186
187 return true;
188 }
189
190 return false;
191}
192
193#else /* WITH_DNSSD_SUPPORT */
194
195 void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
196 unsigned port,
197 int *maxfd,
198 fd_set *listen_set,
199 struct timeval *timeout)
200{}
201
202 void dns_register_close(struct dns_reg_state ** dns_state_ptr)
203{}
204
205 bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
206 fd_set *lfds, struct timeval *timeout)
207{
208 return false;
209}
210
211#endif /* WITH_DNSSD_SUPPORT */
Note: See TracBrowser for help on using the repository browser.