WebRTC-IP相关概念

来源:互联网 发布:搜狗五笔for mac下载 编辑:程序博客网 时间:2024/06/05 17:10

§ Unresolved IP

Unresolved IP直译为“未能解答的IP”,也就是不能识别的IP。必须既不是IPv4地址也不是IPv6地址,才叫Unresolved IP。
IPv4地址格式:xxx.xxx.xxx.xxx (0 <= xxx <= 255)
IPv6地址格式:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (xxxx代表4位十六进制数字)

具体的判断方法见webrtc源码:rtc_base\socketaddress.ccSetIPIsUnresolvedIP函数。

§ Resolve Host

Resolve HostHost解析,对于不能识别的IP地址,可以尝试将其当作host去解析。主要使用 getaddrinfo API实现。

具体的解析方法见webrtc源码:rtc_base\nethelpers.ccResolveHostname函数。代码摘要如下:

int ResolveHostname(const std::string& hostname, int family,                    std::vector<IPAddress>* addresses) {  if (!addresses) {    return -1;  }  addresses->clear();  struct addrinfo* result = nullptr;  struct addrinfo hints = {0};  hints.ai_family = family;  hints.ai_flags = AI_ADDRCONFIG;  int ret = getaddrinfo(hostname.c_str(), nullptr, &hints, &result);  if (ret != 0) {    return ret;  }  struct addrinfo* cursor = result;  for (; cursor; cursor = cursor->ai_next) {    if (family == AF_UNSPEC || cursor->ai_family == family) {      IPAddress ip;      if (IPFromAddrInfo(cursor, &ip)) {        addresses->push_back(ip);      }    }  }  freeaddrinfo(result);  return 0;}

§ Byte Order

Byte Order字节序列,在网络编程中,需要区分“网络字节序列”和“本地主机字节序列”。字节序列有2种:“大端”和“小端”。
详见大端(Bid Endian)、小端(Little Endian)含义

目前,网络字节序列都是“大端”,windows的主机字节序列是“小端”。

关于主机字节序列和网络字节序列的转换,可以参考webrtc源码:rtc_base\byteorder.h,摘要如下:

#if defined(WEBRTC_MAC)#include <libkern/OSByteOrder.h>#define htobe16(v) OSSwapHostToBigInt16(v)#define htobe32(v) OSSwapHostToBigInt32(v)#define htobe64(v) OSSwapHostToBigInt64(v)#define be16toh(v) OSSwapBigToHostInt16(v)#define be32toh(v) OSSwapBigToHostInt32(v)#define be64toh(v) OSSwapBigToHostInt64(v)#define htole16(v) OSSwapHostToLittleInt16(v)#define htole32(v) OSSwapHostToLittleInt32(v)#define htole64(v) OSSwapHostToLittleInt64(v)#define le16toh(v) OSSwapLittleToHostInt16(v)#define le32toh(v) OSSwapLittleToHostInt32(v)#define le64toh(v) OSSwapLittleToHostInt64(v)#elif defined(WEBRTC_WIN) || defined(__native_client__)#if defined(WEBRTC_WIN)#include <stdlib.h>#include <winsock2.h>#else#include <netinet/in.h>#endif#define htobe16(v) htons(v)#define htobe32(v) htonl(v)#define be16toh(v) ntohs(v)#define be32toh(v) ntohl(v)#if defined(WEBRTC_WIN)#define htobe64(v) htonll(v)#define be64toh(v) ntohll(v)#endif#if defined(RTC_ARCH_CPU_LITTLE_ENDIAN)#define htole16(v) (v)#define htole32(v) (v)#define htole64(v) (v)#define le16toh(v) (v)#define le32toh(v) (v)#define le64toh(v) (v)#if defined(__native_client__)#define htobe64(v) __builtin_bswap64(v)#define be64toh(v) __builtin_bswap64(v)#endif#elif defined(RTC_ARCH_CPU_BIG_ENDIAN)#define htole16(v) __builtin_bswap16(v)#define htole32(v) __builtin_bswap32(v)#define htole64(v) __builtin_bswap64(v)#define le16toh(v) __builtin_bswap16(v)#define le32toh(v) __builtin_bswap32(v)#define le64toh(v) __builtin_bswap64(v)#if defined(__native_client__)#define htobe64(v) (v)#define be64toh(v) (v)#endif#else#error RTC_ARCH_CPU_BIG_ENDIAN or RTC_ARCH_CPU_LITTLE_ENDIAN must be defined.#endif  // defined(RTC_ARCH_CPU_LITTLE_ENDIAN)#elif defined(WEBRTC_POSIX)#include <endian.h>#endif

§ Private IP

Private IP私有IP也叫保留IP,RFC1918规定了三个保留地址段落:

10.0.0.0-10.255.255.255172.16.0.0-172.31.255.255192.168.0.0-192.168.255.255

判断是否为Private IP的方法,可以参考rtc_base\ipaddress.cc中的IsPrivateV4函数:

// 参数是主机字节序列bool IsPrivateV4(uint32_t ip_in_host_order) {  return ((ip_in_host_order >> 24) == 127) ||      ((ip_in_host_order >> 24) == 10) ||      ((ip_in_host_order >> 20) == ((172 << 4) | 1)) ||      ((ip_in_host_order >> 16) == ((192 << 8) | 168)) ||      ((ip_in_host_order >> 16) == ((169 << 8) | 254));}

§ IPAddress类

WebRTC封装了针对IP地址处理的类IPAddress,支持IPv4和IPv6。

class IPAddress { public:  IPAddress() : family_(AF_UNSPEC) {    ::memset(&u_, 0, sizeof(u_));  }  explicit IPAddress(const in_addr& ip4) : family_(AF_INET) {    memset(&u_, 0, sizeof(u_));    u_.ip4 = ip4;  }  explicit IPAddress(const in6_addr& ip6) : family_(AF_INET6) {    u_.ip6 = ip6;  }  explicit IPAddress(uint32_t ip_in_host_byte_order) : family_(AF_INET) {    memset(&u_, 0, sizeof(u_));    u_.ip4.s_addr = HostToNetwork32(ip_in_host_byte_order);  }  IPAddress(const IPAddress& other) : family_(other.family_) {    ::memcpy(&u_, &other.u_, sizeof(u_));  }  virtual ~IPAddress() {}  const IPAddress & operator=(const IPAddress& other) {    family_ = other.family_;    ::memcpy(&u_, &other.u_, sizeof(u_));    return *this;  }  bool operator==(const IPAddress& other) const;  bool operator!=(const IPAddress& other) const;  bool operator <(const IPAddress& other) const;  bool operator >(const IPAddress& other) const;  friend std::ostream& operator<<(std::ostream& os, const IPAddress& addr);  int family() const { return family_; }  in_addr ipv4_address() const;  in6_addr ipv6_address() const;  // Returns the number of bytes needed to store the raw address.  size_t Size() const;  // Wraps inet_ntop.  std::string ToString() const;  // Same as ToString but anonymizes it by hiding the last part.  std::string ToSensitiveString() const;  // Returns an unmapped address from a possibly-mapped address.  // Returns the same address if this isn't a mapped address.  IPAddress Normalized() const;  // Returns this address as an IPv6 address.  // Maps v4 addresses (as ::ffff:a.b.c.d), returns v6 addresses unchanged.  IPAddress AsIPv6Address() const;  // For socketaddress' benefit. Returns the IP in host byte order.  uint32_t v4AddressAsHostOrderInteger() const;  // Whether this is an unspecified IP address.  bool IsNil() const; private:  int family_;  union {    in_addr ip4;    in6_addr ip6;  } u_;};