ICE 域名解析耗時太長

smilestone322發表於2016-01-21

當dns伺服器設定錯誤,或者解析的域名是錯誤的域名時,ICE 域名解析耗時太長,20秒左右,發現它是使用getaddrinfo 函式進行域名解析的,並且最大迴圈5次;

 

vector<struct sockaddr_in>
IceInternal::getAddresses(const string& host, int port, bool server, bool blocking)
{
    vector<struct sockaddr_in> result;

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(struct sockaddr_in));

#ifdef GUMSTIX
    //
    // Gumstix does not support calling getaddrinfo with empty host.
    //
    if(host.empty())
    {
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        if(server)
        {
            addr.sin_addr.s_addr = htonl(INADDR_ANY);
        }
        else
        {
            addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
        }
        result.push_back(addr);
        return result;
    }
#endif

    struct addrinfo* info = 0;
    int retry = 5;

    struct addrinfo hints = { 0 };
    hints.ai_family = PF_INET;

    if(!blocking)
    {
        hints.ai_flags = AI_NUMERICHOST;
    }

    if(server)
    {
        //
        // If host is empty, getaddrinfo will return the wildcard
        // address instead of the loopack address.
        //
        hints.ai_flags |= AI_PASSIVE;
    }

    int rs = 0;
    do
    {
        if(host.empty())
        {
            rs = getaddrinfo(0, "1", &hints, &info); // Get the address of the loopback interface
        }
        else
        {
            rs = getaddrinfo(host.c_str(), 0, &hints, &info);
        }
    }
    while(info == 0 && rs == EAI_AGAIN && --retry >= 0);

    // In theory, getaddrinfo should only return EAI_NONAME if AI_NUMERICHOST is specified and the host name
    // is not a IP address. However on some platforms (e.g. Mac OS X 10.4.x) EAI_NODATA is also returned so
    // we also check for it.
#ifdef EAI_NODATA
    if(!blocking && (rs == EAI_NONAME || rs == EAI_NODATA))
#else
    if(!blocking && rs == EAI_NONAME)
#endif
    {
        return result; // Empty result indicates that a blocking lookup is necessary.
    }
    if(rs != 0)
    {
        DNSException ex(__FILE__, __LINE__);
        ex.error = rs;
        ex.host = host;
        throw ex;
    }

    struct addrinfo* p;
    for(p = info; p != NULL; p = p->ai_next)
    {
        assert(p->ai_family == PF_INET);
        memcpy(&addr, p->ai_addr, p->ai_addrlen);
        struct sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(&addr);
        sin->sin_port = htons(port);

        bool found = false;
        for(unsigned int i = 0; i < result.size(); ++i)
        {
            if(compareAddress(result[i], addr) == 0)
            {
                found = true;
                break;
            }
        }
        if(!found)
        {
            result.push_back(addr);
        }
    }

    freeaddrinfo(info);

    if(result.size() == 0)
    {
        DNSException ex(__FILE__, __LINE__);
        ex.host = host;
        throw ex;
    }

    return result;
}


 

 網上有對該函式設定超時的解決方案http://www.cppblog.com/converse/archive/2009/11/07/100349.html

http://www.cnblogs.com/cxz2009/archive/2010/11/19/1881693.html

http://bbs.chinaunix.net/thread-1433843-1-1.html

相關文章