05-udp-raw-api
教程 05:从 udpecho_raw_init() 到 Echo Reply——UDP Raw API、PCB 与回调数据通路 摘要:从 UDP 数据报与端口分发模型出发,沿 Raw API 真实入口追踪 PCB 建立、接收匹配、回调、回包与 pbuf ownership。 [TOC] UDP(User Datagram Protocol,用户数据报协议)是 IP 之上的无连接传输协议。它把应用一次提交的一条消息作为一个 **datagram(数据报)**发送,并在接收端保留这条消息的边界;UDP 自身不先建立连接,也不保证可靠到达、顺序或自动重传。S4S6 本篇从 upstream Raw UDP Echo 的真实入口出发,重点回答:一个发往 UDP port 7 的 datagram,怎样被 udp_pcb 匹配、交给回调,再沿同一 PCB 发回发送端。 Stage 4 已经走到 ip4_input() 的上层协议分发。本篇只改变一个关键字段:IPv4 Header 的 Protocol 为 17 时,payload 交给 UDP;Ethernet、ARP 与 IP...
06-netconn-and-socket-api
教程 06:从 udpecho_thread() 到 Socket——Netconn、Mailbox 与顺序式 API 摘要:从应用线程与 lwIP Core 的执行边界出发,沿 Netconn UDP Echo 追踪 netconn、netbuf、mailbox、Core Locking,并映射到 Socket API。 [TOC] Netconn 是 lwIP 的 sequential API(顺序式 API):应用线程可以用 netconn_recv() 这类阻塞调用写普通“open/read/write/close”式逻辑,而协议 Core 仍保持事件驱动。Raw API 则是 lwIP 的 callback-style Core API,应用 callback 直接由协议栈事件驱动,不能把 callback 当成可长期阻塞的业务线程。S8 **Mailbox(消息邮箱)**是线程间传递指针/消息的队列抽象;Core Locking 是让非 tcpip_thread 线程先取得 Core mutex(保护协议 Core 的互...
07-tcp-handshake
教程 07:从 tcpecho_raw_init() 到 ESTABLISHED——TCP 三次握手与 PCB 状态机 摘要:从 TCP passive open 的三次握手模型出发,沿 Raw TCP Echo 监听入口追踪 LISTEN PCB、SYN_RCVD 连接 PCB、Sequence/ACK 与 accept callback。 [TOC] TCP(Transmission Control Protocol,传输控制协议)是在 IP 之上提供可靠、有序 **byte stream(字节流)**的面向连接传输协议。与 Stage 5 的 UDP 不同,TCP 在发送普通应用数据前先建立连接,并用 Sequence Number(序列号)、Acknowledgment Number(确认号)以及重传等机制维护双方对同一字节流的状态。S6 建立连接时,**SYN(Synchronize)**用于同步初始序列号;**ACK(Acknowledgment)**表示确认号字段有效,并告诉对端“下一次期望哪个 sequence number”。本篇只研究服务端 ...
08-tcp-data-path
教程 08:从 tcp_write() 到 ACK 清队列——TCP 数据发送、窗口与回调 摘要:从 TCP 字节流、序列号/确认号与窗口模型出发,沿 Raw TCP Echo 数据路径追踪接收回调、发送排队、待确认队列、ACK 清理和接收窗口归还。 [TOC] Stage 7 已经完成 passive open,并得到一个 ESTABLISHED connection PCB。本篇从第一块 application data 到达开始继续追:TCP 怎样把收到的 bytes 交给 Raw recv callback,Echo 怎样通过 tcp_write() 把 bytes 排入发送队列,以及远端 ACK 怎样释放 unacked segment、恢复发送额度并触发 sent callback。S1S2 本篇只建立正常数据面的主干;重传超时(RTO)和快速重传(Fast Retransmit)留到 Stage 9,乱序接收与选择性确认(SACK)留到 Stage 10。为了让第一次接触 TCP 数据面的读者能直接进入源码,先把这一主干依赖的协议概念建立起来。 阅...
09-tcp-retransmission
教程 09:从 tcp_slowtmr() 到 Fast Retransmit——TCP 超时重传与重复 ACK 摘要:沿 lwIP 的 RTO 与 Fast Retransmit 源码路径,映射 RFC 定义的丢包恢复机制到 timer、ACK 判定、发送队列与拥塞控制状态。 [TOC] Stage 8 已经建立了 TCP(Transmission Control Protocol,传输控制协议)正常发送路径:应用写入的字节被组织成 segment,发送后进入 unacked(lwIP 保存“已经发出但尚未被累计确认”的 segment 队列),对端返回累计 ACK(Acknowledgment,确认号)后,已确认 segment 才能释放。Stage 9 研究的是这个正常闭环被“丢包或确认长期不推进”打断后,TCP 怎样判断需要重传,以及 lwIP 用哪些 timer、PCB(Protocol Control Block,协议控制块)字段和队列动作实现恢复。 阅读源码前:建议提前阅读下面资料用于校准协议语义和抓包术语,但不是继续阅读本文的强制前置条件。这里先给出阅读用...
10-tcp-out-of-order
教程 10:从 tcp_receive() 到 ooseq / SACK——TCP 乱序、重组与选择确认 摘要:沿 lwIP 的乱序接收与 SACK 实现路径,映射 TCP sequence space、累计 ACK 与选择确认到 ooseq、rcv_nxt、pbuf 重组和 ACK option。 [TOC] Stage 9 从 sender 侧解释了 duplicate ACK 为什么可能触发 Fast Retransmit。Stage 10 转到 receiver 侧:当 TCP segment 没有按 sequence 顺序到达时,lwIP 怎样保存已经收到但暂时不能交付的数据,怎样在 gap 被补齐后恢复连续 byte stream,以及启用 SACK(Selective Acknowledgment,选择确认)时怎样把“gap 后哪些范围已经收到”反馈给 sender。 阅读源码前:建议提前阅读 RFC 9293 — Transmission Control Protocol:用于理解 TCP 怎样给字节编号、为什么确认号表示“下一段连续期望的数据位...
11-sys-arch
教程 11:从 tcpip_init() 到 sys_arch——线程、Mailbox、Timer、Semaphore 与 Core Locking 摘要:从 tcpip_init 与 tcpip_thread 主循环追踪 mailbox、timeout、semaphore、mutex 和 Core Locking,理解 Core thread 与 Unix Port 的运行边界。 [TOC] sys_arch 是 lwIP 面向操作系统或 RTOS 的移植抽象层,不属于 TCP/IP 协议本身。它解决的问题是:lwIP Core 需要线程、消息队列、信号量、互斥锁、时间与短临界区保护,但 Core 不应该绑定 pthread、RT-Thread 或某一种内核 API。Port 只要实现统一的 sys_* contract,Core 就能在不同 OS 上保持同一套调用方式。S4S6 阅读源码前:建议提前阅读 lwIP 2.1.x — OS abstraction layer:用于确认 sys_arch 要向 Core 提供哪些 thread/mailb...
12-mem-memp-pbuf
教程 12:从 pbuf_alloc() / tcp_new() 到资源回收——mem、memp 与 pbuf 内存体系 摘要:把 pbuf、UDP/TCP PCB、TCP segment、Netconn 与 tcpip message 放回统一资源模型,理解 variable heap、typed pools 与 packet-buffer policy。 [TOC] 前面的文章已经遇到很多“分配失败”入口:pbuf_alloc()、udp_new()、tcp_new()、netconn_new()、tcpip_inpkt()。这里的 **allocator(内存分配器)**泛指“根据某种资源策略取得并回收内存/对象”的机制。如果把这些入口全部理解成同一个 malloc(),就会误判资源瓶颈:一个系统可能还有 variable-size heap 空间,却已经耗尽 TCP PCB 这类固定对象池;也可能控制对象充足,却因为 packet buffer pool 不够而无法接收新帧。 阅读源码前:建议提前阅读 lwIP 2.1.x — Pac...
13-dhcpv4
教程 13:从 dhcp_start() 到 DHCP_STATE_BOUND——DHCPv4、ACD、Timer 与真实抓包 摘要:从 example_app 的 DHCP 入口追踪 DORA、UDP 回调、ACD、地址绑定与租约 Timer,并用真实 13 帧 PCAP 验证状态迁移。 [TOC] DHCPv4(Dynamic Host Configuration Protocol for IPv4,IPv4 动态主机配置协议)解决的是“主机刚接入网络、还没有可用 IPv4 配置时,怎样从网络中的 DHCP Server 获得地址、子网掩码、默认网关、DNS Server 与租约生命周期参数”。当前 lwIP 充当 DHCP Client;Client 使用 UDP 68,Server 使用 UDP 67。由于 Client 在第一次请求时可能仍是 0.0.0.0,首次租约阶段允许依赖广播和链路层可达性完成配置交换。S3S6 本文还会遇到 ACD(Address Conflict Detection,IPv4 地址冲突检测)。ACD 不是 DHCP 的另一种报文,而是...
14-dns
教程 14:从 dns_gethostbyname() 到 dns_found()——DNS Resolver、UDP PCB、Cache、Timer 与异步回调 摘要:从 example_app 的 DNS 请求入口追踪 resolver、UDP PCB、Cache、Timer 与异步回调,并用 6 帧真实 PCAP 验证 DHCP Option 6、随机源端口、TXID、A 记录和 TTL。 [TOC] DNS(Domain Name System,域名系统)把人类可读的 hostname 映射为 Resource Record(资源记录)等结构化数据。当前 lwIP 实现的是 stub resolver:应用把 hostname 交给 lwIP,lwIP 向已经配置好的 DNS Server 发送 Query;这个 DNS Server 通常是 recursive resolver(递归解析器),它可以代表 Client 继续访问 root、TLD(Top-Level Domain,顶级域)与 authoritative server(权威服务器),而 lwIP 本...







