DNS请求响应

2023-11-12

问题背景:在无线网络可用,而有线网络不可用的场景下,依靠第三方接口解析域名,或者udp,tcp接口内部解析域名,会默认阻塞10秒钟

办法:自行定制dns请求及响应

BOOL SendDNSRequest(sockaddr_in sockAddrDNSServer, char *szDomainName)
{
    char *pWriteDNSPacket = m_szDNSPacket;
    memset(pWriteDNSPacket, 0, DNS_PACKET_MAX_SIZE);

    //填充DNS查询报文头部
    DNSHeader *pDNSHeader = (DNSHeader*)pWriteDNSPacket;
    pDNSHeader->usTransID = m_usCurrentProcID;
    pDNSHeader->usFlags = htons(0x0100);
    pDNSHeader->usQuestionCount = htons(0x0001);
    pDNSHeader->usAnswerCount = 0x0000;
    pDNSHeader->usAuthorityCount = 0x0000;
    pDNSHeader->usAdditionalCount = 0x0000;

    //设置DNS查询报文内容
    USHORT usQType = htons(0x0001);
    USHORT usQClass = htons(0x0001);
    USHORT nDomainNameLen = strlen(szDomainName);
    char *szEncodedDomainName = (char *)malloc(nDomainNameLen + 2);
    if (szEncodedDomainName == NULL)
    {
        return FALSE;
    }
    if (!EncodeDotStr(szDomainName, szEncodedDomainName, nDomainNameLen + 2))
    {
        return FALSE;
    }

    //填充DNS查询报文内容
    USHORT nEncodedDomainNameLen = strlen(szEncodedDomainName) + 1;
    memcpy(pWriteDNSPacket += sizeof(DNSHeader), szEncodedDomainName, nEncodedDomainNameLen);
    memcpy(pWriteDNSPacket += nEncodedDomainNameLen, (char*)(&usQType), DNS_TYPE_SIZE);
    memcpy(pWriteDNSPacket += DNS_TYPE_SIZE, (char*)(&usQClass), DNS_CLASS_SIZE);
    free(szEncodedDomainName);

    //发送DNS查询报文
    USHORT nDNSPacketSize = sizeof(DNSHeader) + nEncodedDomainNameLen + DNS_TYPE_SIZE + DNS_CLASS_SIZE;
    if (sendto(m_sock, m_szDNSPacket, nDNSPacketSize, 0, (sockaddr*)&sockAddrDNSServer, sizeof(sockAddrDNSServer)) == SOCKET_ERROR)
    {
        return FALSE;
    }

    return TRUE;
}

BOOL RecvDNSResponse(sockaddr_in sockAddrDNSServer, ULONG ulTimeout, std::vector<ULONG> *pveculIPList, std::vector<std::string> *pvecstrCNameList, ULONG *pulTimeSpent)
{
    ULONG ulSendTimestamp = GetTickCountCalibrate();

    if (pveculIPList != NULL)
    {
        pveculIPList->clear();
    }
    if (pvecstrCNameList != NULL)
    {
        pvecstrCNameList->clear();
    }

    char recvbuf[1024] = { '\0' };
    char szDotName[128] = { '\0' };
    USHORT nEncodedNameLen = 0;

    while (TRUE)
    {
        if (WSAWaitForMultipleEvents(1, &m_event, FALSE, 100, FALSE) != WSA_WAIT_TIMEOUT)
        {
            WSANETWORKEVENTS netEvent;
            WSAEnumNetworkEvents(m_sock, m_event, &netEvent);

            if (netEvent.lNetworkEvents & FD_READ)
            {
                ULONG ulRecvTimestamp = GetTickCountCalibrate();
                int nSockaddrDestSize = sizeof(sockAddrDNSServer);

                //接收响应报文
                if (recvfrom(m_sock, recvbuf, 1024, 0, (struct sockaddr*)&sockAddrDNSServer, &nSockaddrDestSize) != SOCKET_ERROR)
                {
                    DNSHeader *pDNSHeader = (DNSHeader*)recvbuf;
                    USHORT usQuestionCount = 0;
                    USHORT usAnswerCount = 0;

                    if (pDNSHeader->usTransID == m_usCurrentProcID
                        && (ntohs(pDNSHeader->usFlags) & 0xfb7f) == 0x8100 //RFC1035 4.1.1(Header section format)
                        && (usQuestionCount = ntohs(pDNSHeader->usQuestionCount)) >= 0
                        && (usAnswerCount = ntohs(pDNSHeader->usAnswerCount)) > 0)
                    {
                        char *pDNSData = recvbuf + sizeof(DNSHeader);

                        //解析Question字段
                        for (int q = 0; q != usQuestionCount; ++q)
                        {
                            if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName)))
                            {
                                return FALSE;
                            }
                            pDNSData += (nEncodedNameLen + DNS_TYPE_SIZE + DNS_CLASS_SIZE);
                        }

                        //解析Answer字段
                        for (int a = 0; a != usAnswerCount; ++a)
                        {
                            if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName), recvbuf))
                            {
                                return FALSE;
                            }
                            pDNSData += nEncodedNameLen;

                            USHORT usAnswerType = ntohs(*(USHORT*)(pDNSData));
                            USHORT usAnswerClass = ntohs(*(USHORT*)(pDNSData + DNS_TYPE_SIZE));
                            ULONG usAnswerTTL = ntohl(*(ULONG*)(pDNSData + DNS_TYPE_SIZE + DNS_CLASS_SIZE));
                            USHORT usAnswerDataLen = ntohs(*(USHORT*)(pDNSData + DNS_TYPE_SIZE + DNS_CLASS_SIZE + DNS_TTL_SIZE));
                            pDNSData += (DNS_TYPE_SIZE + DNS_CLASS_SIZE + DNS_TTL_SIZE + DNS_DATALEN_SIZE);

                            if (usAnswerType == DNS_TYPE_A && pveculIPList != NULL)
                            {
                                ULONG ulIP = *(ULONG*)(pDNSData);
                                pveculIPList->push_back(ulIP);
                            }
                            else if (usAnswerType == DNS_TYPE_CNAME && pvecstrCNameList != NULL)
                            {
                                if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName), recvbuf))
                                {
                                    return FALSE;
                                }
                                pvecstrCNameList->push_back(szDotName);
                            }

                            pDNSData += (usAnswerDataLen);
                        }

                        //计算DNS查询所用时间
                        if (pulTimeSpent != NULL)
                        {
                            *pulTimeSpent = ulRecvTimestamp - ulSendTimestamp;
                        }

                        break;
                    }
                }
            }
        }

        //超时退出
        if (GetTickCountCalibrate() - ulSendTimestamp > ulTimeout)
        {
            *pulTimeSpent = ulTimeout + 1;
            return FALSE;
        }
    }

    return TRUE;
}

代码整体打包已上传

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DNS请求响应 的相关文章

  • 网络基础面试题(二)

    11 什么是网桥 防火墙的端口防护是指什么 网桥是一种网络设备 用于连接两个或多个局域网 LAN 并转发数据包 它能够根据MAC地址来识别和转发数据 提高网络的传输效率和安全性 防火墙的端口防护是指对防火墙上的各个端口进行保护和限制 只允许
  • pandas用法整理

    处理表格数据的时候经常用到pandas 每次用的时候都要去查函数 每次记不住 每次都查 哈哈哈 自己整理一下 码住 一 Pandas的数据类型 进行数据分析时 如何正确使用数据类型 这非常重要 在pandas中的数据类型和python原生数
  • 改善python程序的91建议记录

    使用else子句简化循环 异常处理 案例1 执行sql异常时处理 def save db obj try save attr1 db execute a sql stmt obj attr1 save attr2 db execute an
  • 浅谈能耗系统在马来西亚连锁餐饮业的应用

    1 背景信息 Background 针对连锁餐饮业能耗高且能源管理不合理的问题 利用计算机网络技术 通讯技术 计量控制技术等信息化技术 实现能源资源分类分项计量和能源资源运行监管功能 清晰描述各分店总的用能现状 实时监测各供电回路的电压 电
  • CMAKE_MAKE_PROGRAM is not set 解读

    目录 CMAKE MAKE PROGRAM 未设置 错误原因 解决方案 示例1 GNU Make 示例2 Ninja CMakeLists txt 的结构 示例 CMakeLists txt 文件 总结 CMAKE MAKE PROGRAM
  • CTF之逆向入门

    逆向工程 Reverse Engineering 又称反向工程 是一种技术过程 即对一项目标产品进行逆向分析及研究 从而演绎并得出该产品的处理流程 组织结构 功能性能规格等设计要素 以制作出功能相近 但又不完全一样的产品 逆向工程源于商业及
  • 自定义编写zabbix_agent脚本

    vi usr lib systemd system zabbix agent servicce Unit Description Zabbix Agent After syslog target After network target S
  • 【CTF必看】从零开始的CTF学习路线(超详细),让你从小白进阶成大神!

    最近很多朋友在后台私信我 问应该怎么入门CTF 个人认为入门CTF之前大家应该先了解到底 什么是CTF 而你 学CTF的目的又到底是什么 其次便是最好具备相应的编程能力 若是完全不具备这些能力极有可能直接被劝退 毕竟比赛的时候动不动写个脚本
  • 5个步骤,教你瞬间明白线程和线程安全

    记得今年3月份刚来杭州面试的时候 有一家公司的技术总监问了我这样一个问题 你来说说有哪些线程安全的类 我心里一想 这我早都背好了 稀里哗啦说了一大堆 他又接着问 那你再来说说什么是线程安全 然后我就GG了 说真的 我们整天说线程安全 但是对
  • 【信道估计】【MIMO】【FBMC】未来移动通信的滤波器组多载波调制方案(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 用户数据中的幸存者偏差

    幸存者偏差 Survivorship bias 是一种常见的逻辑谬误 意思是没有考虑到筛选的过程 忽略了被筛选掉的关键信息 只看到经过筛选后而产生的结果 先讲个故事 二战时 无奈德国空防强大 盟军战机损毁严重 于是军方便找来科学家统计飞机受
  • 2024年金三银四网络安全考试试题

    2023年金三银四网络安全考试试题 1 关于数据使用说法错误的是 A 在知识分享 案例中如涉及客户网络数据 应取敏感化 不得直接使用 B 在公开场合 公共媒体等谈论 传播或发布客户网络中的数据 需获得客户书面授权或取敏感化 公开渠道获得的除
  • 「网络安全渗透」如果你还不懂CSRF?这一篇让你彻底掌握

    1 什么是 CSRF 面试的时候的著名问题 谈一谈你对 CSRF 与 SSRF 区别的看法 这个问题 如果我们用非常通俗的语言讲的话 CSRF 更像是钓鱼的举动 是用户攻击用户的 而对于 SSRF 来说 是由服务器发出请求 用户 日 服务器
  • HPE Aruba Networking:五大网络现代化策略助力实现校园数字化转型

    作者 Aruba中国区技术销售总监 俞世丹 全球数字化进程日益加深 科技已成为加速教育行业发展的重要驱动力 人工智能 大数据 云计算 物联网 虚拟现实等新兴技术的快速发展 正在深刻改变着教育的形态和模式 为了更好地满足学校师生个性化教育教学
  • 基于java的物业管理系统设计与实现

    基于java的物业管理系统设计与实现 I 引言 A 研究背景和动机 物业管理系统是指对物业进行管理和服务的系统 该系统需要具备对物业信息 人员信息 财务信息等进行管理的能力 基于Java的物业管理系统设计与实现的研究背景和动机主要体现在以下
  • tcpdump抓包

    tcpdump抓包 基本概念 1 类型的关键字 host 指明一台主机 如 host 10 1 110 110 net 指明一个网络地址 如 net 10 1 0 0 port 指明端口号 如 port 8090 2 确定方向的关键字 sr
  • 服务器VPS是什么意思?一文了解其含义与重要性

    在今天的数字时代 服务器扮演着至关重要的角色 它们是网站 应用程序和在线业务的基石 但是 你是否听说过VPS 本文将深入探讨什么是服务器VPS 以及为什么它在今天的互联网世界中如此重要 什么是服务器VPS 服务器的基本概念 在我们深入探讨V
  • 服务器中E5和I9的区别是什么,如何选择合适的配置

    随着科技的进步 服务器处理器的性能在不断攀升 其中 Intel的E5和I9系列处理器在业界具有广泛的影响力 而当我们在选择服务器的时候会有各种各样的配置让我们眼花缭乱不知道该怎么去选择 下面我跟大家分享一下E5跟I9有什么区别 方便我们在选
  • 2023下半年软考「单独划线」合格标准公布

    中国计算机技术职业资格网发布了 关于2023年度下半年计算机软件资格考试单独划线地区合格标准的通告 2023下半年软考单独划线地区合格标准各科目均为42分 01 官方通告 关于2023年度下半年计算机软件资格考试单独划线地区合格标准的通告
  • 网工内推 | 上市公司同程、科达,五险一金,年终奖,最高12k*15薪

    01 同程旅行 招聘岗位 网络工程师 职责描述 1 负责职场 门店网络规划 建设 维护 2 负责网络安全及访问控制 上网行为管理和VPN设备的日常运维 3 负责内部相关网络自动化和系统化建设 4 优化与提升网络运行质量 制定应急预案 人员培

随机推荐

  • Docker Swarm 创建服务

    Docker Swarm 创建服务 环境 系统 Centos 7 4 x64 应用版本 Docker 18 09 0 管理节点 192 168 1 79 工作节点 192 168 1 78 工作节点 192 168 1 77 1 管理节点
  • LeetCode 1800. 最大升序子数组和

    题目链接 https leetcode cn problems maximum ascending subarray sum 时间复杂度为 O n O n O n 空间复杂度为 O
  • 大学生科技创意大赛查新报告

    大学生科技创意大赛是什么 太多种类分不清 快来看 大学生科技创意大赛需要查新怎么办 去哪儿能办 大学生科技创意大赛的查新需要准备什么材料 大学生科技创意大赛科技查新报告是什么样子的 一 大学生科技创意大赛是什么 太多种类分不清 快来看 大学
  • 如何获取使用某个table的所有存储过程

    select distinct object name id from syscomments where id in select object id from sys objects where type P and text like
  • 目标识别、目标跟踪算法总结

    想自学图像处理的相关知识 正好实验室师兄做过两个关于红外目标跟踪的项目 因此从mean shift SR RP PF开始学习 但是查阅资料的时候 发现对各种算法理解非常 利用图像处理算法 实现的功能一般包括 目标的检测 识别 跟踪 常见的问
  • 机器学习顶刊文献_哪些成为了经典-引用次数最多的10篇机器学习文献

    近40年来机器学习领域产生了数以万计的论文 并以每年上万篇的速度增长 但真正能够称为经典 经受住历史检验 能投入实际应用的并不多 本文整理了机器学习历史上出现的经典论文 按照被引用次数对它们进行了排序 分为top10 被引用次数超过2万 被
  • FreeModbus的移植

    FreeModbus V1 6 主机使用说明 一 简述 FreeModbus是一款开源的Modbus协议栈 但是只有从机开源 主机源码是需要收费的 同时网上也没有发现比较好的开源的Modbus主机协议栈 所以才开发这款支持主机模式的Free
  • 【Docker】使用Docker在远程服务器上安装MySQL8并使用本地navicat连接

    使用Docker在远程服务器上安装MySQL8并使用本地navicat连接 一 下载MySQL8镜像 二 启动MySQL容器 三 配置MySQL数据库的远程访问 使用本地navicat连接服务器MySQL 四 docker中删除已创建的容器
  • 虚拟机使用情况(持续更新)

    装了虚拟机后今天打开发现文字变成了英文的 并且装好的系统打不开机 出现提示 本来用的好好的 怎么就出问题了呢 回忆起来最后使用时为了方便整理磁盘 把安装在E盘的所有虚拟机文件都放在一个命名文件里 我恢复原样后就正常使用了 可能是之前下载的时
  • 操作系统之PV操作

    基本概念 进程状态 进程通常分为就绪 运行和阻塞三个工作状态 三种状态在某些条件下可以转换 三者之间的转换关系如下 进程三个状态之间的转换就是靠PV操作来控制的 PV操作主要就是P操作 V操作和信号量 其中信号量起到了至关重要的作用 信号量
  • 微信小程序分享页面代码

    在微信小程序中实现分享功能需要以下几个步骤 1 在 app json 文件中配置分享参数 例如标题 路径等 示例如下 json pages pages index index window navigationBarTitleText 小程
  • java print\println\printf的区别

    printf主要是继承了C语言的printf的一些特性 可以进行格式化输出 print就是一般的标准输出 但是不换行 print将它的参数显示在命令窗口 并将输出光标定位在所显示的最后一个字符之后 println www infocool
  • 源NAT,目的NAT和PAT以及端口映射的区别?

    一 NAT 1 动态NAT 地址复用 指将内部私有IP转换为公网IP地址时 IP的对应关系是不确定的 也就是说只要指定哪些内部地址可以进行NAT转换 以及哪些可以的合法的IP地址可以作为外部地址 就可以进行动态转换了 也可以使用多个合法地址
  • unity3d运行后自动暂停_Unity3D 关于延迟、暂停执行脚本的几个方法总结

    1 InvokeRepeating函数 和 Invoke函数 个人认为最为有效方法 用法 InvokeRepeating delayOpen 1 5 1秒后调用 delayOpen 函数 之后每5秒调用一次 写在Start函数内 Invok
  • python实现时间序列信号的频谱、倒频谱以及功率谱

    python实现时间序列信号的频谱 倒频谱以及功率谱 认识傅里叶变换 一 频谱 1 引入库 2 频谱函数封装 二 功率谱 功率谱谱函数封装 三 倒频谱 倒频谱谱函数封装 以振动信号为例 认识傅里叶变换 这里我就不多说了 百度谷歌一大堆说的明
  • /sys/module/ 模块信息 目录与/proc/modules文件

    在内核模块编译中 会选择编译成模块 或者build in 内核镜像中 其中对内核模块有很好的的说明 这也是linux在嵌入式当中得到广泛应用的充分体现 内核中有很多功能选项 其中有许多使我们不需要的 内核设计成模块的优势所在就在这里 不需要
  • Android java.lang.UnsatisfiedLinkError: No implementation found

    例如 该项目的如下报错 java lang UnsatisfiedLinkError No implementation found for void org webrtc PeerConnectionFactory nativeIniti
  • Python 环境变量配置详解

    文章目录 1 配置前准备 1 1 检查环境变量是否配置成功 1 2 查询 python exe 的安装路径 2 配置步骤 2 1 进入高级系统设置 2 2 设置环境变量 2 1 1 配置 Python exe 所在路径 2 2 1 配置 p
  • GIT 仓库 子模块 SUBMODULE 拉取子仓库代码

    找到 gitmodules 文件所在的目录 在该目录下运行命令 git submodule init git submodule update
  • DNS请求响应

    问题背景 在无线网络可用 而有线网络不可用的场景下 依靠第三方接口解析域名 或者udp tcp接口内部解析域名 会默认阻塞10秒钟 办法 自行定制dns请求及响应 BOOL SendDNSRequest sockaddr in sockAd