DNS 从域名字段解析看网络协议巧妙的设计

简介

DNS协议 大家都比较熟悉,平时访问的网站是容易记忆的域名地址 ,但是对于机器来说,通信最终路由得靠IP地址,而dns协议主要的目的也就是做一下域名和IP之间的转换。

dns协议属于cs模式,客户端发送dns请求报文到dns服务器,dns服务器收到后进行处理并返回dns响应报文;这里详细说明一下域名字段在报文中的编码格式,感受下网路协议设计有什么巧妙之处。

示例

STEP1、请求www.baidu.com

bash 复制代码
[xiaofeng@localhost ~]$ dig www.baidu.com

; <<>> DiG 9.11.26-RedHat-9.11.26-6.el8 <<>> www.baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12912
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.baidu.com.                 IN      A

;; ANSWER SECTION:
www.baidu.com.          529     IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       25      IN      CNAME   www.wshifen.com.
www.wshifen.com.        158     IN      A       119.63.197.151
www.wshifen.com.        158     IN      A       119.63.197.139

;; Query time: 133 msec
;; SERVER: 208.91.112.52#53(208.91.112.52)
;; WHEN: Fri Mar 22 14:51:51 CST 2024
;; MSG SIZE  rcvd: 127

[xiaofeng@localhost ~]$

STEP2 抓包分析

tcpdump -i ens192 port 53 -envvv -w dns.pcap

DNS请求报文

DNS响应报文

STEP3 编码分析

www.baidu.com 域名在请求报文中和响应报文中第一次出现的十六进制如下:

03 77 77 77 05 62 61 69 64 75 03 63 6f 6d 00

  1. 第一个标签长度字节03,表示后续三个字节是域名的www
  2. 第二个标签长度字节05,表示后续五个字节是域名的baidu
  3. 第三个标签长度字节03,表示后续三个字节是域名的com
  4. 第四个标签长度字节00,标识结束
  5. 然后将每段标签用点进行连接即得到完整的域名www.baidu.com

www.baidu.com 域名在响应报文中第二次出现的十六进制如下:

c0 0c

  1. 第一个字节c0,表示域名出现过,使用指针方式(前两位为11作为标识
  2. 第二个字节0c,为域名第一次出现的偏移这里就是Queies中www.baidu.com 所在的偏移量,即dns头的长度12字节

总结

  1. 域名被编码为一些labels序列,每个labels包含一个字节表示后续字符串长度,以及这个字符串,以0长度和空字符串来表示域名结束。
  2. 如果一个域名在前面已经出现过,那么可以用指针来代替它。指针的格式为两个字节,第一个字节的前两位为 11,后面14位为指向之前出现过的域名的偏移量,偏移量是相对于DNS报文的起始位置计算的。
  3. 通过标签序列可以灵活的表示域名字段,同时利用指针偏移的方式来整体压缩减少报文长度。
相关推荐
imuliuliang3 分钟前
Spring Boot(快速上手)
java·spring boot·后端
yashuk12 分钟前
Spring Boot 3.4 正式发布,结构化日志!
java·spring boot·后端
想打游戏的程序猿10 小时前
核心概念层——深入理解 Agent 是什么
后端·ai编程
woniu_maggie11 小时前
SAP Web Service日志监控:如何用SRT_UTIL快速定位接口问题
后端
一线大码11 小时前
Java 使用国密算法实现数据加密传输
java·spring boot·后端
Rust语言中文社区11 小时前
【Rust日报】用 Rust 重写的 Turso 是一个更好的 SQLite 吗?
开发语言·数据库·后端·rust·sqlite
F1FJJ12 小时前
只是想查个数据,不想装 phpMyAdmin
数据库·网络协议·容器·开源软件
在屏幕前出油13 小时前
06. FastAPI——中间件
后端·python·中间件·pycharm·fastapi
wuqingshun31415913 小时前
说一下spring的bean的作用域
java·后端·spring
F1FJJ14 小时前
Shield CLI:MySQL 插件 vs phpMyAdmin:轻量 Web 数据库管理工具对比
前端·网络·数据库·网络协议·mysql·容器