xref: /aosp_15_r20/external/libcups/vcnet/dns_sd.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1 /*
2  * Dynamic wrapper for Bonjour SDK for Windows.
3  *
4  * Copyright 2018 by Apple Inc.
5  *
6  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
7  * information.
8  */
9 
10 //#include <cups/http-private.h>
11 #include <cups/thread-private.h>
12 #include "dns_sd.h"
13 
14 
15 /*
16  * Pointers for functions...
17  */
18 
19 static int		dnssd_initialized = 0;
20 static _cups_mutex_t	dnssd_mutex = _CUPS_MUTEX_INITIALIZER;
21 static DNSServiceErrorType (*dnssd_add_record)(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags, uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl);
22 static DNSServiceErrorType (*dnssd_browse)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context);
23 static DNSServiceErrorType (*dnssd_construct_full_name)(char * const fullName, const char * const service, const char * const regtype, const char * const domain);
24 static DNSServiceErrorType (*dnssd_create_connection)(DNSServiceRef *sdRef);
25 static DNSServiceErrorType (*dnssd_process_result)(DNSServiceRef sdRef);
26 static DNSServiceErrorType (*dnssd_query_record)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context);
27 static void (*dnssd_deallocate)(DNSServiceRef sdRef);
28 static int (*dnssd_sock_fd)(DNSServiceRef sdRef);
29 static DNSServiceErrorType (*dnssd_register)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen, const void *txtRecord, DNSServiceRegisterReply callBack, void *context);
30 static DNSServiceErrorType (*dnssd_remove_record)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags);
31 static DNSServiceErrorType (*dnssd_resolve)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name, const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context);
32 static DNSServiceErrorType (*dnssd_update_record)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags, uint16_t rdlen, const void *rdata, uint32_t ttl);
33 
34 static void (*dnssd_txt_create)(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer);
35 static void (*dnssd_txt_deallocate)(TXTRecordRef *txtRecord);
36 static const void *(*dnssd_txt_get_bytes_ptr)(const TXTRecordRef *txtRecord);
37 static uint16_t (*dnssd_txt_get_count)(uint16_t txtLen, const void *txtRecord);
38 static uint16_t (*dnssd_txt_get_length)(const TXTRecordRef *txtRecord);
39 static DNSServiceErrorType (*dnssd_txt_get_item_at_index)(uint16_t txtLen, const void *txtRecord, uint16_t itemIndex, uint16_t keyBufLen, char *key, uint8_t *valueLen, const void **value);
40 static const void *(*dnssd_txt_get_value_ptr)(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen);
41 static DNSServiceErrorType (*dnssd_txt_set_value)(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value);
42 
43 
44 /*
45  * Function to initialize pointers...
46  */
47 
48 static void
dnssd_init(void)49 dnssd_init(void)
50 {
51   _cupsMutexLock(&dnssd_mutex);
52   if (!dnssd_initialized)
53   {
54     HINSTANCE	dll_handle = LoadLibraryA("dnssd.dll");
55 
56     if (dll_handle)
57     {
58       dnssd_add_record          = (DNSServiceErrorType (*)(DNSServiceRef, DNSRecordRef *, DNSServiceFlags, uint16_t, uint16_t, const void *, uint32_t))GetProcAddress(dll_handle, "DNSServiceAddRecord");
59       dnssd_browse              = (DNSServiceErrorType(*)(DNSServiceRef *, DNSServiceFlags, uint32_t, const char *, const char *, DNSServiceBrowseReply, void *))GetProcAddress(dll_handle, "DNSServiceBrowse");
60       dnssd_construct_full_name = (DNSServiceErrorType(*)(char * const, const char * const, const char * const, const char * const))GetProcAddress(dll_handle, "DNSServiceConstructFullName");
61       dnssd_create_connection   = (DNSServiceErrorType(*)(DNSServiceRef *))GetProcAddress(dll_handle, "DNSServiceCreateConnection");
62       dnssd_deallocate          = (DNSServiceErrorType(*)(DNSServiceRef))GetProcAddress(dll_handle, "DNSServiceRefDeallocate");
63       dnssd_process_result      = (DNSServiceErrorType(*)(DNSServiceRef))GetProcAddress(dll_handle, "DNSServiceProcessResult");
64       dnssd_query_record        = (DNSServiceErrorType(*)(DNSServiceRef *, DNSServiceFlags, uint32_t, const char *, uint16_t, uint16_t, DNSServiceQueryRecordReply, void *))GetProcAddress(dll_handle, "DNSServiceQueryRecord");
65       dnssd_register            = (DNSServiceErrorType(*)(DNSServiceRef *, DNSServiceFlags, uint32_t, const char *, const char *, const char *, const char *, uint16_t, uint16_t, const void *, DNSServiceRegisterReply, void *))GetProcAddress(dll_handle, "DNSServiceRegister");
66       dnssd_remove_record       = (DNSServiceErrorType(*)(DNSServiceRef, DNSRecordRef, DNSServiceFlags))GetProcAddress(dll_handle, "DNSServiceRemoveRecord");
67       dnssd_resolve             = (DNSServiceErrorType(*)(DNSServiceRef *, DNSServiceFlags, uint32_t, const char *, const char *, const char *, DNSServiceResolveReply, void *))GetProcAddress(dll_handle, "DNSServiceResolve");
68       dnssd_sock_fd             = (int(*)(DNSServiceRef))GetProcAddress(dll_handle, "DNSServiceRefSockFD");
69       dnssd_update_record       = (DNSServiceErrorType(*)(DNSServiceRef, DNSRecordRef, DNSServiceFlags, uint16_t, const void *, uint32_t))GetProcAddress(dll_handle, "DNSServiceUpdateRecord");
70 
71       dnssd_txt_create          = (void (*)(TXTRecordRef *, uint16_t, void *))GetProcAddress(dll_handle, "TXTRecordCreate");
72       dnssd_txt_deallocate      = (void (*)(TXTRecordRef *))GetProcAddress(dll_handle, "TXTRecordDeallocate");
73       dnssd_txt_get_bytes_ptr   = (const void *(*)(const TXTRecordRef *))GetProcAddress(dll_handle, "TXTRecordGetBytesPtr");
74       dnssd_txt_get_count       = (uint16_t (*)(uint16_t, const void *))GetProcAddress(dll_handle, "TXTRecordGetCount");
75       dnssd_txt_get_item_at_index = (DNSServiceErrorType (*)(uint16_t, const void *, uint16_t, uint16_t, char *, uint8_t *, const void **))GetProcAddress(dll_handle, "TXTRecordGetItemAtIndex");
76       dnssd_txt_get_length      = (uint16_t (*)(const TXTRecordRef *))GetProcAddress(dll_handle, "TXTRecordGetLength");
77       dnssd_txt_get_value_ptr   = (const void *(*)(uint16_t, const void *, const char *, uint8_t *))GetProcAddress(dll_handle, "TXTRecordGetValuePtr");
78       dnssd_txt_set_value       = (DNSServiceErrorType (*)(TXTRecordRef *, const char *, uint8_t, const void *))GetProcAddress(dll_handle, "TXTRecordSetValue");
79     }
80 
81     dnssd_initialized = 1;
82   }
83   _cupsMutexUnlock(&dnssd_mutex);
84 }
85 
86 
87 // DNSServiceAddRecord
DNSServiceAddRecord(DNSServiceRef sdRef,DNSRecordRef * RecordRef,DNSServiceFlags flags,uint16_t rrtype,uint16_t rdlen,const void * rdata,uint32_t ttl)88 DNSServiceErrorType DNSSD_API DNSServiceAddRecord
89     (
90     DNSServiceRef                       sdRef,
91     DNSRecordRef                        *RecordRef,
92     DNSServiceFlags                     flags,
93     uint16_t                            rrtype,
94     uint16_t                            rdlen,
95     const void                          *rdata,
96     uint32_t                            ttl
97     )
98 {
99   if (!dnssd_initialized)
100     dnssd_init();
101 
102   if (dnssd_add_record)
103     return (*dnssd_add_record)(sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl);
104   else
105     return (kDNSServiceErr_ServiceNotRunning);
106 }
107 
108 
109 // DNSServiceBrowse
DNSServiceBrowse(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * regtype,const char * domain,DNSServiceBrowseReply callBack,void * context)110 DNSServiceErrorType DNSSD_API DNSServiceBrowse
111     (
112     DNSServiceRef                       *sdRef,
113     DNSServiceFlags                     flags,
114     uint32_t                            interfaceIndex,
115     const char                          *regtype,
116     const char                          *domain,    /* may be NULL */
117     DNSServiceBrowseReply               callBack,
118     void                                *context    /* may be NULL */
119     )
120 {
121   if (!dnssd_initialized)
122     dnssd_init();
123 
124   if (dnssd_browse)
125     return (*dnssd_browse)(sdRef, flags, interfaceIndex, regtype, domain, callBack, context);
126   else
127     return (kDNSServiceErr_ServiceNotRunning);
128 }
129 
130 
131 // DNSServiceConstructFullName
DNSServiceConstructFullName(char * const fullName,const char * const service,const char * const regtype,const char * const domain)132 DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
133     (
134     char                            * const fullName,
135     const char                      * const service,      /* may be NULL */
136     const char                      * const regtype,
137     const char                      * const domain
138     )
139 {
140   if (!dnssd_initialized)
141     dnssd_init();
142 
143   if (dnssd_construct_full_name)
144     return (*dnssd_construct_full_name)(fullName, service, regtype, domain);
145   else
146     return (-1);
147 }
148 
149 
150 // DNSServiceCreateConnection
DNSServiceCreateConnection(DNSServiceRef * sdRef)151 DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
152 {
153   if (!dnssd_initialized)
154     dnssd_init();
155 
156   if (dnssd_create_connection)
157     return (*dnssd_create_connection)(sdRef);
158   else
159     return (kDNSServiceErr_ServiceNotRunning);
160 }
161 
162 
163 // DNSServiceProcessResult
DNSServiceProcessResult(DNSServiceRef sdRef)164 DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef)
165 {
166   if (!dnssd_initialized)
167     dnssd_init();
168 
169   if (dnssd_process_result)
170     return (*dnssd_process_result)(sdRef);
171   else
172     return (kDNSServiceErr_ServiceNotRunning);
173 }
174 
175 
176 // DNSServiceQueryRecord
DNSServiceQueryRecord(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * fullname,uint16_t rrtype,uint16_t rrclass,DNSServiceQueryRecordReply callBack,void * context)177 DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
178     (
179     DNSServiceRef                       *sdRef,
180     DNSServiceFlags                     flags,
181     uint32_t                            interfaceIndex,
182     const char                          *fullname,
183     uint16_t                            rrtype,
184     uint16_t                            rrclass,
185     DNSServiceQueryRecordReply          callBack,
186     void                                *context  /* may be NULL */
187     )
188 {
189   if (!dnssd_initialized)
190     dnssd_init();
191 
192   if (dnssd_query_record)
193     return (*dnssd_query_record)(sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context);
194   else
195     return (kDNSServiceErr_ServiceNotRunning);
196 }
197 
198 
199 // DNSServiceRefDeallocate
DNSServiceRefDeallocate(DNSServiceRef sdRef)200 void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
201 {
202   if (!dnssd_initialized)
203     dnssd_init();
204 
205   if (dnssd_deallocate)
206     (*dnssd_deallocate)(sdRef);
207 }
208 
209 
210 // DNSServiceRefSockFD
DNSServiceRefSockFD(DNSServiceRef sdRef)211 int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
212 {
213   if (!dnssd_initialized)
214     dnssd_init();
215 
216   if (dnssd_sock_fd)
217     return (*dnssd_sock_fd)(sdRef);
218   else
219     return (kDNSServiceErr_ServiceNotRunning);
220 }
221 
222 
223 // DNSServiceRegister
DNSServiceRegister(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * name,const char * regtype,const char * domain,const char * host,uint16_t port,uint16_t txtLen,const void * txtRecord,DNSServiceRegisterReply callBack,void * context)224 DNSServiceErrorType DNSSD_API DNSServiceRegister
225     (
226     DNSServiceRef                       *sdRef,
227     DNSServiceFlags                     flags,
228     uint32_t                            interfaceIndex,
229     const char                          *name,         /* may be NULL */
230     const char                          *regtype,
231     const char                          *domain,       /* may be NULL */
232     const char                          *host,         /* may be NULL */
233     uint16_t                            port,          /* In network byte order */
234     uint16_t                            txtLen,
235     const void                          *txtRecord,    /* may be NULL */
236     DNSServiceRegisterReply             callBack,      /* may be NULL */
237     void                                *context       /* may be NULL */
238     )
239 {
240   if (!dnssd_initialized)
241     dnssd_init();
242 
243   if (dnssd_register)
244     return (*dnssd_register)(sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context);
245   else
246     return (kDNSServiceErr_ServiceNotRunning);
247 }
248 
249 
250 // DNSServiceRemoveRecord
DNSServiceRemoveRecord(DNSServiceRef sdRef,DNSRecordRef RecordRef,DNSServiceFlags flags)251 DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
252     (
253     DNSServiceRef                 sdRef,
254     DNSRecordRef                  RecordRef,
255     DNSServiceFlags               flags
256     )
257 {
258   if (!dnssd_initialized)
259     dnssd_init();
260 
261   if (dnssd_remove_record)
262     return (*dnssd_remove_record)(sdRef, RecordRef, flags);
263   else
264     return (kDNSServiceErr_ServiceNotRunning);
265 }
266 
267 
268 // DNSServiceResolve
DNSServiceResolve(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * name,const char * regtype,const char * domain,DNSServiceResolveReply callBack,void * context)269 DNSServiceErrorType DNSSD_API DNSServiceResolve
270     (
271     DNSServiceRef                       *sdRef,
272     DNSServiceFlags                     flags,
273     uint32_t                            interfaceIndex,
274     const char                          *name,
275     const char                          *regtype,
276     const char                          *domain,
277     DNSServiceResolveReply              callBack,
278     void                                *context  /* may be NULL */
279     )
280 {
281   if (!dnssd_initialized)
282     dnssd_init();
283 
284   if (dnssd_resolve)
285     return (*dnssd_resolve)(sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context);
286   else
287     return (kDNSServiceErr_ServiceNotRunning);
288 }
289 
290 
291 // DNSServiceUpdateRecord
DNSServiceUpdateRecord(DNSServiceRef sdRef,DNSRecordRef RecordRef,DNSServiceFlags flags,uint16_t rdlen,const void * rdata,uint32_t ttl)292 DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
293     (
294     DNSServiceRef                       sdRef,
295     DNSRecordRef                        RecordRef,     /* may be NULL */
296     DNSServiceFlags                     flags,
297     uint16_t                            rdlen,
298     const void                          *rdata,
299     uint32_t                            ttl
300     )
301 {
302   if (!dnssd_initialized)
303     dnssd_init();
304 
305   if (dnssd_update_record)
306     return (*dnssd_update_record)(sdRef, RecordRef, flags, rdlen, rdata, ttl);
307   else
308     return (kDNSServiceErr_ServiceNotRunning);
309 }
310 
311 
312 // TXTRecordCreate
313 void DNSSD_API
TXTRecordCreate(TXTRecordRef * txtRecord,uint16_t bufferLen,void * buffer)314 TXTRecordCreate(
315     TXTRecordRef     *txtRecord,
316     uint16_t         bufferLen,
317     void             *buffer)
318 {
319   if (!dnssd_initialized)
320     dnssd_init();
321 
322   if (dnssd_txt_create)
323     (*dnssd_txt_create)(txtRecord, bufferLen, buffer);
324 }
325 
326 
327 // TXTRecordDeallocate
TXTRecordDeallocate(TXTRecordRef * txtRecord)328 void DNSSD_API TXTRecordDeallocate
329     (
330     TXTRecordRef     *txtRecord
331     )
332 {
333   if (!dnssd_initialized)
334     dnssd_init();
335 
336   if (dnssd_txt_deallocate)
337     (*dnssd_txt_deallocate)(txtRecord);
338 }
339 
340 
341 // TXTRecordGetBytesPtr
TXTRecordGetBytesPtr(const TXTRecordRef * txtRecord)342 const void * DNSSD_API TXTRecordGetBytesPtr
343     (
344     const TXTRecordRef *txtRecord
345     )
346 {
347   if (!dnssd_initialized)
348     dnssd_init();
349 
350   if (dnssd_txt_get_bytes_ptr)
351     return (*dnssd_txt_get_bytes_ptr)(txtRecord);
352   else
353     return (NULL);
354 }
355 
356 
357 // TXTRecordGetLength
TXTRecordGetLength(const TXTRecordRef * txtRecord)358 uint16_t DNSSD_API TXTRecordGetLength
359     (
360     const TXTRecordRef *txtRecord
361     )
362 {
363   if (!dnssd_initialized)
364     dnssd_init();
365 
366   if (dnssd_txt_get_length)
367     return (*dnssd_txt_get_length)(txtRecord);
368   else
369     return (0);
370 }
371 
372 
373 // TXTRecordSetValue
TXTRecordSetValue(TXTRecordRef * txtRecord,const char * key,uint8_t valueSize,const void * value)374 DNSServiceErrorType DNSSD_API TXTRecordSetValue
375     (
376     TXTRecordRef     *txtRecord,
377     const char       *key,
378     uint8_t          valueSize,        /* may be zero */
379     const void       *value            /* may be NULL */
380     )
381 {
382   if (!dnssd_initialized)
383     dnssd_init();
384 
385   if (dnssd_txt_set_value)
386     return (*dnssd_txt_set_value)(txtRecord, key, valueSize, value);
387   else
388     return (-1);
389 }
390 
391 
392 // TXTRecordGetCount
393 uint16_t DNSSD_API
TXTRecordGetCount(uint16_t txtLen,const void * txtRecord)394 TXTRecordGetCount(
395     uint16_t         txtLen,
396     const void       *txtRecord)
397 {
398   if (!dnssd_initialized)
399     dnssd_init();
400 
401   if (dnssd_txt_get_count)
402     return (*dnssd_txt_get_count)(txtLen, txtRecord);
403   else
404     return (0);
405 }
406 
407 
408 // TXTRecordGetItemAtIndex
409 DNSServiceErrorType DNSSD_API
TXTRecordGetItemAtIndex(uint16_t txtLen,const void * txtRecord,uint16_t itemIndex,uint16_t keyBufLen,char * key,uint8_t * valueLen,const void ** value)410 TXTRecordGetItemAtIndex(
411     uint16_t         txtLen,
412     const void       *txtRecord,
413     uint16_t         itemIndex,
414     uint16_t         keyBufLen,
415     char             *key,
416     uint8_t          *valueLen,
417     const void       **value)
418 {
419   if (!dnssd_initialized)
420     dnssd_init();
421 
422   if (dnssd_txt_get_item_at_index)
423     return (*dnssd_txt_get_item_at_index)(txtLen, txtRecord, itemIndex, keyBufLen, key, valueLen, value);
424   else
425     return (-1);
426 }
427 
428 
429 // TXTRecordGetValuePtr
430 const void * DNSSD_API
TXTRecordGetValuePtr(uint16_t txtLen,const void * txtRecord,const char * key,uint8_t * valueLen)431 TXTRecordGetValuePtr(
432     uint16_t         txtLen,
433     const void       *txtRecord,
434     const char       *key,
435     uint8_t          *valueLen)
436 {
437   if (!dnssd_initialized)
438     dnssd_init();
439 
440   if (dnssd_txt_get_value_ptr)
441     return (*dnssd_txt_get_value_ptr)(txtLen, txtRecord, key, valueLen);
442   else
443     return (NULL);
444 }
445