ICE 域名解析耗时太长

当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
### ICE报文解析方法与工具 ICE(Interactive Connectivity Establishment)是一种用于建立网络连接的协议,通常在通信领域中被广泛使用。解析ICE报文的过程涉及对STUN、TURN等协议的理解和应用。以下是关于ICE报文解析的方法和工具的相关信息。 #### 1. 解析ICE报文的方法 解析ICE报文需要理解其底层协议的工作机制,包括STUN(Session Traversal Utilities for NAT)和TURN(Traversal Using Relays around NAT)。以下为解析ICE报文的基本方法: - **STUN消息解析**:STUN协议主要用于NAT穿透,其消息类型包括请求/响应和指示交易。解析时需识别消息类型并提取关键字段,例如事务ID、地址信息等[^5]。 - **候选者分析**:ICE协议通过收集本地和远程候选者来建立连接。解析过程中需要分析这些候选者的类型(如host、srflx、prflx或relay)及其优先级[^2]。 - **连通性检测**:解析ICE报文时,需关注连通性检测过程中的STUN绑定请求和响应消息。这一步骤对于Full ICE模式尤为重要,Lite ICE模式则主要依赖于响应消息。 #### 2. ICE报文解析工具 针对电力系统或其他领域的ICE报文解析,市场上存在多种专业工具。以下是几款推荐工具及其功能特点: - **电力ICE101/104规约报文解析软件**: - 这是一款专注于解析ICE101/104规约报文的专业工具,适用于电力系统工作人员[^1]。 - 功能特点包括自动识别报文类型、可视化界面展示、实时解析结果以及支持导出功能[^3]。 - 使用方法简单,只需拖拽文件即可完成解析,并提供详细的解析结果供用户查看[^3]。 - **Wireshark**: - Wireshark是一款通用的网络协议分析工具,支持对STUN、TURN和ICE协议的深度解析。 - 用户可以通过过滤器筛选相关报文,并查看其详细结构和字段内容[^4]。 - **mediasoup Lite ICE实现**: - mediasoup是一款WebRTC框架,其Lite ICE实现专注于简化ICE连接流程。 - 该工具适合开发者研究Lite ICE模式下的连通性检测机制,尤其是STUN绑定请求的处理逻辑[^2]。 #### 3. 示例代码:解析STUN消息 以下是一个简单的Python代码示例,用于解析STUN消息中的关键字段: ```python import stun # STUN服务器配置 stun_server = "stun.l.google.com" stun_port = 19302 # 发起STUN请求并解析响应 response = stun.get_ip_info(stun_host=stun_server, stun_port=stun_port) print(f"External IP: {response[1]}") print(f"External Port: {response[2]}") ``` 此代码利用`stun`库发起STUN请求,并解析返回的外部IP和端口信息。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值