Init
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
---
|
||||
tags: [计算机网络, DNS, DHCP, WebSocket]
|
||||
create time: 2026-05-18 03:10
|
||||
---
|
||||
|
||||
# DNS / DHCP / WebSocket
|
||||
|
||||
## 一、DNS 原理与优化
|
||||
|
||||
### DNS 查询流程(递归 vs 迭代)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户浏览器
|
||||
participant LRD as 本地 DNS Resolver<br/>ISP 或 1.1.1.1/9.9.9.9
|
||||
participant TLD as TLD Server<br/>.com
|
||||
participant AUTH as Authoritative NS<br/>example.com
|
||||
|
||||
U->>LRD: 递归查询 "example.com?"
|
||||
|
||||
Note over LRD: 检查本地缓存...
|
||||
LRD->>TLD: 迭代查询 ".com?"
|
||||
TLD-->>LRD: "去问 example.com 的 NS"
|
||||
|
||||
LRD->>AUTH: 迭代查询 "example.com A 记录?"
|
||||
AUTH-->>LRD: 93.184.216.34
|
||||
|
||||
Note over LRD: TTL=300 → 缓存 5 分钟
|
||||
LRD-->>U: ✅ 93.184.216.34
|
||||
```
|
||||
|
||||
### 关键概念
|
||||
|
||||
| 术语 | 说明 |
|
||||
|------|------|
|
||||
| **Recursion Desired (RD)** | 客户端要求 DNS 服务器递归查找 |
|
||||
| **Authority Section** | 指向下一级的授权 NS |
|
||||
| **CNAME Chain** | 别名链,最多 63 层嵌套 |
|
||||
| **TTL** | Time To Live,缓存有效期(秒) |
|
||||
| **ANAME/ALIAS** | 根域名的 CNAME 替代方案 |
|
||||
| **Any 查询** | `query type = ANY`,RFC 8753 建议禁用 |
|
||||
|
||||
### 常见记录类型
|
||||
|
||||
| 类型 | 名称 | 用途 | 示例 |
|
||||
|------|------|------|------|
|
||||
| A | Address | IPv4 地址 | `@ A 93.184.216.34` |
|
||||
| AAAA | Address V6 | IPv6 地址 | `@ AAAA 2606:2800:220:1:248:1893:25c8:1946` |
|
||||
| CNAME | Canonical Name | 别名 | `www CNAME example.com` |
|
||||
| MX | Mail Exchange | 邮件服务器优先级 | `@ MX 10 mail.example.com` |
|
||||
| TXT | Text | SPF/DKIM/域名验证 | `v=spf1 include:_spf.google.com ~all` |
|
||||
| SRV | Service | 服务定位 | `_sip._tcp SVC 1 0 5060 sip.example.com` |
|
||||
| NS | Name Server | 授权 NS 记录 | `@ NS ns1.provider.com` |
|
||||
| PTR | Pointer | 反向解析 (IP → 域名) | `34.216.184.93.in-addr.arpa PTR example.com` |
|
||||
| SOA | Start of Authority | 区域文件起始权威记录 | `ns1 admin email serial refresh retry expire minimum` |
|
||||
| DS / DNSKEY | — | DNSSEC 签名验证 | — |
|
||||
|
||||
### DNS 缓存层次
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Tier 1: Application/CPU Cache │ ← Go sync.Map / HTTP cache header
|
||||
│ TTL controlled by Content-TTL │ Browser cache varies 0~30min
|
||||
├─────────────────────────────────────┤
|
||||
│ Tier 2: OS Resolver Cache │ ← nscd / systemd-resolved / DNSMasq
|
||||
│ Linux: nscd (default off!) │ macOS: mDNSResponder
|
||||
│ macOS: mDNSResponder (~120s) │ Windows: Dnscache
|
||||
├─────────────────────────────────────┤
|
||||
│ Tier 3: ISP / Recursive Resolver │ ← Cloudflare 1.1.1.1, Google 8.8.8.8
|
||||
│ TTL from authoritative server │ 通常 60~300s 最小缓存
|
||||
├─────────────────────────────────────┤
|
||||
│ Tier 4: TLD + Authoritative │ ← .com NS → example.com NS
|
||||
│ No user-controlable caching │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### DNS-over-HTTPS / DNS-over-TLS
|
||||
|
||||
| 协议 | RFC | 端口 | 特点 |
|
||||
|------|-----|------|------|
|
||||
| DoH (DNS over HTTPS) | 8484 | 443 (TCP) | 伪装成 HTTPS 流量,CDN 友好 |
|
||||
| DoT (DNS over TLS) | 7858 | 853 (TCP) | 专用加密通道 |
|
||||
| DoQ (DNS over QUIC) | 9230 | 853 (UDP via QUIC) | HTTP/3 风格 |
|
||||
|
||||
```bash
|
||||
# Linux 启用 DoH
|
||||
$ resolvectl dns eth0 1.1.1.1
|
||||
$ resolvectl domain eth0 "~."
|
||||
|
||||
# dig 指定 DNS 服务器
|
||||
$ dig @1.1.1.1 example.com +short
|
||||
93.184.216.34
|
||||
```
|
||||
|
||||
## 二、DHCP 自动分配
|
||||
|
||||
### DHCP 四步交互(DORA)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 新设备<br/>(无 IP)
|
||||
participant Server as DHCP Server
|
||||
|
||||
Note over Client: BOOTING state, src_ip=0.0.0.0
|
||||
Client->>Server: DHCPDISCOVER (broadcast ff:ff:ff:ff:ff:ff)
|
||||
Note over Server: 收到后从可用池选择一个 IP
|
||||
|
||||
Server-->>Client: DHCPOFFER (ip=x.x.x.x, lease_time=T, gw=y.y.y.y)
|
||||
Note over Client: SELECTING state
|
||||
|
||||
Client->>Server: DHCPREQUEST (requested ip=x.x.x.x)
|
||||
Note over Server: 确认分配
|
||||
|
||||
Server-->>Client: DHCPACK (confirmed allocation)
|
||||
Note over Client: BOUND state ✅ IP = x.x.x.x
|
||||
```
|
||||
|
||||
### DHCP 续租机制
|
||||
|
||||
```
|
||||
租约时间 = Lease Time(默认通常 24h)
|
||||
|
||||
续约时机:
|
||||
• T1 = 50% 租约时 → RENEW (单播到原服务器)
|
||||
• T2 = 87.5% 租约时 → REBIND (广播到新服务器)
|
||||
• 到期前必须续约成功,否则释放 IP
|
||||
```
|
||||
|
||||
```bash
|
||||
# Linux DHCP 客户端配置
|
||||
$ cat /etc/dhcp/dhclient.conf
|
||||
timeout 300; # 超时重试间隔
|
||||
retry 60; # 初始重试间隔
|
||||
reboot 10; # 重启时重尝试获取 IP
|
||||
request subnet-mask, broadcast-address, time-offset, routers;
|
||||
|
||||
# 手动刷新 IP
|
||||
$ sudo dhclient -r eth0 # release
|
||||
$ sudo dhclient eth0 # request new
|
||||
```
|
||||
|
||||
## 三、WebSocket 全双工通信
|
||||
|
||||
### 为什么需要 WebSocket?
|
||||
|
||||
```
|
||||
传统轮询 vs WebSocket:
|
||||
═══════════════════════
|
||||
Polling: Client ─→ GET /status ─→ empty
|
||||
Client ─→ GET /status ─→ {"msg": "hi"}
|
||||
Client ─→ GET /status ─→ empty
|
||||
... 浪费带宽,延迟高
|
||||
|
||||
Long Polling:
|
||||
Client ─→ GET /status (挂起) ─→ ...等待... ─→ {"msg": "hi"}
|
||||
Client ─→ GET /status (再挂起) ─→ ...
|
||||
|
||||
WebSocket ✨:
|
||||
Client ─── 握手升级 ───→ 持久双向通道
|
||||
Server ─── 推送消息 ───→ Client
|
||||
Client ─── 推送消息 ───→ Server
|
||||
← 全双工、低开销! -->
|
||||
```
|
||||
|
||||
### WebSocket 握手升级过程
|
||||
|
||||
```
|
||||
HTTP 请求 → WebSocket → HTTP 响应
|
||||
|
||||
Client: Server:
|
||||
GET /ws/chat HTTP/1.1 101 Switching Protocols
|
||||
Host: chat.example.com Upgrade: websocket
|
||||
Upgrade: websocket Connection: Upgrade
|
||||
Connection: Upgrade Sec-WebSocket-Accept: <base64-hash>
|
||||
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
||||
Sec-WebSocket-Version: 13
|
||||
```
|
||||
|
||||
**关键:** 这不是 TCP 层面的升级,而是 HTTP 协议的升级——服务器返回 `101` 状态码告诉客户端:"好的,我们从这里开始用 WebSocket 协议"。
|
||||
|
||||
### Sec-WebSocket-Accept 计算
|
||||
|
||||
```go
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const magicGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
|
||||
|
||||
func computeAccept(key string) string {
|
||||
h := sha1.New()
|
||||
h.Write([]byte(key + magicGUID))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// 例: key = "dGhlIHNhbXBsZSBub25jZQ=="
|
||||
// accept = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
|
||||
```
|
||||
|
||||
### WebSocket Frame 格式
|
||||
|
||||
```
|
||||
┌───────────┬───────────┬─────────────┬───────────────┬────────────────┐
|
||||
│ FIN(1 bit)│ RSV(3bit) │ Opcode(4bit)│ Mask(1 bit) │ Payload Len │
|
||||
│ │ │ │ │ + Ext Len │
|
||||
├───────────┴───────────┴─────────────┴───────────────┼────────────────┤
|
||||
│ Extended Payload Length │ Mask Key │
|
||||
│ (0, 126, or 127 bytes) │ (4 bytes) │
|
||||
├─────────────────────────────────────────────────────┴────────────────┤
|
||||
│ Masked Payload Data (variable) │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
| Opcode | 含义 |
|
||||
|--------|------|
|
||||
| 0x0 | Continuation frame |
|
||||
| 0x1 | Text frame |
|
||||
| 0x2 | Binary frame |
|
||||
| 0x8 | Connection Close |
|
||||
| 0x9 | Ping |
|
||||
| 0xA | Pong |
|
||||
|
||||
### Go 中的 WebSocket
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true // 生产环境应严格校验 Origin
|
||||
},
|
||||
}
|
||||
|
||||
func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Println("upgrade error:", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
for {
|
||||
mt, message, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", message)
|
||||
conn.WriteMessage(mt, message)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/ws", wsHandler)
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
```
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[hhs/NETWORK/HTTPS与TLS握手]] — SNI 扩展在 DNS 解析中的应用
|
||||
- [[hhs/NETWORK/WebSocket全双工通信]] — 心跳机制防止 NAT/代理超时断开
|
||||
- [[hhs/NETWORK/NAT原理与应用]] — WebSocket 也受 NAT 影响
|
||||
Reference in New Issue
Block a user