当前位置: 首页 > article >正文

librdns一个开源DNS解析库

原文地址: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.kler.cn/a/405346.html

相关文章:

  • JAVA八股与代码实践----JDK代理和CGLIB代理的区别
  • 【从零开始的LeetCode-算法】3233. 统计不是特殊数字的数字数量
  • 巧用观测云可用性监测(云拨测)
  • ara::com 与 AUTOSAR 元模型的关系总结
  • 算法.图论-习题全集(Updating)
  • ubuntu18.04 vscode c++ filesystem 使用
  • 垂起固定翼无人机搭载高清三光(4K可见+红外+激光测距)吊舱图像采集技术详解
  • FileProvider高版本使用,跨进程传输文件
  • 主IP地址与从IP地址:深入解析与应用探讨
  • 锂电池学习笔记(一) 初识锂电池
  • 浅谈Python库之lxml
  • 24小时自动监控,自动录制直播蓝光视频!支持抖音等热门直播软件
  • RUST学习教程-安装教程
  • 使用 PyTorch TunableOp 加速 ROCm 上的模型
  • QT FTP的方式访问其他电脑文件
  • 【vue3+vite】新一代vue脚手架工具vite,助力前端开发更快捷更高效
  • 【http】http协议状态码
  • DataWorks快速入门
  • 【1.4 Getting Started--->Support Matrix】
  • aws建立多区域只读库
  • sigmoid和softmax的异同以及对应的loss解析
  • Java解析视频FPS(帧率)、分辨率信息
  • MySQL UPDATE语句执行链路解析
  • 攻克OCR手写识别难点!InkSight教程上线,实现高精度转写;iNatSounds数据集发布,含23万自然物种音频
  • K8S资源限制之LimitRange
  • VUE:基于MVVN的前端js框架