多网段切换导致DNS域名解析失败问题处理

Posted 谁吃薄荷糖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多网段切换导致DNS域名解析失败问题处理相关的知识,希望对你有一定的参考价值。

文章目录


🔴问题描述:

设备有LAN和WIFI两种网络方式,测试时LAN和WIFI分别连接在两个不同的路由器上,切换两个网络(只启用LAN或者WIFI)时发现设备的mqtt程序重连服务器会失败(服务器地址使用的是域名)。

🟠问题排查:

初步排查时发现重启mqtt程序,可以正常连接。但是使用mqtt的断网重连功能发现就不行。最后研读mqtt源码,发现是调用
getaddrinfo函数失败了,顺藤摸瓜去排查这个函数与DNS相关的地方。

🟡问题解决:

需要在DNS解析失败时,重新加载一下DNS。所以在mqtt断链的回调里加入了res_init()函数,问题解决,重连成功。

🟢知识扩展:

如果在程序中调用getaddrinfogetnameinfo来获取域名对应的IP,在同一进程中,上一次成功获取的结果会被保留下来,即使在下一次调用之前disable了DNS并清空了系统的DNS缓存,下一次仍然能够解析出正确的IP。此时需要在调用这两个函数之前用res_init()函数来清空他们自己保留的缓存。

🔵res_init() 简介:

作用:

搜索默认域名和 Internet 地址。

所属库:

标准 C 库 ( libc.a )

示例:

#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
 
void res_init ( )

描述

res_init子例程读取/etc/resolv.conf文件以获取默认域名和运行名称服务器的初始主机的 Internet 地址。
注意:如果/etc/resolv.conf文件不存在,res_init子例程会尝试使用本地/etc/hosts文件进行名称解析。如果系统没有使用域名服务器,则/etc/resolv.conf文件不应该存在。即使系统正在使用名称服务器,系统上也应该存在/ etc/hosts文件。在这种情况下,该文件应包含系统运行所需的主机 ID,即使名称服务器未运行也是如此。
res_init子例程是构成解析器的一组子例程之一,解析器是一组将域名转换为 Internet 地址的函数。所有解析器子例程都使用/usr/include/resolv.h文件,该文件定义了_res结构。res_init子例程将域名信息存储在_res结构中。三个环境变量LOCALDOMAIN、RES_TIMEOUT和RES_RETRY影响与_res结构相关的默认值。
所有包含res_init子例程的应用程序都必须在编译时将_BSD宏设置为特定值。可接受的值为 43 和 44。此外,所有套接字应用程序都必须包含 BSD libbsd.a库。

相关文件

路径描述
/etc/resolv.conf包含名称服务器和域名。
/etc/hosts包含网络中主机的主机名及其地址。此文件用于将主机名解析为 Internet 地址。

🟣引经据典:

https://blog.csdn.net/weixin_39530839/article/details/116778660?utm_source=app&app_version=5.3.0
https://www.ibm.com/docs/zh/aix/7.3?topic=r-res-init-subroutine

以上是关于多网段切换导致DNS域名解析失败问题处理的主要内容,如果未能解决你的问题,请参考以下文章

bind9搭建dns,本网可解析,其他网段只解析自定义的域名,不解析公网

服务器的SSL证书验证失败问题,怎么解决

ping 域名失败。。但是ping ip 可以成功

为啥我的SSL证书验证失败

小红帽进不去显示dns

https证书较验不通过