ZBLOG

函数注释: int make_ioa_addr(const uint8_t *saddr0, int port, ioa_addr *addr) { if (!saddr0 || !addr) { return -1; } char ssaddr[257]; STRCPY(ssaddr, saddr0); char *saddr = ssaddr; while (*saddr == ' ') { ++saddr; } size_t l...

以下是 make_ioa_addr 函数的详细注释,旨在解释每个部分的功能和逻辑。

/**
 * @brief 将给定的地址字符串和端口转换为 ioa_addr 结构体。
 *
 * @param saddr0 输入的地址字符串(可以是 IPv4 或 IPv6 格式)。
 * @param port 要绑定或连接的端口号。
 * @param addr 指向要填充的 ioa_addr 结构体指针。
 * 
 * @return 成功时返回 0;失败时返回 -1。
 */
int make_ioa_addr(const uint8_t *saddr0, int port, ioa_addr *addr) {

    // 检查输入参数是否有效
    if (!saddr0 || !addr) {
        return -1; // 参数无效,返回错误
    }

    char ssaddr[257]; // 存储输入地址字符串的缓冲区
    STRCPY(ssaddr, saddr0); // 将输入地址复制到缓冲区

    char *saddr = ssaddr;
    
    // 跳过前导空格
    while (*saddr == ' ') {
        ++saddr;
    }

    size_t len = strlen(saddr);
    
    // 移除末尾空格
    while (len > 0) {
        if (saddr[len - 1] == ' ') {
            saddr[len - 1] = 0; // 替换为空字符以结束字符串
            --len;
        } else {
            break;
        }
    }

    memset(addr, 0, sizeof(ioa_addr)); // 清空 addr 的内容

    // 尝试将地址解析为 IPv4 地址
    if ((len == 0) || (inet_pton(AF_INET, saddr, &addr->s4.sin_addr) == 1)) {
        addr->s4.sin_family = AF_INET; // 设置地址族为 IPv4
#if defined(TURN_HAS_SIN_LEN)
        addr->s4.sin_len = sizeof(struct sockaddr_in); // 如果有需要,设置长度字段
#endif
        addr->s4.sin_port = nswap16(port); // 设置端口(网络字节序)
        
    } else if (inet_pton(AF_INET6, saddr, &addr->s6.sin6_addr) == 1) { 
        // 尝试将地址解析为 IPv6 地址
        addr->s6.sin6_family = AF_INET6; 
#if defined(SIN6_LEN)
        addr->s6.sin6_len = sizeof(struct sockaddr_in6); 
#endif
        addr->s6.sin6_port = nswap16(port); 

    } else {
        struct addrinfo addr_hints;
        struct addrinfo *addr_result = NULL;
        int err;

        memset(&addr_hints, 0, sizeof(struct addrinfo)); 
        addr_hints.ai_family = AF_UNSPEC;   /* 支持 IPv4 或 IPv6 */
        addr_hints.ai_socktype = SOCK_DGRAM; /* 数据报套接字 */
        addr_hints.ai_flags = AI_PASSIVE;     /* 用于通配符 IP 地址 */
        
         /* 获取与主机名相关的信息 */
         err = getaddrinfo(saddr, NULL, &addr_hints, &addr_result);
         if ((err != 0) || (!addr_result)) { 
             fprintf(stderr, "error resolving '%s' hostname: %s\n", saddr, gai_strerror(err));
             return -1; 
         }

         int family = AF_INET; /* 默认使用 IPv4 */
         struct addrinfo *addr_result_orig = addr_result;
         int found = 0;

     beg_af:

         while (addr_result) {

             if (addr_result->ai_family == family) {  
                 if (family == AF_INET) {  
                     memcpy(addr, addr_result->ai_addr, addr_result->ai_addrlen); 
                     addr->s4.sin_port = nswap16(port); 
#if defined(TURN_HAS_SIN_LEN)
                     addr->s4.sin_len = sizeof(struct sockaddr_in);
#endif
                     found=1;  
                     break;
                 } else if (family == AF_INET6) {  
                     memcpy(addr, addr_result->ai_addr, addr_result->ai_addrlen);  
                     addr->s6.sin6_port=nswap16(port);
#if defined(SIN6_LEN)
                     addr->s6.sin6_len=sizeof(struct sockaddr_in6);
#endif      
                     found=1;
                     break;
                 }
             }

             addressResult=addressResult→ ai_next ;  
          }

          if (!found && family==AF_INET){   
              family=AF_INET six ;   /* 切换到IPv六*/
              addressResult=addressResultOrig ;
              goto beg_af ;     /* 循环进行处理*/
           }
           
           freeAddrInfo(addrResultOrig );   /*释放获得的信息*/
      }
     
      return 0 ;   /*成功*/
}

注释总结:

  • 函数作用: 将传入的字符串形式的IP地址和端口号转换成 ioa_addr 类型的数据结构,以便后续网络操作使用。
  • 输入检查: 确保输入不为空,以避免潜在的问题。
  • 清理和标准化输入: 去除前后空白字符,以确保格式正确。
  • 协议处理: 首先尝试解析为IPv4,然后是IPv6,如果都失败则使用 getaddrinfo 来支持主机名解析。
  • 内存管理: 使用 freeAddrInfo 来释放通过 getAddrInfo 分配的信息。

如果您有特定问题或者想深入了解某一部分,请告诉我!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=6185

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?