librdns一个开源DNS解析库

news2024/11/25 4:18:27

原文地址:librdns一个开源DNS解析库 – 无敌牛

欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等

介绍

librdns是一个开源的异步多功能插件式的解析器,用于DNS解析。

源代码地址:GitHub - vstakhov/librdns: Asynchronous DNS resolver

librdns使用libev和libevent的方式集成,来实现异步操作。

关于DNS相关知识参看往期文章:DNS记录这件小事 – 无敌牛

关于libev的介绍参看往期文章:libev监听IO事件 – 无敌牛

编译安装

下载源文件,指令:git clone https://github.com/vstakhov/librdns.git

编译,先进入拉取的源代码目录,然后执行:mkdir build && cd build && cmake .. && make -j 5

安装,主要是把编译后的so库和需要引用的头文件拿到系统目录。执行指令:cp lib* ../include/* /usr/local/include/。然后重新加载系统动态库 ldconfig

测试示例

在 librdns 源代码里已经有两个测试文件,我这里做了一些修改,把获取到的数据打印了出来。代码如下:

trdns.c

// gcc -Wall -o test trdns.c -lev -lrdns

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "rdns.h"
#include "rdns_curve.h"
#include "rdns_ev.h"

#define LL_FOREACH_SAFE(head,el,tmp)                                    \
    LL_FOREACH_SAFE2(head,el,tmp,next)

#define LL_FOREACH_SAFE2(head,el,tmp,next)                              \
  for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)


static int remain_tests = 0;

static void
rdns_regress_callback (struct rdns_reply *reply, void *arg)
{
    // 获取有多少个查询项
    unsigned int count ;
    const struct rdns_request_name* names = rdns_request_get_name (reply->request, &count);
    for( int i=0 ; i < count ; ++i ) {
        printf ("===========================\ncount %d host: %s type: %d result\n", count, names[i].name, names[i].type ) ;
    }

    // 判断是否获取DNS成功
    if(reply->code != RDNS_RC_NOERROR) {
        printf("failed code : %d\n", reply->code) ;
        if (--remain_tests == 0) {
            rdns_resolver_release (reply->resolver);
        }
        return ;
    }

    // 遍历返回的结果实体
    struct rdns_reply_entry *entry, *tmp ;
    LL_FOREACH_SAFE (reply->entries, entry, tmp) {


        switch (entry->type) {
        case RDNS_REQUEST_MX :        // MX 结果
            printf("MX ===== record rslt is : %u %s\n", entry->content.mx.priority , entry->content.mx.name ) ;

            break ;
        case RDNS_REQUEST_A :        // A 结果
            char ip_str[16] ;
            inet_ntop(AF_INET, &entry->content.a.addr, ip_str, sizeof(ip_str) ) ;
            printf("A ===== record rslt is : %s\n", ip_str) ;

            break ;
        case RDNS_REQUEST_TXT :        // TXT 结果
            printf("TXT ===== rslt is : %s\n", entry->content.txt.data) ;

            break ;

        default :
            printf("wrong type : %u\n", entry->type) ;
        }
    }

    if (--remain_tests == 0) {
        // 减少 DNS解析服务器的引用,如果 为 0 则释放空间 
        // 同时会停止 libev 的 loop 循环
        rdns_resolver_release (reply->resolver);
    }
}



static void
rdns_test_a (struct rdns_resolver *resolver)
{
    char *names[] = {
            "baidu.com",
            "163.com",
            "qq.com",
            NULL
    };
    char **cur;

    for (cur = names; *cur != NULL; cur ++) {
        // 增加检测结果回调函数
        // 参数: DNS解析句柄、解析结果回调函数、回调函数参数、DNS查询超时时间(单位:秒)、失败重复查询次数、总共要做多少个查询、请求值、类型、请求值、类型...
        // 坑:当添加多个查询的时候,会超时,所以这里一个一个添加
        rdns_make_request_full (resolver, rdns_regress_callback, NULL, 5.0, 2, 1, *cur, RDNS_REQUEST_A );
        remain_tests++ ;
        rdns_make_request_full (resolver, rdns_regress_callback, NULL, 5.0, 2, 1, *cur, RDNS_REQUEST_MX);
        remain_tests++ ;
        rdns_make_request_full (resolver, rdns_regress_callback, NULL, 5.0, 2, 1, *cur, RDNS_REQUEST_TXT);
        remain_tests++ ;
    }
}

int
main(int argc, char **argv)
{
    struct rdns_resolver *resolver_ev;
    struct ev_loop *loop;

    // 创建 libev 监听轮询 loop 句柄
    loop = ev_default_loop (0);

    // 创建 DNS 解析器结构
    resolver_ev = rdns_resolver_new ();

    // 绑定 libev 的 loop 和 resolver_ev
    rdns_bind_libev (resolver_ev, loop);

    // 增加 DNS服务器信息 : argv[1] IP地址  argv[2] 端口号
    rdns_resolver_add_server (resolver_ev, argv[1], strtoul (argv[2], NULL, 10), 0, 8);

    // 初始化 DNS 解析器
    rdns_resolver_init (resolver_ev);

    // 添加测试
    rdns_test_a (resolver_ev);

    ev_loop (loop, 0);

    return 0;
}

编译测试

指令:gcc -Wall -o test trdns.c -lev -lrdns

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2247063.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

成都睿明智科技有限公司怎么样可靠不?

在这个日新月异的数字时代&#xff0c;电商行业如同一股不可阻挡的洪流&#xff0c;席卷着每一个消费者的生活。而抖音&#xff0c;作为短视频与电商完美融合的典范&#xff0c;更是为无数商家开辟了一片全新的蓝海。在这片充满机遇与挑战的海洋中&#xff0c;成都睿明智科技有…

栈的应用,力扣394.字符串解码力扣946.验证栈序列力扣429.N叉树的层序遍历力扣103.二叉树的锯齿形层序遍历

目录 力扣394.字符串解码 力扣946.验证栈序列 力扣429.N叉树的层序遍历 力扣103.二叉树的锯齿形层序遍历 力扣394.字符串解码 看见括号&#xff0c;由内而外&#xff0c;转向用栈解决。使用两个栈处理&#xff0c;一个用String,一个用Integer 遇到数字:提取数字放入到数字栈…

Vue3移动端-点餐项目

目录 一、项目构建 1、使用了vite构建vue3项目&#xff0c;其中支持如下图 2、其余路由配置、axios封装、组件封装 都与 后台管理系统 方式一致 二、Vant组件引入 1、安装 &#xff08;vue3使用vant4&#xff09;Vant官方文档 2、全局引入main.ts/js 3、如果是基于 Vite 的…

分词器的概念(通俗易懂版)

什么是分词器&#xff1f;分词器&#xff08;Tokenizer&#xff09;是自然语言处理&#xff08;NLP&#xff09;中的一个关键组件&#xff0c;它的主要功能是将文本数据分解成更小的单元&#xff0c;这些单元可以是单词、子词&#xff08;subword&#xff09;、字符或其他有意义…

【JavaEE进阶】 JavaScript

本节⽬标 了解什么是JavaScript, 学习JavaScript的常⻅操作, 以及使⽤JQuery完成简单的⻚⾯元素操作. 一. 初识 JavaScript 1.JavaScript 是什么 JavaScript (简称 JS), 是⼀个脚本语⾔, 解释型或即时编译型的编程语⾔. 虽然它是作为开发Web⻚⾯的脚本语⾔⽽出名&#xff0c;…

浮点数的表示—IEEE754标准

浮点数的表示—IEEE754标准 引言 我们知道&#xff0c;在计算机中&#xff0c;数字以0和1组成的二进制序列来表示。但是&#xff0c;对于非常大的数字以及非常接近0的数字&#xff0c;简单的存储方式往往会造成精度的丢失。 为了解决这个问题&#xff0c;提供更高效的浮点数…

uniapp vue2项目迁移vue3项目

uniapp vue2项目迁移vue3项目&#xff0c;必须适配的部分 一、main.js 创建应用实例 // 之前 - Vue 2 import Vue from vue import App from ./App Vue.config.productionTip false // vue3 不再需要 App.mpType app // vue3 不再需要 const app new Vue({ ...App }) …

计算机网络(14)ip地址超详解

先看图&#xff1a; 注意看第三列蓝色标注的点不会改变&#xff0c;A类地址第一个比特只会是0&#xff0c;B类是10&#xff0c;C类是110&#xff0c;D类是1110&#xff0c;E类是1111. IPv4地址根据其用途和网络规模的不同&#xff0c;分为五个主要类别&#xff08;A、B、C、D、…

Unity DOTS中的Entity

Unity DOTS中的Entity 在DOTS中entity往往只被看作一个ID&#xff0c;用来查找component&#xff0c;但实际上Unity为了有效地管理entity&#xff0c;在背后还做了一些其他的工作。首先是Entity类本身的定义&#xff0c;它的确跟一个ID差不多&#xff0c;只包含了两个int类型的…

SpringBoot实现单文件上传

一、在springBoot项目中的pom.xml添加依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> 二、在资源目录下的static目录下中创建一个upload.html的表单文件…

CNN—LeNet:从0开始神经网络学习,实战MNIST和CIFAR10~

文章目录 前言一、CNN与LeNet介绍二、LeNet组成及其名词解释2.1 输入2.2 卷积层2.3池化层2.4 全连接层2.5 总结 三、MNIST实战3.1 构建神经网络3.2 数据处理3.3 &#xff08;模板&#xff09;设置优化器&#xff0c;损失函数&#xff0c;使用gpu(如果是N卡有cuda核心)&#xff…

PVE系统中风扇驱动安装——linux 硬件驱动安装(IT8613E为例)

本文提供全流程命令代码,IT8613E的Github下载地址,pve头文件官方下载地址 对网卡驱动感兴趣的可以看这篇文章 linux系统下 usb网卡的驱动安装_0bda:a192-CSDN博客文章浏览阅读1.5w次,点赞16次,收藏72次。本文介绍如何通过lsusb查找USB网卡vid:pid,使用google搜索驱动信息…

美国人工智能国家安全备忘录核心解读(下)

文章目录 三、美国国内和国际人工智能治理策略1.保证AI政策有效执行的协调措施2.推进AI治理格局的优势地位&#xff08;1&#xff09;对于美国盟友&#xff1a;试图向盟友保证其将从美国的战略中获益。&#xff08;2&#xff09;对于美国的战略竞争对手&#xff1a;介绍了超越竞…

工具学习_Docker

0. Docker 简介 Docker 是一个开源平台&#xff0c;旨在帮助开发者构建、运行和交付应用程序。它通过容器化技术将应用程序及其所有依赖项打包在一个标准化的单元&#xff08;即容器&#xff09;中&#xff0c;使得应用程序在任何环境中都能保持一致的运行效果。Docker 提供了…

红黑树模拟实现STL中的map与set

1.map 在C标准模板库(STL)中&#xff0c;std::map是一种非常实用且强大的容器&#xff0c;它提供了键值对的存储机制。这使得std::map成为处理具有唯一关键的关联数据的理想选择。 1.1 map的特性 1、键值对存储&#xff1a;std::map通过键值对的形式存储数据&#xff0c;其中…

【数据结构专栏】二叉搜索树(Binary Search Tree)的剖析?

文章目录 &#x1f9e8;前言1、二叉搜索树的基本概念&#xff1f;2、二叉搜索树的节点结构组成&#xff1f;3、二叉搜索树的插入操作&#xff1f;4、二叉搜索树的删除操作&#xff1f;5、二叉搜索树的遍历&#xff1f; 6、二叉搜索树的性能分析&#xff1f; &#x1f389;完整代…

FastApi学习第三天:两表联查

两表联查 在 FastAPI 中&#xff0c;使用 Tortoise ORM 查询两表联查&#xff08;通常是通过外键关系进行联接&#xff09;是非常简单的。可以使用 select_related 或 prefetch_related 来执行联表查询&#xff0c;它们类似于 Django ORM 的 select_related 和 prefetch_relate…

Redis原理及应用

Redis简介 Redis是开源的&#xff08;BSD许可&#xff09;&#xff0c;数据结构存储于内存中&#xff0c;被用来作为数据库&#xff0c;缓存和消息代理。它支持多种数据结构&#xff0c;例如&#xff1a;字符串&#xff08;string&#xff09;&#xff0c;哈希&#xff08;hash…

Unity类银河战士恶魔城学习总结(P141 Finalising ToolTip优化UI显示)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ UI部分暂时完结&#xff01;&#xff01;&#xff01; 本章节优化了UI中物品描述的显示效果&#xff0c;技能描述的显示效果 并且可以批…

oracle的静态注册和动态注册

oracle的静态注册和动态注册 静态注册&#xff1a; 静态注册 : 指将实例的相关信息手动告知 listener 侦 听 器 &#xff0c; 可以使用netmgr,netca,oem 以及直接 vi listener.ora 文件来实现静态注册&#xff0c;在动态注册不稳定时使用&#xff0c;特点是&#xff1a;稳定&…