WebRTC -- IP地址

§ 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* 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 

#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 
#include 
#else
#include 
#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 
#endif

§ Private IP

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

10.0.0.0-10.255.255.255
172.16.0.0-172.31.255.255
192.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_;
};

你可能感兴趣的:(☆,WebRTC,☆,网络编程,WebRTC从入门到精通)