PRBool Resolver :: process(DNSSession* session) { PR_AtomicIncrement(&curlookups); PRBool locstatus = PR_FALSE; char host[MAXDNAME]; resinfo_t resi; resinfo_t* rp = &resi; struct hostent* hp = NULL; PRInt32 rv = 0; int querytype = 0; if (session) { session->setStatus(DNS_IN_PROCESS); if (FORWARD_LOOKUP == session->getQType ()) { PR_AtomicIncrement(&namelookups); memset((char *)rp, 0, sizeof(resi)); ar_reinfo.re_na_look++; strncpy(host, session->getName(), 64); host[64] = '\0'; locstatus = PR_TRUE; switch(session->getFamily()) { case PR_AF_INET: querytype = T_A; break; case PR_AF_INET6: querytype = T_AAAA; break; default: locstatus = PR_FALSE; } // Makes and sends the query // the session gets automatically added to the hash table if (PR_TRUE == locstatus) { if (do_query_name(rp, host, session, querytype) == -1) { PR_SetError(PR_BAD_ADDRESS_ERROR, 0); locstatus = PR_FALSE; } } } else if (REVERSE_LOOKUP == session->getQType ()) { PR_AtomicIncrement(&addrlookups); memset((char *)rp, 0, sizeof(resi)); ar_reinfo.re_na_look++; const PRNetAddr* addrp = session->getIP(); locstatus = PR_TRUE; switch(addrp->raw.family) { case PR_AF_INET: rv = do_query_number(rp, (char *) &addrp->inet.ip, session, PR_AF_INET); break; case PR_AF_INET6: rv = do_query_number(rp, (char *) &addrp->ipv6.ip, session, PR_AF_INET6); break; default: locstatus = PR_FALSE; PR_SetError(PR_BAD_ADDRESS_ERROR, 0); break; } if (-1 == rv) { locstatus = PR_FALSE; } } } if (PR_TRUE == locstatus) { locstatus = PR_FALSE; int resend; do { resend = 0; session->wait(); if (DNS_COMPLETED == session->getStatus() ) { // Process answer and return meaningful data to caller. if (FORWARD_LOOKUP == session->getQType()) { if ((hp = ar_answer(session, &resend, NULL, 0)) != NULL) { PRInt32 rv = CopyHostent(session->getHentp(), hp, session->getBuffer(), session->getBufferSize()); if (rv != PR_AR_OK) PR_SetError(rv, 0); else locstatus = PR_TRUE; } } else if (REVERSE_LOOKUP == session->getQType()) { if (hp = ar_answer(session, &resend, NULL, 0)) { PRInt32 rv = CopyHostent(session->getHentp(), hp, session->getBuffer(), session->getBufferSize()); if (rv != PR_AR_OK) PR_SetError(rv, 0); else locstatus = PR_TRUE; } } } else if (DNS_TIMED_OUT == session->getStatus()) { PR_SetError(PR_IO_TIMEOUT_ERROR, 0); } else { PR_SetError(PR_BAD_ADDRESS_ERROR, 0); } } while (resend); } PR_AtomicDecrement(&curlookups); return locstatus; }
// **************************************************************************** // Method: Connect // // Purpose: // given a host and a port, connect to it and return the new fd // // Programmer: Jeremy Meredith // Creation: May 24, 2007 // // **************************************************************************** static int Connect(const char *host, int port) { #if defined(_WIN32) // Create a copy of the hostent struct in case other WinSock // functions want to modify it. void *hostInfo = (void *)CopyHostent(gethostbyname(host)); #else void *hostInfo = (void *)gethostbyname(host); #endif int connectedSock; struct hostent *hp; struct sockaddr_in server; // // Set up the structures for opening the sockets. // hp = (struct hostent *)hostInfo; if (hp == NULL) return -1; memset(&server, 0, sizeof(server)); memcpy(&(server.sin_addr), hp->h_addr, hp->h_length); server.sin_family = hp->h_addrtype; server.sin_port = htons(port); // // Create a socket. // #if defined(_WIN32) connectedSock = socket(AF_INET, SOCK_STREAM, 0); if (connectedSock == INVALID_SOCKET) { return -1; } // Disable the Nagle algorithm int opt = 1; setsockopt(connectedSock, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&opt, sizeof(int)); if (connect(connectedSock, (struct sockaddr *)&server, sizeof(server)) < 0) { closesocket(connectedSock); return -1; } #else connectedSock = socket(AF_INET, SOCK_STREAM, 0); if (connectedSock < 0) { return -1; } // Disable the Nagle algorithm int opt = 1; setsockopt(connectedSock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int)); if (connect(connectedSock, (struct sockaddr *)&server, sizeof(server)) < 0) { close(connectedSock); return -1; } #endif return connectedSock; }