summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/dnsregister.c208
-rw-r--r--source3/smbd/server.c25
2 files changed, 108 insertions, 125 deletions
diff --git a/source3/smbd/dnsregister.c b/source3/smbd/dnsregister.c
index c092251fee..2fd95f9fb7 100644
--- a/source3/smbd/dnsregister.c
+++ b/source3/smbd/dnsregister.c
@@ -35,18 +35,16 @@
#include <dns_sd.h>
struct dns_reg_state {
+ struct tevent_context *event_ctx;
+ uint16_t port;
DNSServiceRef srv_ref;
- struct timed_event *retry_handler;
+ struct tevent_timer *te;
+ int fd;
+ struct tevent_fd *fde;
};
-void dns_register_close(struct dns_reg_state **dns_state_ptr)
+static int dns_reg_state_destructor(struct dns_reg_state *dns_state)
{
- 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);
@@ -54,81 +52,52 @@ void dns_register_close(struct dns_reg_state **dns_state_ptr)
}
/* Clear event handler */
- if (dns_state->retry_handler != NULL) {
- TALLOC_FREE(dns_state->retry_handler);
- dns_state->retry_handler = NULL;
- }
+ TALLOC_FREE(dns_state->te);
+ TALLOC_FREE(dns_state->fde);
+ dns_state->fd = -1;
- talloc_free(dns_state);
- *dns_state_ptr = NULL;
+ return 0;
}
-static void dns_register_smbd_retry(struct event_context *ctx,
- struct timed_event *te,
- const struct timeval *now,
- void *private_data)
+static void dns_register_smbd_retry(struct tevent_context *ctx,
+ struct tevent_timer *te,
+ struct timeval now,
+ void *private_data);
+static void dns_register_smbd_fde_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data);
+
+static bool dns_register_smbd_schedule(struct dns_reg_state *dns_state,
+ struct timeval tval)
{
- 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_register_smbd_retry,
- dns_state);
+ dns_reg_state_destructor(dns_state);
+
+ dns_state->te = tevent_add_timer(dns_state->event_ctx,
+ dns_state,
+ tval,
+ dns_register_smbd_retry,
+ dns_state);
+ if (!dns_state->te) {
+ return false;
+ }
- dns_state->retry_handler = event;
- get_timed_events_timeout(smbd_event_context(), timeout);
+ return true;
}
-/* 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)
+static void dns_register_smbd_retry(struct tevent_context *ctx,
+ struct tevent_timer *te,
+ struct timeval now,
+ void *private_data)
{
- int mdnsd_conn_fd;
+ struct dns_reg_state *dns_state = talloc_get_type_abort(private_data,
+ struct dns_reg_state);
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;
- }
+ dns_reg_state_destructor(dns_state);
- DEBUG(6, ("registering _smb._tcp service on port %d\n", port));
+ DEBUG(6, ("registering _smb._tcp service on port %d\n",
+ dns_state->port));
/* Register service with DNS. Connects with the mDNS
* daemon running on the local system to perform DNS
@@ -140,7 +109,7 @@ void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
"_smb._tcp" /* service type */,
NULL /* domain */,
"" /* SRV target host name */,
- htons(port),
+ htons(dns_state->port),
0 /* TXT record len */,
NULL /* TXT record data */,
NULL /* callback func */,
@@ -150,62 +119,81 @@ void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
/* 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;
+ goto retry;
+ }
+
+ dns_state->fd = DNSServiceRefSockFD(dns_state->srv_ref);
+ if (dns_state->fd == -1) {
+ goto retry;
}
- mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
- FD_SET(mdnsd_conn_fd, listen_set);
- *maxfd = MAX(*maxfd, mdnsd_conn_fd);
- *timeout = timeval_zero();
+ dns_state->fde = tevent_add_fd(dns_state->event_ctx,
+ dns_state,
+ dns_state->fd,
+ TEVENT_FD_READ,
+ dns_register_smbd_fde_handler,
+ dns_state);
+ if (!dns_state->fde) {
+ goto retry;
+ }
+ return;
+ retry:
+ dns_register_smbd_schedule(dns_state,
+ timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0));
}
/* 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)
+static void dns_register_smbd_fde_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
{
- int mdnsd_conn_fd = -1;
+ struct dns_reg_state *dns_state = talloc_get_type_abort(private_data,
+ struct dns_reg_state);
+ DNSServiceErrorType err;
- if (dns_state->srv_ref == NULL) {
- return false;
+ err = DNSServiceProcessResult(dns_state->srv_ref);
+ if (err != kDNSServiceErr_NoError) {
+ DEBUG(3, ("failed to process mDNS result (err %d), re-trying\n",
+ err));
+ goto retry;
}
- mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
+ talloc_free(dns_state);
+ return;
- /* 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);
- }
+ retry:
+ dns_register_smbd_schedule(dns_state,
+ timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0));
+}
- return true;
+bool smbd_setup_mdns_registration(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ uint16_t port)
+{
+ struct dns_reg_state *dns_state;
+
+ dns_state = talloc_zero(mem_ctx, struct dns_reg_state);
+ if (dns_state == NULL) {
+ return false;
}
+ dns_state->event_ctx = ev;
+ dns_state->port = port;
+ dns_state->fd = -1;
+
+ talloc_set_destructor(dns_state, dns_reg_state_destructor);
- return false;
+ return dns_register_smbd_schedule(dns_state, timeval_zero());
}
#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)
+bool smbd_setup_mdns_registration(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ uint16_t port)
{
- return false;
+ return true;
}
#endif /* WITH_DNSSD_SUPPORT */
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index f95fa874ff..d71a04ebc1 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -309,13 +309,15 @@ static bool open_sockets_smbd(bool interactive, const char *smb_ports)
int maxfd = 0;
int i;
char *ports;
- struct dns_reg_state * dns_reg = NULL;
+ TALLOC_CTX *dns_ctx = NULL;
unsigned dns_port = 0;
#ifdef HAVE_ATEXIT
atexit(killkids);
#endif
+ dns_ctx = talloc_new(NULL);
+
/* Stop zombies */
smbd_setup_sig_chld_handler();
@@ -535,6 +537,11 @@ static bool open_sockets_smbd(bool interactive, const char *smb_ports)
MSG_SMB_INJECT_FAULT, msg_inject_fault);
#endif
+ if (dns_port != 0) {
+ smbd_setup_mdns_registration(smbd_event_context(),
+ dns_ctx, dns_port);
+ }
+
/* now accept incoming connections - forking a new process
for each incoming connection */
DEBUG(2,("waiting for a connection\n"));
@@ -554,12 +561,6 @@ static bool open_sockets_smbd(bool interactive, const char *smb_ports)
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);
@@ -580,11 +581,6 @@ static bool open_sockets_smbd(bool interactive, const char *smb_ports)
exit_server_cleanly("idle timeout");
}
- /* process pending nDNS responses */
- if (dns_register_smbd_reply(dns_reg, &r_fds, &idle_timeout)) {
- --num;
- }
-
/* check if we need to reload services */
check_reload(time(NULL));
@@ -624,6 +620,8 @@ static bool open_sockets_smbd(bool interactive, const char *smb_ports)
((child = sys_fork())==0)) {
/* Child code ... */
+ TALLOC_FREE(dns_ctx);
+
/* Stop zombies, the parent explicitly handles
* them, counting worker smbds. */
CatchChild();
@@ -632,9 +630,6 @@ static bool open_sockets_smbd(bool interactive, const char *smb_ports)
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);