~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/smbd/dnsregister.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
37
struct dns_reg_state {
 
38
        struct tevent_context *event_ctx;
 
39
        uint16_t port;
 
40
        DNSServiceRef srv_ref;
 
41
        struct tevent_timer *te;
 
42
        int fd;
 
43
        struct tevent_fd *fde;
 
44
};
 
45
 
 
46
static int dns_reg_state_destructor(struct dns_reg_state *dns_state)
 
47
{
 
48
        if (dns_state->srv_ref != NULL) {
 
49
                /* Close connection to the mDNS daemon */
 
50
                DNSServiceRefDeallocate(dns_state->srv_ref);
 
51
                dns_state->srv_ref = NULL;
 
52
        }
 
53
 
 
54
        /* Clear event handler */
 
55
        TALLOC_FREE(dns_state->te);
 
56
        TALLOC_FREE(dns_state->fde);
 
57
        dns_state->fd = -1;
 
58
 
 
59
        return 0;
 
60
}
 
61
 
 
62
static void dns_register_smbd_retry(struct tevent_context *ctx,
 
63
                                    struct tevent_timer *te,
 
64
                                    struct timeval now,
 
65
                                    void *private_data);
 
66
static void dns_register_smbd_fde_handler(struct tevent_context *ev,
 
67
                                          struct tevent_fd *fde,
 
68
                                          uint16_t flags,
 
69
                                          void *private_data);
 
70
 
 
71
static bool dns_register_smbd_schedule(struct dns_reg_state *dns_state,
 
72
                                       struct timeval tval)
 
73
{
 
74
        dns_reg_state_destructor(dns_state);
 
75
 
 
76
        dns_state->te = tevent_add_timer(dns_state->event_ctx,
 
77
                                         dns_state,
 
78
                                         tval,
 
79
                                         dns_register_smbd_retry,
 
80
                                         dns_state);
 
81
        if (!dns_state->te) {
 
82
                return false;
 
83
        }
 
84
 
 
85
        return true;
 
86
}
 
87
 
 
88
static void dns_register_smbd_retry(struct tevent_context *ctx,
 
89
                                    struct tevent_timer *te,
 
90
                                    struct timeval now,
 
91
                                    void *private_data)
 
92
{
 
93
        struct dns_reg_state *dns_state = talloc_get_type_abort(private_data,
 
94
                                          struct dns_reg_state);
 
95
        DNSServiceErrorType err;
 
96
 
 
97
        dns_reg_state_destructor(dns_state);
 
98
 
 
99
        DEBUG(6, ("registering _smb._tcp service on port %d\n",
 
100
                  dns_state->port));
 
101
 
 
102
        /* Register service with DNS. Connects with the mDNS
 
103
         * daemon running on the local system to perform DNS
 
104
         * service registration.
 
105
         */
 
106
        err = DNSServiceRegister(&dns_state->srv_ref, 0 /* flags */,
 
107
                        kDNSServiceInterfaceIndexAny,
 
108
                        NULL /* service name */,
 
109
                        "_smb._tcp" /* service type */,
 
110
                        NULL /* domain */,
 
111
                        "" /* SRV target host name */,
 
112
                        htons(dns_state->port),
 
113
                        0 /* TXT record len */,
 
114
                        NULL /* TXT record data */,
 
115
                        NULL /* callback func */,
 
116
                        NULL /* callback context */);
 
117
 
 
118
        if (err != kDNSServiceErr_NoError) {
 
119
                /* Failed to register service. Schedule a re-try attempt.
 
120
                 */
 
121
                DEBUG(3, ("unable to register with mDNS (err %d)\n", err));
 
122
                goto retry;
 
123
        }
 
124
 
 
125
        dns_state->fd = DNSServiceRefSockFD(dns_state->srv_ref);
 
126
        if (dns_state->fd == -1) {
 
127
                goto retry;
 
128
        }
 
129
 
 
130
        dns_state->fde = tevent_add_fd(dns_state->event_ctx,
 
131
                                       dns_state,
 
132
                                       dns_state->fd,
 
133
                                       TEVENT_FD_READ,
 
134
                                       dns_register_smbd_fde_handler,
 
135
                                       dns_state);
 
136
        if (!dns_state->fde) {
 
137
                goto retry;
 
138
        }
 
139
 
 
140
        return;
 
141
 retry:
 
142
        dns_register_smbd_schedule(dns_state,
 
143
                timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0));
 
144
}
 
145
 
 
146
/* Processes reply from mDNS daemon. Returns true if a reply was received */
 
147
static void dns_register_smbd_fde_handler(struct tevent_context *ev,
 
148
                                          struct tevent_fd *fde,
 
149
                                          uint16_t flags,
 
150
                                          void *private_data)
 
151
{
 
152
        struct dns_reg_state *dns_state = talloc_get_type_abort(private_data,
 
153
                                          struct dns_reg_state);
 
154
        DNSServiceErrorType err;
 
155
 
 
156
        err = DNSServiceProcessResult(dns_state->srv_ref);
 
157
        if (err != kDNSServiceErr_NoError) {
 
158
                DEBUG(3, ("failed to process mDNS result (err %d), re-trying\n",
 
159
                            err));
 
160
                goto retry;
 
161
        }
 
162
 
 
163
        talloc_free(dns_state);
 
164
        return;
 
165
 
 
166
 retry:
 
167
        dns_register_smbd_schedule(dns_state,
 
168
                timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0));
 
169
}
 
170
 
 
171
bool smbd_setup_mdns_registration(struct tevent_context *ev,
 
172
                                  TALLOC_CTX *mem_ctx,
 
173
                                  uint16_t port)
 
174
{
 
175
        struct dns_reg_state *dns_state;
 
176
 
 
177
        dns_state = talloc_zero(mem_ctx, struct dns_reg_state);
 
178
        if (dns_state == NULL) {
 
179
                return false;
 
180
        }
 
181
        dns_state->event_ctx = ev;
 
182
        dns_state->port = port;
 
183
        dns_state->fd = -1;
 
184
 
 
185
        talloc_set_destructor(dns_state, dns_reg_state_destructor);
 
186
 
 
187
        return dns_register_smbd_schedule(dns_state, timeval_zero());
 
188
}
 
189
 
 
190
#else /* WITH_DNSSD_SUPPORT */
 
191
 
 
192
bool smbd_setup_mdns_registration(struct tevent_context *ev,
 
193
                                  TALLOC_CTX *mem_ctx,
 
194
                                  uint16_t port)
 
195
{
 
196
        return true;
 
197
}
 
198
 
 
199
#endif /* WITH_DNSSD_SUPPORT */