error_t nbnsResolve(NetInterface *interface, const char_t *name, IpAddr *ipAddr) { error_t error; DnsCacheEntry *entry; #if (NET_RTOS_SUPPORT == ENABLED) systime_t delay; //Debug message TRACE_INFO("Resolving host name %s (NBNS resolver)...\r\n", name); #endif //Acquire exclusive access to the DNS cache osAcquireMutex(&dnsCacheMutex); //Search the DNS cache for the specified host name entry = dnsFindEntry(interface, name, HOST_TYPE_IPV4, HOST_NAME_RESOLVER_NBNS); //Check whether a matching entry has been found if(entry) { //Host name already resolved? if(entry->state == DNS_STATE_RESOLVED || entry->state == DNS_STATE_PERMANENT) { //Return the corresponding IP address *ipAddr = entry->ipAddr; //Successful host name resolution error = NO_ERROR; } else { //Host name resolution is in progress... error = ERROR_IN_PROGRESS; } } else { //If no entry exists, then create a new one entry = dnsCreateEntry(); //Record the host name whose IP address is unknown strcpy(entry->name, name); //Initialize DNS cache entry entry->type = HOST_TYPE_IPV4; entry->protocol = HOST_NAME_RESOLVER_NBNS; entry->interface = interface; //Initialize retransmission counter entry->retransmitCount = NBNS_CLIENT_MAX_RETRIES; //Send NBNS query error = nbnsSendQuery(entry); //NBNS message successfully sent? if(!error) { //Save the time at which the query message was sent entry->timestamp = osGetSystemTime(); //Set timeout value entry->timeout = NBNS_CLIENT_INIT_TIMEOUT; entry->maxTimeout = NBNS_CLIENT_MAX_TIMEOUT; //Decrement retransmission counter entry->retransmitCount--; //Switch state entry->state = DNS_STATE_IN_PROGRESS; //Host name resolution is in progress error = ERROR_IN_PROGRESS; } } //Release exclusive access to the DNS cache osReleaseMutex(&dnsCacheMutex); #if (NET_RTOS_SUPPORT == ENABLED) //Set default polling interval delay = DNS_CACHE_INIT_POLLING_INTERVAL; //Wait the host name resolution to complete while(error == ERROR_IN_PROGRESS) { //Wait until the next polling period osDelayTask(delay); //Acquire exclusive access to the DNS cache osAcquireMutex(&dnsCacheMutex); //Search the DNS cache for the specified host name entry = dnsFindEntry(interface, name, HOST_TYPE_IPV4, HOST_NAME_RESOLVER_NBNS); //Check whether a matching entry has been found if(entry) { //Host name successfully resolved? if(entry->state == DNS_STATE_RESOLVED) { //Return the corresponding IP address *ipAddr = entry->ipAddr; //Successful host name resolution error = NO_ERROR; } } else { //Host name resolution failed error = ERROR_FAILURE; } //Release exclusive access to the DNS cache osReleaseMutex(&dnsCacheMutex); //Backoff support for less aggressive polling delay = MIN(delay * 2, DNS_CACHE_MAX_POLLING_INTERVAL); } //Check status code if(error) { //Failed to resolve host name TRACE_INFO("Host name resolution failed!\r\n"); } else { //Successful host name resolution TRACE_INFO("Host name resolved to %s...\r\n", ipAddrToString(ipAddr, NULL)); } #endif //Return status code return error; }
error_t dnsResolve(NetInterface *interface, const char_t *name, HostType type, IpAddr *ipAddr) { error_t error; systime_t delay; DnsCacheEntry *entry; //Debug message TRACE_INFO("Resolving host name %s (DNS resolver)...\r\n", name); //Acquire exclusive access to the DNS cache osMutexAcquire(dnsCacheMutex); //Search the DNS cache for the specified host name entry = dnsFindEntry(interface, name, type, HOST_NAME_RESOLVER_DNS); //Check whether a matching entry has been found if(entry) { //Host name already resolved? if(entry->state == DNS_STATE_RESOLVED || entry->state == DNS_STATE_PERMANENT) { //Return the corresponding IP address *ipAddr = entry->ipAddr; //Successful host name resolution error = NO_ERROR; } else { //Host name resolution is in progress... error = ERROR_IN_PROGRESS; } } else { //If no entry exists, then create a new one entry = dnsCreateEntry(); //Record the host name whose IP address is unknown strcpy(entry->name, name); //Initialize DNS cache entry entry->type = type; entry->protocol = HOST_NAME_RESOLVER_DNS; entry->interface = interface; //Select primary DNS server entry->dnsServerNum = 0; //Get an ephemeral port number entry->port = socketGetEphemeralPort(); //An identifier is used by the DNS client to match replies //with corresponding requests entry->id = tcpIpStackGetRand(); //Callback function to be called when a DNS response is received error = udpAttachRxCallback(interface, entry->port, dnsProcessResponse, NULL); //Check status code if(!error) { //Initialize retransmission counter entry->retransmitCount = DNS_CLIENT_MAX_RETRIES; //Send DNS query error = dnsSendQuery(entry); //DNS message successfully sent? if(!error) { //Save the time at which the query message was sent entry->timestamp = osGetTickCount(); //Set timeout value entry->timeout = DNS_CLIENT_INIT_TIMEOUT; entry->maxTimeout = DNS_CLIENT_MAX_TIMEOUT; //Decrement retransmission counter entry->retransmitCount--; //Switch state entry->state = DNS_STATE_IN_PROGRESS; //Host name resolution is in progress error = ERROR_IN_PROGRESS; } else { //Unregister callback function udpDetachRxCallback(interface, entry->port); } } } //Release exclusive access to the DNS cache osMutexRelease(dnsCacheMutex); //Set default polling interval delay = DNS_CACHE_INIT_POLLING_INTERVAL; //Wait the host name resolution to complete while(error == ERROR_IN_PROGRESS) { //Wait until the next polling period osDelay(delay); //Acquire exclusive access to the DNS cache osMutexAcquire(dnsCacheMutex); //Search the DNS cache for the specified host name entry = dnsFindEntry(interface, name, type, HOST_NAME_RESOLVER_DNS); //Check whether a matching entry has been found if(entry) { //Host name successfully resolved? if(entry->state == DNS_STATE_RESOLVED) { //Return the corresponding IP address *ipAddr = entry->ipAddr; //Successful host name resolution error = NO_ERROR; } } else { //Host name resolution failed error = ERROR_FAILURE; } //Release exclusive access to the DNS cache osMutexRelease(dnsCacheMutex); //Backoff support for less aggressive polling delay = min(delay * 2, DNS_CACHE_MAX_POLLING_INTERVAL); } //Check status code if(error) { //Failed to resolve host name TRACE_INFO("Host name resolution failed!\r\n"); } else { //Successful host name resolution TRACE_INFO("Host name resolved to %s...\r\n", ipAddrToString(ipAddr, NULL)); } //Return status code return error; }