0%

【Linux技术分享】sock模块显示0xc000000d错误码问题分析

sock模块显示0xc000000d错误码问题分析

问题概述

在机房监控应用启动时,ws2_32.dll模块中报错connect failed, status 0xc000000d

分析逻辑

  1. 错误日志为:connect failed, status 0xc000000d,0xc000000d是系统中的一个常见错误代码,表示 “INVALID_PARAMETER”,即无效的参数
  2. 打印server与winsock日志,发现winsock在connect函数报错,server在ioctl中报错,同样返回为参数错误问题,在connect函数日志中参数传入为socket 0x50,{ family AF_INET, address 192.0.xxx.xxx, port xxxxx }, len 40,经验判断传入参数无问题
  3. 编写demo验证,并传入相同参数,验证connect成功未报错
  4. 查看 winsock 日志,其中观察socket 0x50 创建流程,发现其在connet前调用bind函数
  5. 查看bind日志参数,socket 0x50,{ family AF_INET, address 127.0.1.1, port 0 },查看此日志基本就发现出现原因了
  6. 问题原因:127.0.1.1地址为回环地址,通常使用本地应用sock,当创建sock绑定此地址时,不能访问非本机地址
  7. 继续分析日志发现其通过getaddrinfo函数获取当前系统ip,但在wine下通过此函数返回127.0.1.1,如下图
    图1
    图2
  8. 经demo验证发现在nfs下的getaddrinfo函数无法获取到当前系统所有ip地址,但在deepin通过此函数是可行的
  9. getaddrinfo函数首先是通过系统中/etc/hosts文件中获取,若此文件中存在当传入的主机名称对应ip地址时则直接返回,在nfs上系统安装时,会默认将127.0.1.1与主机名称写入至当前系统/etc/hosts
  10. debian官方文档显示当系统安装的时候若没有设置ip地址则会将127.0.1.1设置为系统ip以防止某些软件存在bug,若存在固定ip则需要进行替换
  11. 修改应用安装包的preinstall,将hosts文件中的127.0.1.1替换为当前系统ip解决此问题