NS_IMETHODIMP nsDNSRecord::GetNextAddr(PRUint16 port, PRNetAddr *addr) { // not a programming error to poke the DNS record when it has no more // entries. just fail without any debug warnings. this enables consumers // to enumerate the DNS record without calling HasMore. if (mDone) return NS_ERROR_NOT_AVAILABLE; if (mHostRecord->addr_info) { mIter = PR_EnumerateAddrInfo(mIter, mHostRecord->addr_info, port, addr); if (!mIter) return NS_ERROR_NOT_AVAILABLE; } else { // This should never be null (but see bug 290190) :-( NS_ENSURE_STATE(mHostRecord->addr); mIter = nsnull; // no iterations memcpy(addr, mHostRecord->addr, sizeof(PRNetAddr)); // set given port port = PR_htons(port); if (addr->raw.family == PR_AF_INET) addr->inet.port = port; else addr->ipv6.port = port; } mDone = !mIter; return NS_OK; }
AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, const char *cname) { size_t hostlen = strlen(host); mHostName = static_cast<char*>(moz_xmalloc(hostlen + 1)); memcpy(mHostName, host, hostlen + 1); if (cname) { size_t cnameLen = strlen(cname); mCanonicalName = static_cast<char*>(moz_xmalloc(cnameLen + 1)); memcpy(mCanonicalName, cname, cnameLen + 1); } else { mCanonicalName = nullptr; } PRNetAddr tmpAddr; void *iter = nullptr; do { iter = PR_EnumerateAddrInfo(iter, prAddrInfo, 0, &tmpAddr); if (iter) { NetAddrElement *addrElement = new NetAddrElement(&tmpAddr); mAddresses.insertBack(addrElement); } } while (iter); }
AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, bool disableIPv4) { size_t hostlen = strlen(host); mHostName = static_cast<char*>(moz_xmalloc(hostlen + 1)); memcpy(mHostName, host, hostlen + 1); PRNetAddr tmpAddr; void *iter = nullptr; do { iter = PR_EnumerateAddrInfo(iter, prAddrInfo, 0, &tmpAddr); if (iter && (!disableIPv4 || tmpAddr.raw.family != PR_AF_INET)) { NetAddrElement *addrElement = new NetAddrElement(&tmpAddr); mAddresses.insertBack(addrElement); } } while (iter); }
/* LASDNSBuild * Builds a hash table of all the hostnames provided (plus their aliases * if aliasflg is true). Wildcards are only permitted in the leftmost * field. They're represented in the hash table by a leading period. * E.g. ".mcom.com". * * RETURNS Zero on success, else LAS_EVAL_INVALID */ int LASDnsBuild(NSErr_t *errp, char *attr_pattern, LASDnsContext_t *context, int aliasflg) { size_t delimiter; /* length of valid tokeni */ char token[256]; /* max length dns name */ int i; char **p; pool_handle_t *pool; PRStatus error=PR_SUCCESS; char buffer[PR_NETDB_BUF_SIZE]; #ifdef UTEST struct hostent *he, host; #else PRHostEnt *he, host; #endif char *end_attr_pattern; if (attr_pattern == NULL) { nserrGenerate(errp, ACLERRINVAL, ACLERR4770, ACL_Program, 1, XP_GetAdminStr(DBT_lasdnsbuildInvalidAttributePattern_)); return LAS_EVAL_INVALID; } context->Table = PR_NewHashTable(0, PR_HashCaseString, PR_CompareCaseStrings, PR_CompareValues, &ACLPermAllocOps, NULL); pool = pool_create(); context->pool = pool; if ((!context->Table) || (!context->pool)) { nserrGenerate(errp, ACLERRNOMEM, ACLERR4700, ACL_Program, 1, XP_GetAdminStr(DBT_lasdnsbuildUnableToAllocateHashT_)); return LAS_EVAL_INVALID; } end_attr_pattern = attr_pattern + strlen(attr_pattern); do { size_t maxsize = sizeof(token); /* Get a single hostname from the pattern string */ delimiter = strcspn(attr_pattern, ", \t"); if (delimiter >= maxsize) { delimiter = maxsize-1; } PL_strncpyz(token, attr_pattern, delimiter + 1); token[delimiter] = '\0'; /* Skip any white space after the token */ attr_pattern += delimiter; if (attr_pattern < end_attr_pattern) { attr_pattern += strspn(attr_pattern, ", \t"); } /* If there's a wildcard, strip it off but leave the "." * Can't have aliases for a wildcard pattern. * Treat "*" as a special case. If so, go ahead and hash it. */ if (token[0] == '*') { if (token[1] != '\0') { if (!PR_HashTableAdd(context->Table, pool_strdup(pool, &token[1]), (void *)-1)) { nserrGenerate(errp, ACLERRFAIL, ACLERR4710, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_), token); return LAS_EVAL_INVALID; } } else { if (!PR_HashTableAdd(context->Table, pool_strdup(pool, token), (void *)-1)) { nserrGenerate(errp, ACLERRFAIL, ACLERR4720, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_), token); return LAS_EVAL_INVALID; } } } else { /* This is a single hostname add it to the hash table */ if (!PR_HashTableAdd(context->Table, pool_strdup(pool, &token[0]), (void *)-1)) { nserrGenerate(errp, ACLERRFAIL, ACLERR4730, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_), token); return LAS_EVAL_INVALID; } if (aliasflg) { void *iter = NULL; int addrcnt = 0; PRNetAddr *netaddr = (PRNetAddr *)PERM_CALLOC(sizeof(PRNetAddr)); PRAddrInfo *infop = PR_GetAddrInfoByName(token, PR_AF_UNSPEC, (PR_AI_ADDRCONFIG|PR_AI_NOCANONNAME)); if (!netaddr) { if (infop) { PR_FreeAddrInfo(infop); } return LAS_EVAL_NEED_MORE_INFO; /* hostname not known to dns? */ } if (!infop) { if (netaddr) { PERM_FREE(netaddr); } return LAS_EVAL_NEED_MORE_INFO; /* hostname not known to dns? */ } /* need to count the address, first */ while ((iter = PR_EnumerateAddrInfo(iter, infop, 0, netaddr))) { addrcnt++; } if (0 == addrcnt) { PERM_FREE(netaddr); PR_FreeAddrInfo(infop); return LAS_EVAL_NEED_MORE_INFO; /* hostname not known to dns? */ } iter = NULL; /* from the beginning */ memset(netaddr, 0, sizeof(PRNetAddr)); for (i = 0; i < addrcnt; i++) { iter = PR_EnumerateAddrInfo( iter, infop, 0, netaddr ); if (NULL == iter) { break; } error = PR_GetHostByAddr(netaddr, buffer, PR_NETDB_BUF_SIZE, &host); if (error == PR_SUCCESS) { he = &host; } else { continue; } if (he->h_name) { /* Add it to the hash table */ if (!PR_HashTableAdd(context->Table, pool_strdup(pool, he->h_name), (void *)-1)) { nserrGenerate(errp, ACLERRFAIL, ACLERR4750, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_), he->h_name); PERM_FREE(netaddr); PR_FreeAddrInfo(infop); return LAS_EVAL_INVALID; } } if (he->h_aliases && he->h_aliases[0]) { for (p = he->h_aliases; *p; ++p) { /* Add it to the hash table */ if (!PR_HashTableAdd(context->Table, pool_strdup(pool, *p), (void *)-1)) { nserrGenerate(errp, ACLERRFAIL, ACLERR4760, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsbuildUnableToAddKeySN_), *p); PERM_FREE(netaddr); PR_FreeAddrInfo(infop); return LAS_EVAL_INVALID; } } } } /* for (i = 0; i < addrcnt; i++) */ PERM_FREE(netaddr); PR_FreeAddrInfo(infop); } /* if aliasflg */ } /* else - single hostname */ } while ((attr_pattern != NULL) && (attr_pattern[0] != '\0') && (delimiter != 0)); return 0; }
TPS_PUBLIC PSHttpResponse *HttpConnection::getResponse(int index, const char *servlet, const char *body) { char *host_port; char uri[800]; char *nickname; const char *httpprotocol; ConnectionInfo *failoverList = GetFailoverList(); int len = failoverList->ConnectionInfo::GetHostPortListLen(); if (index >= len) { index = len - 1; // use the last one } host_port= (failoverList->GetHostPortList())[index]; if (IsSSL()) { httpprotocol = "https"; } else { httpprotocol = "http"; } PR_snprintf((char *)uri, 800, "%s://%s/%s", httpprotocol, host_port, servlet); RA::Debug("HttpConnection::getResponse", "Send request to host %s servlet %s", host_port, servlet); RA::Debug(LL_PER_PDU, "HttpConnection::getResponse", "uri=%s", uri); RA::Debug(LL_PER_PDU, "HttpConnection::getResponse", "host_port=%s", host_port); char *pPort = NULL; char *pPortActual = NULL; char hostName[512]; /* * Isolate the host name, account for IPV6 numeric addresses. * */ if(host_port) strncpy(hostName,host_port,512); pPort = hostName; while(1) { pPort = strchr(pPort, ':'); if (pPort) { pPortActual = pPort; pPort++; } else break; } if(pPortActual) *pPortActual = '\0'; /* * Rifle through the values for the host */ PRAddrInfo *ai; void *iter; PRNetAddr addr; int family = PR_AF_INET; ai = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC, PR_AI_ADDRCONFIG); if (ai) { printf("%s\n", PR_GetCanonNameFromAddrInfo(ai)); iter = NULL; while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) { char buf[512]; PR_NetAddrToString(&addr, buf, sizeof buf); RA::Debug( LL_PER_PDU, "HttpConnection::getResponse: ", "Sending addr -- Msg='%s'\n", buf ); family = PR_NetAddrFamily(&addr); RA::Debug( LL_PER_PDU, "HttpConnection::getResponse: ", "Sending family -- Msg='%d'\n", family ); break; } PR_FreeAddrInfo(ai); } PSHttpServer httpserver(host_port, family); nickname = GetClientNickname(); if (IsSSL()) httpserver.setSSL(PR_TRUE); else httpserver.setSSL(PR_FALSE); PSHttpRequest httprequest(&httpserver, uri, HTTP11, 0); if (IsSSL()) { httprequest.setSSL(PR_TRUE); if (nickname != NULL) { httprequest.setCertNickName(nickname); } else { return NULL; } } else httprequest.setSSL(PR_FALSE); httprequest.setMethod("POST"); if (body != NULL) { httprequest.setBody( strlen(body), body); } httprequest.addHeader( "Content-Type", "application/x-www-form-urlencoded" ); if (m_headers != NULL) { for (int i=0; i<m_headers->Size(); i++) { char *name = m_headers->GetNameAt(i); httprequest.addHeader(name, m_headers->GetValue(name)); } } if (IsKeepAlive()) httprequest.addHeader( "Connection", "keep-alive" ); HttpEngine httpEngine; return httpEngine.makeRequest(httprequest, httpserver, (PRIntervalTime)GetTimeout(), PR_FALSE /*expectChunked*/); }
/** Create socket and connect to it. @param hostname Hostname to connect @param port Port name/number to connect @param mode Connection mode. Bit-array of MODE_NO_SSL, MODE_IP6MODE, MODE_IP4MODE. @return NULL on error, otherwise connected socket. */ static PRFileDesc *create_connected_socket(char *hostname,int port,int mode) { PRAddrInfo *addr_info; void *addr_iter; PRNetAddr addr; PRFileDesc *localsocket; int can_exit,valid_socket; PRUint16 af_spec; localsocket=NULL; addr_info=NULL; af_spec=PR_AF_UNSPEC; if (!(mode&MODE_IP6MODE)) af_spec=PR_AF_INET; addr_info=PR_GetAddrInfoByName(hostname,af_spec,PR_AI_ADDRCONFIG); if (addr_info == NULL) { print_nspr_error(); return NULL; } /*We have socket -> enumerate and try to connect*/ addr_iter=NULL; can_exit=0; valid_socket=0; while (!can_exit) { addr_iter=PR_EnumerateAddrInfo(addr_iter,addr_info,port,&addr); if (addr_iter==NULL) { can_exit=1; } else { if ((PR_NetAddrFamily(&addr)==PR_AF_INET && (mode&MODE_IP4MODE)) || (PR_NetAddrFamily(&addr)==PR_AF_INET6 && (mode&MODE_IP6MODE))) { /*Type of address is what user want, try to create socket and make connection*/ /*Create socket*/ localsocket=create_socket(!(mode&MODE_NO_SSL),(PR_NetAddrFamily(&addr)==PR_AF_INET6)); if (localsocket) { /*Try to connect*/ if (PR_Connect(localsocket,&addr,PR_INTERVAL_NO_TIMEOUT)==PR_SUCCESS) { /*Force handshake*/ if ((!(mode&MODE_NO_SSL)) && SSL_ForceHandshake(localsocket)!=SECSuccess) { /*Handhake failure -> fail*/ print_nspr_error(); if (PR_Close(localsocket)!=PR_SUCCESS) { print_nspr_error(); can_exit=1; } localsocket=NULL; } /*Socket is connected -> we can return it*/ can_exit=1; } else { /*Try another address*/ if (PR_Close(localsocket)!=PR_SUCCESS) { print_nspr_error(); can_exit=1; } localsocket=NULL; } } } } } if (!localsocket) { /*Socket is unvalid -> we don't found any usable address*/ fprintf(stderr,"Can't connect to host %s on port %d!\n",hostname,port); } PR_FreeAddrInfo(addr_info); return localsocket; }