Esempio n. 1
0
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; 
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
/*  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;
}
Esempio n. 5
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*/);
}
Esempio n. 6
0
/** 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;
}