/* Initialise the resolver. Open a socket and bind it to the address of the server. return -1 if something goes wrong, otherwise 0. If we are being called a second time we have to be careful to allow any ongoing lookups to finish before we close the socket and connect to a different DNS server. The danger here is that we may have to wait for upto 32 seconds if the DNS server is down. */ int cyg_dns_res_init(struct in_addr *dns_server) { struct sockaddr_in server; struct servent *sent; static int init =0; CYG_REPORT_FUNCNAMETYPE( "cyg_dns_res_init", "returning %d" ); CYG_REPORT_FUNCARG1( "dns_server=%08x", dns_server ); CYG_CHECK_DATA_PTR( dns_server, "dns_server is not a valid pointer!" ); if (init) { cyg_drv_mutex_lock(&dns_mutex); cyg_thread_free_data_index(ptdindex); if (s >= 0) { close(s); } } else { init = 1; cyg_drv_mutex_init(&dns_mutex); cyg_drv_mutex_lock(&dns_mutex); } s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { cyg_drv_mutex_unlock(&dns_mutex); CYG_REPORT_RETVAL( -1 ); return -1; } sent = getservbyname("domain", "udp"); if (sent == (struct servent *)0) { s = -1; cyg_drv_mutex_unlock(&dns_mutex); CYG_REPORT_RETVAL( -1 ); return -1; } memcpy((char *)&server.sin_addr, (const void *)dns_server, sizeof(server.sin_addr)); server.sin_port = sent->s_port; server.sin_family = AF_INET; server.sin_len = sizeof(server); if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0) { s = -1; cyg_drv_mutex_unlock(&dns_mutex); CYG_REPORT_RETVAL( -1 ); return -1; } ptdindex = cyg_thread_new_data_index(); cyg_drv_mutex_unlock(&dns_mutex); CYG_REPORT_RETVAL( 0 ); return 0; }
int matherr( struct exception *x ) { CYG_REPORT_FUNCNAMETYPE( "matherr", "returning %d" ); CYG_UNUSED_PARAM( struct exception *, x ); CYG_EMPTY_STATEMENT; CYG_REPORT_RETVAL( 0 ); return 0; } // matherr()
/* Send the query to the server and read the response back. Return -1 if it fails, otherwise put the response back in msg and return the length of the response. */ static int send_recv(char * msg, int len, int msglen) { struct dns_header *dns_hdr; struct timeval timeout; int finished = false; int backoff = 2; fd_set readfds; int written; int ret; CYG_REPORT_FUNCNAMETYPE( "send_recv", "returning %d" ); CYG_REPORT_FUNCARG3( "msg=%08x, len=%d, msglen", msg, len, msglen ); CYG_CHECK_DATA_PTR( msg, "msg is not a valid pointer!" ); dns_hdr = (struct dns_header *) msg; do { written = write(s, msg, len); if (written < 0 || (written!=len)) { ret = -1; break; } FD_ZERO(&readfds); FD_SET(s, &readfds); timeout.tv_sec = backoff; timeout.tv_usec = 0; backoff = backoff << 1; ret = select(s+1, &readfds, NULL, NULL, &timeout); if (ret < 0) { ret = -1; break; } /* Timeout */ if (ret == 0) { if (backoff > 16) { h_errno = TRY_AGAIN; ret = -1; break; } } if (ret == 1) { ret = read(s, msg, msglen); if (ret < 0) { ret = -1; break; } /* Reply to an old query. Ignore it */ if (ntohs(dns_hdr->id) != (id-1)) { continue; } finished = true; } } while (!finished); CYG_REPORT_RETVAL( ret ); return ret; }