tcp rev + tcp syn send
1 | __dev_xmit_skb (\root\codes\kernel-dev\linux\net\core\dev.c:3760) |
1 | static inline struct sock *__inet_lookup(struct net *net, |
到TCP层后,skb需要转换成 struct sock
,从 kernel 协议栈查找skb -> struct sk 映射
tcp rev + tcp syn send
1 | __dev_xmit_skb (\root\codes\kernel-dev\linux\net\core\dev.c:3760) |
1 | static inline struct sock *__inet_lookup(struct net *net, |
到TCP层后,skb需要转换成 struct sock
,从 kernel 协议栈查找skb -> struct sk 映射
目标:
分析 kernel 驱动收到后skb
1. 如何唤醒epoll callback?
2. accpet syscall 如何从listener socket spawn 子 socket?
一个极简epoll server程序(无法编译,只说明流程)
1 | // 创建listener socket |
以联发科 mt7921
无线网卡驱动为例
kernel
mt7921/
下有pci,usb接口的驱动,usb接口驱动入口是usb.c
。手里有mt7921芯片的USB无线网卡,对应的驱动为mt7921u
pci驱动为 mt7921e
USB接口 MT7921 外观
PCI接口的MT7921网卡外观
无线通讯通过电磁波完成,发送端通过电流转换成电磁场,电磁场产生无线电波在空间中传递。利用这现象,将信息调制到无线电波上发送。计算机领域中,信息就是 0/1,通过电磁波的带宽表示(也可以用电磁波其他的概念组合表示,不一定是是带宽)
接收端利用电磁感应原理,通过解调还原成最初的数据,所以 WI-FI 设备都带天线,天线
数据在传输中,发送器会在天线上施加电流,施加的时变电压或时变电流而产生辐射的电磁场,使得电流的能量转变成无线电波。在接收时,天线会由于电场的感应,而在天线内部产生时变电流,并在其终端产生时变电压,产生电讯号经过处理之后,可以在接收器中观察或收听。天线被广泛应用于广播、点对点无线电通讯、雷达和太空探索等通讯系统。天线是无线电通讯系统中的必需组件。
维基百科对无线电通讯有个大体介绍
驱动向内核注册 softirq,里面包含回调函数。驱动收到数据触发中断,kernel读取
1 | __netif_receive_skb_list_ptype(struct net_device * orig_dev, struct packet_type * pt_prev, struct list_head * head) (/data00/codes/linux/net/core/dev.c:5533) |
基于已有thread_struct封装的新的任务调度库
工作中涉及Nginx module开发,分析Nginx/tengine代码
每个 module 必须有 ngx_module_t,且在module不同生命周期都支持 hook 函数
1 | struct ngx_module_s { |
由于 ngx_module_t 为基础类型,对于http和stream,通过 ngx_module_t#ctx进行了扩展,用于放置 http/stream module相关的 hook 函数
salt 只用一次,用于生成 cipher,和 salt 类似的概念叫initial vector(初始化向量),可认为 salt 和 iv 是等价的概念。
nonce 每次 encrypt,decrypt都需要,而且 decrypt 时使用的nonce必须和那次encrypt的nonce一致。由于加解密的nonce必须一一对应,所以nonce往往采用双方提前约定的生成规则,一般都是每次使用完自加1,为下次使用做准备
从tun读出来后再写入tun,下次读还会将自己刚写入的packet读出来,如果设置默认路由是tun网卡,会导致死循环。下文会介绍解决routing loop的多种方法
https://www.kernel.org/doc/Documentation/networking/tuntap.txt
How does Virtual network device actually work ?
Virtual network device can be viewed as a simple Point-to-Point or
Ethernet device, which instead of receiving packets from a physical
media, receives them from user space program and instead of sending
packets via physical media sends them to the user space program.Let’s say that you configured IPv6 on the tap0, then whenever
the kernel sends an IPv6 packet to tap0, it is passed to the application
(VTun for example). The application encrypts, compresses and sends it to
the other side over TCP or UDP. The application on the other side decompresses
and decrypts the data received and writes the packet to the TAP device,
the kernel handles the packet like it came from real physical device.
一共两个方法, read 和 write
read from tun读取数据包
将LT想象成scope不太容易理解,可以将其想象成链。标注同一个的引用必须共存亡。通过 'a, 多个引用链在一起。
![将引用比作绳子]](https://user-images.githubusercontent.com/24750337/114650520-fb8a8c80-9d14-11eb-93a0-3ee191ff4938.png)
https://doc.rust-lang.org/stable/book/ch10-03-lifetime-syntax.html
https://www.zhihu.com/question/30861652/answer/132841992
跨函数的变量生存期分析及其复杂,要分析完成各种条件语句,且需要的值只有在运行时才能确认,这就加大了编译器分析的复杂度(又可认为不可能进行分析),Rust通过在函数,结构体上进行生命周期标注,将分析的范围限定到函数内部,从而完成整个分析的过程。这就是为何生命之后需要在 函数, 结构体 上进行 'a
标注