JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv, jobject pThis, jint flags, jint ifIndex, jstring serviceName, jint rrtype, jint rrclass) { jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis); jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J"); OpContext *pContext = NULL; DNSServiceErrorType err = kDNSServiceErr_NoError; if ( contextField != 0) pContext = NewContext( pEnv, pThis, "queryAnswered", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;II[BI)V"); else err = kDNSServiceErr_BadParam; if ( pContext != NULL) { const char *servStr = SafeGetUTFChars( pEnv, serviceName); err = DNSServiceQueryRecord( &pContext->ServiceRef, flags, ifIndex, servStr, rrtype, rrclass, ServiceQueryReply, pContext); if ( err == kDNSServiceErr_NoError) { (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext); } SafeReleaseUTFChars( pEnv, serviceName, servStr); } else err = kDNSServiceErr_NoMemory; return err; }
static VALUE dnssd_service_query_record(VALUE self, VALUE _flags, VALUE _interface, VALUE _fullname, VALUE _rrtype, VALUE _rrclass) { DNSServiceRef *client; DNSServiceFlags flags; DNSServiceErrorType e; char *fullname; uint32_t interface; uint16_t rrtype; uint16_t rrclass; flags = (DNSServiceFlags)NUM2ULONG(_flags); interface = (uint32_t)NUM2ULONG(_interface); dnssd_utf8_cstr(_fullname, fullname); rrtype = NUM2UINT(_rrtype); rrclass = NUM2UINT(_rrclass); get(cDNSSDService, self, DNSServiceRef, client); e = DNSServiceQueryRecord(client, flags, interface, fullname, rrtype, rrclass, dnssd_service_query_record_reply, (void *)self); dnssd_check_error_code(e); return self; }
static void resolve_reply (DNSServiceRef client, DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t opaqueport, uint16_t txtLen, const char *txtRecord, void *context) { GMDNSUserData *ud = context; GMDNSUserData *ud2; DNSServiceErrorType err; gint i; union { guint16 s; guchar b[2]; } portu = { opaqueport }; g_return_if_fail (ud); ud->server->port = ((guint16) portu.b[0]) << 8 | portu.b[1]; ud->server->hostname = g_strdup (hosttarget); ud->server->txtvalues = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); for (i = 0; i < TXTRecordGetCount (txtLen, txtRecord); i++) { gchar key[256]; const void *txt_value; gchar *value; guint8 vallen; err = TXTRecordGetItemAtIndex (txtLen, txtRecord, i, 256, key, &vallen, &txt_value); if (err != kDNSServiceErr_NoError) { g_warning ("error parsing TXT records!"); } value = g_malloc (vallen + 1); g_strlcpy (value, txt_value, vallen + 1); g_hash_table_insert (ud->server->txtvalues, g_strdup (key), value); } ud2 = g_new0 (GMDNSUserData, 1); err = DNSServiceQueryRecord (&ud2->client, 0, kDNSServiceInterfaceIndexAny, ud->server->hostname, kDNSServiceType_A, kDNSServiceClass_IN, qr_reply, ud2); if (err != kDNSServiceErr_NoError) { g_warning ("Error from QueryRecord!"); } g_mdns_poll_add (ud->mdns, ud2, ud2->client); ud2->server = ud->server; g_mdns_user_data_destroy (ud); }
int main(int argc, char **argv) { struct dummy_struct ds; int c; int type = kDNSServiceType_ANY; int flags = 0; int ifindex = 0; memset (&ds, 0, sizeof(ds)); while ((c = getopt(argc, argv, "f:t:i:")) != -1) switch (c) { case 't': type = atoi(optarg); break; case 'i': ifindex = if_nametoindex(optarg); break; case 'f': flags = atoi(optarg); break; } if (argc <= 1) { fprintf(stderr, "Usage: %s [-f <flags>] [-i <if>] [-t <type>] <name>\n", argv[0]); exit(1); } if (DNSServiceQueryRecord(&ds.service, flags, ifindex, argv[1], type, kDNSServiceClass_IN, dummy_callback, NULL) != kDNSServiceErr_NoError) { fprintf(stderr, "Error initializing DNSServiceQueryRecord\n"); exit(1); } if (uloop_init() < 0) { fprintf(stderr, "Error in uloop_init\n"); exit(1); } ds.ufd.fd = DNSServiceRefSockFD(ds.service); printf("FD:%d\n", ds.ufd.fd); ds.ufd.cb = uloop_fd_callback; if (uloop_fd_add(&ds.ufd, ULOOP_READ) < 0) { fprintf(stderr, "Error in uloop_fd_add\n"); exit(1); } printf("Entering event loop\n"); uloop_run(); return 0; }
STDMETHODIMP CDNSSD::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IQueryRecordListener *listener, IDNSSDService **service) { CComObject<CDNSSDService> * object = NULL; DNSServiceRef sref = NULL; std::string fullNameUTF8; DNSServiceErrorType err = 0; HRESULT hr = 0; BOOL ok; // Initialize *service = NULL; // Convert BSTR params to utf8 ok = BSTRToUTF8( fullname, fullNameUTF8 ); require_action( ok, exit, err = kDNSServiceErr_BadParam ); try { object = new CComObject<CDNSSDService>(); } catch ( ... ) { object = NULL; } require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory ); hr = object->FinalConstruct(); require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown ); object->AddRef(); err = DNSServiceQueryRecord( &sref, flags, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object ); require_noerr( err, exit ); object->SetServiceRef( sref ); object->SetListener( listener ); err = object->Run(); require_noerr( err, exit ); *service = object; exit: if ( err && object ) { object->Release(); } return err; }
bool Client::query( const std::string& hostname, int port ) { m_port = port; m_qRef = 0; DNSServiceErrorType e = DNSServiceQueryRecord( &m_qRef, 0, m_interface, hostname.c_str(), kDNSServiceType_A, kDNSServiceClass_IN, &handleQueryReply, this ); if( e != kDNSServiceErr_NoError ) { // printf( "Client::query() failed\n" ); DNSServiceRefDeallocate( m_qRef ); m_qRef = 0; return false; } m_currentRef = m_qRef; return true; }
address bonjour_resolve_policy::resolve (std::string const& s) { address result; DNSServiceRef sd_ref; DNSServiceErrorType error = DNSServiceQueryRecord (&sd_ref, 0, 0, s.c_str (), kDNSServiceType_SRV, kDNSServiceClass_IN, callback, static_cast<void*> (&result) ); if (error == kDNSServiceErr_NoError) DNSServiceProcessResult (sd_ref); else result = address::from_string ("::1"); DNSServiceRefDeallocate (sd_ref); return result; }
static void FoundInstanceInfo(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t notAnIntPort, uint16_t txtLen, const char *txtRecord, void *context) { linkedServiceInfo *info = (linkedServiceInfo *)context; SearcherServices *services = info->services; (void)sdRef; // Unused (void)flags; // Unused (void)interfaceIndex; // Unused (void)errorCode; // Unused (void)fullname; // Unused strcpy(info->host, hosttarget); if (txtLen == 0) info->text[0] = 0; else { strncpy(info->text, txtRecord+1, txtRecord[0]); info->text[txtRecord[0]] = 0; } info->notAnIntPort.NotAnInteger = notAnIntPort; DNSServiceRefDeallocate(info->sdRef); DNSServiceQueryRecord(&info->sdRef, 0, 0, info->host, ns_t_a, ns_c_in, FoundInstanceAddress, info); }
DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo( DNSServiceRef * outRef, DNSServiceFlags inFlags, uint32_t inInterfaceIndex, DNSServiceProtocol inProtocol, const char * inHostName, DNSServiceGetAddrInfoReply inCallback, void * inContext ) { const char * errormsg = "Unknown"; DNSServiceErrorType err; mDNS_DirectOP_GetAddrInfo * x; // Allocate memory, and handle failure x = (mDNS_DirectOP_GetAddrInfo *)mDNSPlatformMemAllocate(sizeof(*x)); if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; } // Set up object x->disposefn = DNSServiceGetAddrInfoDispose; x->callback = inCallback; x->context = inContext; x->aQuery = mDNSNULL; // Start the query. // (It would probably be more efficient to code this using mDNS_StartQuery directly, // instead of wrapping DNSServiceQueryRecord, which then unnecessarily allocates // more memory and then just calls through to mDNS_StartQuery. -- SC June 2010) err = DNSServiceQueryRecord(&x->aQuery, inFlags, inInterfaceIndex, inHostName, kDNSServiceType_A, kDNSServiceClass_IN, DNSServiceGetAddrInfoResponse, x); if (err) { DNSServiceGetAddrInfoDispose((mDNS_DirectOP*)x); errormsg = "DNSServiceQueryRecord"; goto fail; } *outRef = (DNSServiceRef)x; return(mStatus_NoError); fail: LogMsg("DNSServiceGetAddrInfo(\"%s\", %d) failed: %s (%ld)", inHostName, inProtocol, errormsg, err); return(err); }
void DNSSD_API CSecondPage::OnResolve( DNSServiceRef inRef, DNSServiceFlags inFlags, uint32_t inInterfaceIndex, DNSServiceErrorType inErrorCode, const char * inFullName, const char * inHostName, uint16_t inPort, uint16_t inTXTSize, const char * inTXT, void * inContext ) { DEBUG_UNUSED(inFullName); DEBUG_UNUSED(inInterfaceIndex); DEBUG_UNUSED(inFlags); DEBUG_UNUSED(inRef); CSecondPage * self; Service * service; Queue * q; bool qtotalDefined = false; uint32_t qpriority = kDefaultPriority; CString qname; int idx; OSStatus err; require_noerr( inErrorCode, exit ); service = reinterpret_cast<Service*>( inContext ); require_quiet( service, exit); check( service->refs != 0 ); self = service->printer->window; require_quiet( self, exit ); err = self->StopOperation( service->serviceRef ); require_noerr( err, exit ); // // hold on to the hostname... // err = UTF8StringToStringObject( inHostName, service->hostname ); require_noerr( err, exit ); // // <rdar://problem/3739200> remove the trailing dot on hostname // idx = service->hostname.ReverseFind('.'); if ((idx > 1) && ((service->hostname.GetLength() - 1) == idx)) { service->hostname.Delete(idx, 1); } // // hold on to the port // service->portNumber = ntohs(inPort); // // parse the text record. // err = self->ParseTextRecord( service, inTXTSize, inTXT, qtotalDefined, qname, qpriority ); require_noerr( err, exit ); if ( service->qtotal == 1 ) { // // create a new queue // try { q = new Queue; } catch (...) { q = NULL; } require_action( q, exit, err = E_OUTOFMEMORY ); if ( qtotalDefined ) { q->name = qname; } q->priority = qpriority; service->queues.push_back( q ); // // we've completely resolved this service // self->OnResolveService( service ); } else { // // if qtotal is more than 1, then we need to get additional // text records. if not, then this service is considered // resolved // err = DNSServiceQueryRecord(&service->serviceRef, 0, inInterfaceIndex, inFullName, kDNSServiceType_TXT, kDNSServiceClass_IN, OnQuery, (void*) service ); require_noerr( err, exit ); err = self->StartOperation( service->serviceRef ); require_noerr( err, exit ); } exit: return; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { const char *name; /* Backend name */ cups_array_t *devices; /* Device array */ cups_device_t *device; /* Current device */ char uriName[1024]; /* Unquoted fullName for URI */ #ifdef HAVE_DNSSD int fd; /* Main file descriptor */ fd_set input; /* Input set for select() */ struct timeval timeout; /* Timeout for select() */ DNSServiceRef main_ref, /* Main service reference */ fax_ipp_ref, /* IPP fax service reference */ ipp_ref, /* IPP service reference */ ipp_tls_ref, /* IPP w/TLS service reference */ ipps_ref, /* IPP service reference */ local_fax_ipp_ref, /* Local IPP fax service reference */ local_ipp_ref, /* Local IPP service reference */ local_ipp_tls_ref, /* Local IPP w/TLS service reference */ local_ipps_ref, /* Local IPP service reference */ local_printer_ref, /* Local LPD service reference */ pdl_datastream_ref, /* AppSocket service reference */ printer_ref, /* LPD service reference */ riousbprint_ref; /* Remote IO service reference */ #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI AvahiClient *client; /* Client information */ int error; /* Error code, if any */ #endif /* HAVE_AVAHI */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ /* * Don't buffer stderr, and catch SIGTERM... */ setbuf(stderr, NULL); #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ sigset(SIGTERM, sigterm_handler); #elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); action.sa_handler = sigterm_handler; sigaction(SIGTERM, &action, NULL); #else signal(SIGTERM, sigterm_handler); #endif /* HAVE_SIGSET */ /* * Check command-line... */ if (argc >= 6) exec_backend(argv); else if (argc != 1) { _cupsLangPrintf(stderr, _("Usage: %s job-id user title copies options [file]"), argv[0]); return (1); } /* * Only do discovery when run as "dnssd"... */ if ((name = strrchr(argv[0], '/')) != NULL) name ++; else name = argv[0]; if (strcmp(name, "dnssd")) return (0); /* * Create an array to track devices... */ devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL); /* * Browse for different kinds of printers... */ #ifdef HAVE_DNSSD if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) { perror("ERROR: Unable to create service connection"); return (1); } fd = DNSServiceRefSockFD(main_ref); fax_ipp_ref = main_ref; DNSServiceBrowse(&fax_ipp_ref, kDNSServiceFlagsShareConnection, 0, "_fax-ipp._tcp", NULL, browse_callback, devices); ipp_ref = main_ref; DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, browse_callback, devices); ipp_tls_ref = main_ref; DNSServiceBrowse(&ipp_tls_ref, kDNSServiceFlagsShareConnection, 0, "_ipp-tls._tcp", NULL, browse_callback, devices); ipps_ref = main_ref; DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0, "_ipps._tcp", NULL, browse_callback, devices); local_fax_ipp_ref = main_ref; DNSServiceBrowse(&local_fax_ipp_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_fax-ipp._tcp", NULL, browse_local_callback, devices); local_ipp_ref = main_ref; DNSServiceBrowse(&local_ipp_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipp._tcp", NULL, browse_local_callback, devices); local_ipp_tls_ref = main_ref; DNSServiceBrowse(&local_ipp_tls_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipp-tls._tcp", NULL, browse_local_callback, devices); local_ipps_ref = main_ref; DNSServiceBrowse(&local_ipps_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipps._tcp", NULL, browse_local_callback, devices); local_printer_ref = main_ref; DNSServiceBrowse(&local_printer_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_printer._tcp", NULL, browse_local_callback, devices); pdl_datastream_ref = main_ref; DNSServiceBrowse(&pdl_datastream_ref, kDNSServiceFlagsShareConnection, 0, "_pdl-datastream._tcp", NULL, browse_callback, devices); printer_ref = main_ref; DNSServiceBrowse(&printer_ref, kDNSServiceFlagsShareConnection, 0, "_printer._tcp", NULL, browse_callback, devices); riousbprint_ref = main_ref; DNSServiceBrowse(&riousbprint_ref, kDNSServiceFlagsShareConnection, 0, "_riousbprint._tcp", NULL, browse_callback, devices); #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI if ((simple_poll = avahi_simple_poll_new()) == NULL) { fputs("DEBUG: Unable to create Avahi simple poll object.\n", stderr); return (0); } avahi_simple_poll_set_func(simple_poll, poll_callback, NULL); client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, simple_poll, &error); if (!client) { fputs("DEBUG: Unable to create Avahi client.\n", stderr); return (0); } browsers = 6; avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_fax-ipp._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp-tls._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_pdl-datastream._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_printer._tcp", NULL, 0, browse_callback, devices); #endif /* HAVE_AVAHI */ /* * Loop until we are killed... */ while (!job_canceled) { int announce = 0; /* Announce printers? */ #ifdef HAVE_DNSSD FD_ZERO(&input); FD_SET(fd, &input); timeout.tv_sec = 0; timeout.tv_usec = 500000; if (select(fd + 1, &input, NULL, NULL, &timeout) < 0) continue; if (FD_ISSET(fd, &input)) { /* * Process results of our browsing... */ DNSServiceProcessResult(main_ref); } else announce = 1; #elif defined(HAVE_AVAHI) got_data = 0; if ((error = avahi_simple_poll_iterate(simple_poll, 500)) > 0) { /* * We've been told to exit the loop. Perhaps the connection to * Avahi failed. */ break; } if (!got_data) announce = 1; #endif /* HAVE_DNSSD */ /* fprintf(stderr, "DEBUG: announce=%d\n", announce);*/ if (announce) { /* * Announce any devices we've found... */ #ifdef HAVE_DNSSD DNSServiceErrorType status; /* DNS query status */ #endif /* HAVE_DNSSD */ cups_device_t *best; /* Best matching device */ char device_uri[1024]; /* Device URI */ int count; /* Number of queries */ int sent; /* Number of sent */ for (device = (cups_device_t *)cupsArrayFirst(devices), best = NULL, count = 0, sent = 0; device; device = (cups_device_t *)cupsArrayNext(devices)) { if (device->sent) sent ++; if (device->ref) count ++; if (!device->ref && !device->sent) { /* * Found the device, now get the TXT record(s) for it... */ if (count < 50) { fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName); #ifdef HAVE_DNSSD device->ref = main_ref; status = DNSServiceQueryRecord(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->fullName, kDNSServiceType_TXT, kDNSServiceClass_IN, query_callback, device); if (status != kDNSServiceErr_NoError) fprintf(stderr, "ERROR: Unable to query \"%s\" for TXT records: %d\n", device->fullName, status); /* Users never see this */ else count ++; #else if ((device->ref = avahi_record_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, device->fullName, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, 0, query_callback, device)) == NULL) fprintf(stderr, "ERROR: Unable to query \"%s\" for TXT records: %s\n", device->fullName, avahi_strerror(avahi_client_errno(client))); /* Users never see this */ else count ++; #endif /* HAVE_AVAHI */ } } else if (!device->sent) { #ifdef HAVE_DNSSD /* * Got the TXT records, now report the device... */ DNSServiceRefDeallocate(device->ref); #else avahi_record_browser_free(device->ref); #endif /* HAVE_DNSSD */ device->ref = NULL; if (!best) best = device; else if (_cups_strcasecmp(best->name, device->name) || _cups_strcasecmp(best->domain, device->domain)) { unquote(uriName, best->fullName, sizeof(uriName)); if (best->uuid) httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups?uuid=%s" : "/?uuid=%s", best->uuid); else httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups" : "/"); cupsBackendReport("network", device_uri, best->make_and_model, best->name, best->device_id, NULL); best->sent = 1; best = device; sent ++; } else if (best->priority > device->priority || (best->priority == device->priority && best->type < device->type)) { best->sent = 1; best = device; sent ++; } else { device->sent = 1; sent ++; } } } if (best) { unquote(uriName, best->fullName, sizeof(uriName)); if (best->uuid) httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups?uuid=%s" : "/?uuid=%s", best->uuid); else httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups" : "/"); cupsBackendReport("network", device_uri, best->make_and_model, best->name, best->device_id, NULL); best->sent = 1; sent ++; } fprintf(stderr, "DEBUG: sent=%d, count=%d\n", sent, count); #ifdef HAVE_AVAHI if (sent == cupsArrayCount(devices) && browsers == 0) #else if (sent == cupsArrayCount(devices)) #endif /* HAVE_AVAHI */ break; } } return (CUPS_BACKEND_OK); }
static int _nss_mdns_queryrecord(const char *rrname, int rrclass, int rrtype, DNSServiceQueryRecordReply callback, struct mdns_querydata *data) { int sockfd; int flags = kDNSServiceFlagsForceMulticast; /* Multicast only */ int opinterface = kDNSServiceInterfaceIndexAny; DNSServiceErrorType err; DNSServiceRef ref = NULL; int ret; struct fd_set readfds; struct timeval tv; data->status = NSS_NOTFOUND; #ifdef DEBUG syslog(LOG_DEBUG, "nss_mdns: query called rrname:%s rrtype:%d", rrname, rrtype); #endif err = DNSServiceQueryRecord(&ref, flags, opinterface, rrname, rrtype, rrclass, callback, data); if (err != kDNSServiceErr_NoError || ref == NULL || (sockfd = DNSServiceRefSockFD(ref)) == NULL) { DNSServiceRefDeallocate(ref); data->status = NSS_UNAVAIL; return (NSS_UNAVAIL); } do { FD_ZERO(&readfds); FD_SET(sockfd, &readfds); tv.tv_sec = NSSMDNS_MAXQRYTMO; tv.tv_usec = 0; /* Wait until response received from mDNS daemon */ ret = select(sockfd + 1, &readfds, NULL, NULL, &tv); if (!((ret > 0) && FD_ISSET(sockfd, &readfds) && (DNSServiceProcessResult(ref) == kDNSServiceErr_NoError))) { data->status = NSS_NOTFOUND; if (errno != EINTR) data->qrydone = B_TRUE; } } while (data->qrydone != B_TRUE); if (data->status == NSS_SUCCESS && (data->withttlbuffer == NULL)) { nss_XbyY_args_t *argp = data->argp; if (argp->buf.result != NULL) { int stat; if (data->buffer == NULL) { data->status = NSS_NOTFOUND; DNSServiceRefDeallocate(ref); return (data->status); } stat = (*argp->str2ent)(data->buffer, strlen(data->buffer), argp->buf.result, argp->buf.buffer, argp->buf.buflen); if (stat == NSS_STR_PARSE_SUCCESS) { argp->returnval = argp->buf.result; argp->returnlen = 1; } else { data->status = NSS_NOTFOUND; if (stat == NSS_STR_PARSE_ERANGE) argp->erange = 1; } free(data->buffer); } else { argp->returnval = argp->buf.buffer; argp->returnlen = strlen(argp->buf.buffer); } data->buffer = NULL; data->buflen = 0; } if (data->status != NSS_SUCCESS) data->argp->h_errno = HOST_NOT_FOUND; DNSServiceRefDeallocate(ref); return (data->status); }
void DNSServiceResolveReplyCallback ( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context ) { (void)sdRef; (void)errorCode; (void)port; (void)txtLen; (void)txtRecord; (void)context; char interfaceName[IF_NAMESIZE]; if_indextoname( interfaceIndex, interfaceName ); printf( "Resolve: interfaceIndex [%i]=%s : %s @ %s\n", interfaceIndex, interfaceName, fullname, hosttarget ); callbackFlags = flags; #if 0 struct hostent * host = gethostbyname( hosttarget ); if ( host ) { printf( "h_name: %s\n", host->h_name ); if ( host->h_aliases ) { // this can be NULL for ( char **list = host->h_aliases ; *list ; list++ ) { printf( "h_alias: %s\n", *list ); } } printf( "h_addrtype: %i\n", host->h_addrtype ); printf( "h_length: %i\n", host->h_length ); if ( !host->h_addr_list ) { // I doubt this would ever be NULL... return; } for ( char **list = host->h_addr_list ; *list ; list++ ) { printf( "addr: %i.%i.%i.%i\n", ((byte *)*list)[0], ((byte *)*list)[1], ((byte *)*list)[2], ((byte *)*list)[3] ); } memset( &resolvedServerAddress, 0, sizeof( resolvedServerAddress ) ); resolvedServerAddress.sin_len = sizeof( resolvedServerAddress ); resolvedServerAddress.sin_family = host->h_addrtype; resolvedServerAddress.sin_port = htons( DOOM_PORT ); assert( host->h_length == 4 ); memcpy( &resolvedServerAddress.sin_addr, *host->h_addr_list, host->h_length ); gotServerAddress = true; } #else DNSServiceRef queryRef; // look up the name for this host DNSServiceErrorType err = DNSServiceQueryRecord ( &queryRef, kDNSServiceFlagsForceMulticast, interfaceIndex, hosttarget, kDNSServiceType_A, // we want the host address kDNSServiceClass_IN, DNSServiceQueryRecordReplyCallback, NULL /* may be NULL */ ); if ( err != kDNSServiceErr_NoError ) { printf( "DNSServiceQueryRecord error\n" ); } else { // block until we get a response, process it, and run the callback err = DNSServiceProcessResult( queryRef ); if ( err != kDNSServiceErr_NoError ) { printf( "DNSServiceProcessResult error\n" ); } DNSServiceRefDeallocate( queryRef ); } #endif }