1 #include "config.h"
2 #ifdef HAVE_MDNS
3 #define _GNU_SOURCE
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include "state.h"
8 #include "service.h"
9 #include "server.h"
10 #include "sconf.h"
11 #include "pset.h"
12
13 #ifdef HAVE_DNSREGISTRATION
14 #include <DNSServiceDiscovery/DNSServiceDiscovery.h>
15 #endif
16
17 #ifdef HAVE_HOWL
18 #include <howl.h>
19 #endif
20
21 extern struct program_state ps ;
22
23 #ifdef HAVE_DNSREGISTRATION
mdns_callback(DNSServiceRegistrationReplyErrorType err,void * d)24 static void mdns_callback(DNSServiceRegistrationReplyErrorType err, void *d)
25 {
26 return;
27 }
28 #endif
29
30 #ifdef HAVE_HOWL
howl_callback(sw_discovery discovery,sw_discovery_oid oid,sw_discovery_publish_status status,sw_opaque extra)31 static sw_result howl_callback(sw_discovery discovery, sw_discovery_oid oid, sw_discovery_publish_status status, sw_opaque extra) {
32 if( debug.on ) {
33 const char *name = NULL;
34 unsigned u;
35 for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) {
36 struct service *sp;
37 struct service_config *scp;
38
39 sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
40 scp = SVC_CONF(sp);
41 if( scp->mdns_state && (*(sw_discovery_oid *)scp->mdns_state == oid) ) {
42 name = SC_ID(scp);
43 break;
44 }
45 }
46 msg(LOG_DEBUG, "howl_callback", "callback status: %d for service %s (oid: %d)", status, name, oid);
47 }
48 return SW_OKAY;
49 }
50 #endif
51
xinetd_mdns_deregister(struct service_config * scp)52 int xinetd_mdns_deregister(struct service_config *scp) {
53 if( (!scp) || (scp->mdns_state == NULL) )
54 return 0;
55
56 if( debug.on )
57 msg(LOG_DEBUG, "xinetd_mdns_deregister", "Deregistering service: %s", SC_ID(scp));
58
59 #ifdef HAVE_DNSREGISTRATION
60 DNSServiceDiscoveryDeallocate( (dns_service_discovery_ref)scp->mdns_state );
61 return 0;
62 #endif
63
64 #ifdef HAVE_HOWL
65 if( !ps.rws.mdns_state ) return 0;
66 if( sw_discovery_cancel(*(sw_discovery *)ps.rws.mdns_state, *(sw_discovery_oid *)scp->mdns_state) != SW_OKAY )
67 return -1;
68 return 0;
69 #endif
70 }
71
xinetd_mdns_register(struct service_config * scp)72 int xinetd_mdns_register(struct service_config *scp) {
73 if( ps.rws.mdns_state == NULL )
74 return -1;
75 xinetd_mdns_deregister(scp);
76
77 if( SC_MDNS_NAME(scp) )
78 free(SC_MDNS_NAME(scp));
79 if( asprintf(&SC_MDNS_NAME(scp), "_%s._%s", SC_NAME(scp), SC_PROTONAME(scp)) < 0 )
80 return -1;
81
82 if( debug.on )
83 msg(LOG_DEBUG, "xinetd_mdns_register", "Registering service: %s (%s)", SC_MDNS_NAME(scp), SC_ID(scp));
84
85 #ifdef HAVE_DNSREGISTRATION
86 scp->mdns_state = DNSServiceRegistrationCreate("", SC_MDNS_NAME(scp), "", htons(SC_PORT(scp)), "", mdns_callback, NULL);
87 #endif
88
89 #ifdef HAVE_HOWL
90 sw_discovery_publish(*(sw_discovery *)ps.rws.mdns_state, 0, SC_ID(scp), SC_MDNS_NAME(scp), NULL, NULL, SC_PORT(scp), NULL, 0, howl_callback, NULL, (sw_discovery_oid *)scp->mdns_state);
91 return 0;
92 #endif
93
94 return 0;
95 }
96
xinetd_mdns_init(void)97 int xinetd_mdns_init(void) {
98 #ifdef HAVE_DNSREGISTRATION
99 ps.rws.mdns_state = (char *)1;
100 return 0;
101 #endif
102
103 #ifdef HAVE_HOWL
104 ps.rws.mdns_state = malloc(sizeof(sw_discovery));
105 if( !ps.rws.mdns_state )
106 return -1;
107 if( sw_discovery_init(ps.rws.mdns_state) != SW_OKAY ) {
108 free(ps.rws.mdns_state);
109 ps.rws.mdns_state = NULL;
110 return -1;
111 }
112 FD_SET( sw_discovery_socket(*(sw_discovery *)ps.rws.mdns_state), &ps.rws.socket_mask ) ;
113 return 0;
114 #endif
115 }
116
xinetd_mdns_svc_init(struct service_config * scp)117 int xinetd_mdns_svc_init(struct service_config *scp) {
118 #ifdef HAVE_DNSREGISTRATION
119 // scp->mdns_state = malloc(sizeof(dns_service_discovery_ref));
120 #endif
121
122 #ifdef HAVE_HOWL
123 scp->mdns_state = malloc(sizeof(sw_discovery_oid));
124 #endif
125
126 if( !scp->mdns_state )
127 return -1;
128 return 0;
129 }
130
xinetd_mdns_svc_free(struct service_config * scp)131 int xinetd_mdns_svc_free(struct service_config *scp) {
132 #ifndef HAVE_DNSREGISTRATION
133 if(scp->mdns_state)
134 free(scp->mdns_state);
135 scp->mdns_state = NULL;
136 #endif
137 return 0;
138 }
139
xinetd_mdns_poll(void)140 int xinetd_mdns_poll(void) {
141 #ifdef HAVE_HOWL
142 if( sw_discovery_read_socket(*(sw_discovery *)ps.rws.mdns_state) == SW_OKAY )
143 return 0;
144 #endif
145 return -1;
146 }
147 #endif /* HAVE_MDNS */
148