`

Libjingle一个虽小但却很严重的bug - 误导人的SocketAddress构造函数参数名称

阅读更多

在Libjingle+Linphone for Windows的voice call测试中, 遇到了一些问题. 而这些问题的root cause竟然源于Google code的一些小bug. 这里先指出一个.

 

SocketAddress这个类的其中一个构造函数是:

  // Creates the address with the given host and port.  If use_dns is true,
  // the hostname will be immediately resolved to an IP (which may block for
  // several seconds if DNS is not available).  Alternately, set use_dns to
  // false, and then call Resolve() to complete resolution later, or use
  // SetResolvedIP to set the IP explictly.
  SocketAddress(const std::string& hostname, int port);

 这个构造函数的参数看起来很简单, 一般人很少注意上面那堆罗嗦的注释, 第一个参数是hostname, 第二参数是port. 问题就出在hostname上面.

 

那这个构造函数的实现是什么呢?

SocketAddress::SocketAddress(const std::string& hostname, int port) {
  SetIP(hostname);
  SetPort(port);
}

void SocketAddress::SetIP(const std::string& hostname) {
  hostname_ = hostname;
  ip_ = StringToIP(hostname);
}

uint32 SocketAddress::StringToIP(const std::string& hostname) {
  uint32 ip = 0;
  StringToIP(hostname, &ip);
  return ip;
}

bool SocketAddress::StringToIP(const std::string& hostname, uint32* ip) {
  in_addr addr;
  if (inet_aton(hostname.c_str(), &addr) == 0)
    return false;
  *ip = NetworkToHost32(addr.s_addr);
  return true;
}

#ifdef WIN32
// Win32 doesn't provide inet_aton, so we add our own version here.
// Since inet_addr returns 0xFFFFFFFF on error, if we get this value
// we need to test the input to see if the address really was 255.255.255.255.
// This is slightly fragile, but better than doing nothing.
int inet_aton(const char* cp, struct in_addr* inp) {
  inp->s_addr = inet_addr(cp);
  return (inp->s_addr == INADDR_NONE &&
          strcmp(cp, "255.255.255.255") != 0) ? 0 : 1;
}
#endif  // WIN32

 hostname被传递的顺序是SocketAddress()->SetIP()->StringToIP()->inet_aton()->inet_addr()

 

那我们再来看看inet_addr()的说明, 这是一个系统函数. Refer to:

http://msdn.microsoft.com/en-us/library/ms738563%28v=vs.85%29.aspx

写道
The inet_addr function converts a string containing an IPv4 dotted-decimal address into a proper address for the IN_ADDR structure.
Parameters

cp [in]

A NULL-terminated character string representing a number expressed in the Internet standard ".'' (dotted) notation.

 也就是说inet_addr()函数的参数是一个IP地址字符串, 如"192.168.1.1".

 

而SocketAddress类的构造函数的参数按照字面意思应该是hostname (主机名),  所以如果传入hostname, 最终inet_addr()函数将无法正确解析, 那么构造的对象将会代表一个无效的地址.

 

偶被这个隐藏的小bug捉弄了好几天, 差点放弃Libjingle的测试, 幸亏最终静下心来仔细分析了一下.  如果传入hostname (比如"localhost") 构造这样一个SocketAddress对象, 然后调用SendTo()发送数据, 会返回-1, 系统错误码为WSAEADDRNOTAVAIL (10049) Cannot assign requested address.

写道
被请求的地址在它的环境中是不合法的。通常地在bind()函数试图将一个本地机器不合法的
地址绑扎到套接字时产生。它也可能在connect()、sendto()、WSAConnect()、WSAJoinLeaf()
或WSASendTo()函数调用时因远程机器的远程地址或端口号非法(如0地址或0端口号)而
产生。
 

 

 

分享到:
评论

相关推荐

    libjingle-0.6.2.

    Libjingle是Google提供的C++组件集,它为Google Talk的点对点通讯与语音呼叫功能提供交互操作性。组件包包括了Jingle和Jingle-Audio的google实现的源代码,它们是XMPP标准的推荐扩展,目前试验版可用。 我们发布此...

    libjingle-0.5.1.zip

    “libjingle-0.5.1.zip”是一个包含libjingle库的压缩文件,特别用于实现WebRTC(Web Real-Time Communication)中的NAT(Network Address Translation)穿透技术。NAT打洞是一种网络通信方法,允许在NAT背后的不同...

    VS2010编译libjingle0.6.2步骤

    下载 expat 2.0.1 版本,解压到 libjingle-0.6.2\talk\third_party 目录下。 知识点解释:expat 库是一个功能强大且广泛应用的 XML 解析库,它提供了高效的 XML 解析功能。在编译 libjingle 库时,expat 库是一个必...

    libjingle0.6.14编译好的.lib

    标题"libjingle0.6.14编译好的.lib"指出这是一个关于libjingle库的特定版本(0.6.14)的编译结果,通常是一个静态或动态链接库文件,后缀为.lib,表明它是针对Windows平台的,因为Windows系统使用.lib作为库文件格式...

    libjingle0.6.14

    由于压缩包文件名列表只有一个"libjingle-0.6.14",我们可以推测这可能包含以下内容: 1. **源代码**:完整的libjingle 0.6.14源代码,供学习者阅读和理解库的内部实现。 2. **编译脚本**:用于构建和测试libjingle...

    带GIPS的libjingle source

    标题 "带GIPS的libjingle source" 指的是一个包含GIPS(Global IP Sound)技术的libjingle源代码库。libjingle是Google开发的一个开源项目,主要用于实现跨平台的实时通信(RTC)功能,特别是网络音视频通话。GIPS是...

    libjingle在windows和ubuntu-linux上编译方法

    本文主要针对libjingle(版本包括但不限于0.6.6、0.6.9和最新的0.6.10)在Windows与Ubuntu Linux操作系统上的编译过程进行详细介绍,并分享了在编译过程中遇到的一些常见问题及其解决方案。 #### Windows平台下的...

    基于海思芯片(ARM平台)的libjingle静态库(交叉编译).rar

    Libjingle是一个方便实现P2P传输的开源库,由google公司开发,并与2005年12月15日发布第一个版本,可以粗略的看成是Jingle协议的C++实现库(peakflys注:只是和Jingle协议非常相似,并不完全兼容,区别以后介绍),...

    libjingle源码(linux版本)

    标题"libjingle源码(linux版本)"指的是开源项目libjingle的一个特定版本,针对Linux操作系统。libjingle是Google开发的一个跨平台库,主要用于实现P2P(Peer-to-Peer)通信,它包含了音视频通话、即时消息等多种实时...

    Libjingle 通过vs2005编译

    目前GOOGLECODE上的最新更新删除了libjingle.vcproj文件,采用scons脚本进行编译,增加了学习门槛,本次下载包增加了libjingle.vcproj文件并且已经通过了vs2005编译,方便大家学习使用。 Libjingle - Google Talk ...

    libjingle vs2010 编译通过

    libjingle是一个开源项目,由Google开发,主要用于实现网络音视频通信。这个项目的核心是提供一个跨平台的库,使得开发者能够轻松地在他们的应用程序中集成VoIP(Voice over IP)和视频聊天功能。在本案例中,我们...

    libjingle文档和0.4.0版本源码

    **libjingle** 是一个开源项目,由Google开发并维护,主要用于实现跨平台的实时通信(RTC)功能,包括音频、视频通话以及数据共享。它最初是为Google Talk服务设计的,现在已经成为WebRTC(Web Real-Time ...

    libjingle_peerconnection

    《深入理解libjingle_peerconnection:WebRTC的核心组件》 libjingle_peerconnection是Google开源项目WebRTC(Web Real-Time Communication)中的关键组件,它在实时通信领域扮演着至关重要的角色。WebRTC是一种...

    libjingle的封装库

    Libjingle是一个开源的跨平台通信库,由Google开发并维护,主要用于实现实时音视频通信和即时消息(IM)功能。它基于XMPP(Extensible Messaging and Presence Protocol)协议,为开发者提供了一套底层接口,可以...

    android webrtc libjingle_peerconnection

    Android WebRTC是一个强大的开源项目,它实现了WebRTC(Web Real-Time Communication)标准,允许在浏览器和其他应用程序之间进行实时通信,包括视频通话、音频聊天和数据共享。libjingle_peerconnection是Android ...

    【英文】Libjingle(GoogleTalk) 交叉编译步骤(arm-linux)

    作者:Group ArmTalk 文档:2011-11-30 ...1. Libjingle是什么 2. 怎么获取Libjingle 3. 怎么交叉编译Libjingle(arm-linux-) 以下是个人说明: 要在ARM架构的嵌入式设备使用libjingle,可以参考该文档进行操作

    libjingle源码(含GIPS LITE)

    libjingle源码(含GIPS LITE),方便大家编译上传

    libjingle 英文手册

    libjingle 中文 手册,很不错的哦,描述的很清楚,还有使用范例

    libjingle,P2P传输的开源库

    P2P传输的开源库,通过libjingle我们可以建立一个直通的网络连接(无视中间的NAT、防火墙、中继服务器和代理等),无需特别关心Session建立的细节(加解密、格式等),直接进行数据的交换

Global site tag (gtag.js) - Google Analytics