一、给出一个UDP C/S通信的总调用过程
使用GDB对内核进行调试,先加断点b SYSC_socketcall,查看整个通信过程中socket系统调用情况。
嵌入式进阶教程分门别类整理好了,看的时候十分方便,由于内容较多,这里就截取一部分图吧。

需要的朋友私信【内核】即可领取
内核学习地址:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈-学习视频教程-腾讯课堂
Server的调用过程为:

从图中可以看到call的变化为 :1–>2–>12。
同理,我们可以得到Client的socket调用过程中call值变化为:1–>11–>12。
然后,从内核代码中我们可以寻找到call值对应的socket操作,这些宏的定义在include/uapi/linux/net.h文件中:
#define SYS_SOCKET 1 /* sys_socket(2) */
#define SYS_BIND 2 /* sys_bind(2) */
#define SYS_CONNECT 3 /* sys_connect(2) */
#define SYS_LISTEN 4 /* sys_listen(2) */
#define SYS_ACCEPT 5 /* sys_accept(2) */
#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */
#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */
#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */
#define SYS_SEND 9 /* sys_send(2) */
#define SYS_RECV 10 /* sys_recv(2) */
#define SYS_SENDTO 11 /* sys_sendto(2) */
#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
#define SYS_ACCEPT4 18 /* sys_accept4(2) */
#define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */
#define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */
从而我们得到整个调用过程为:

总的来说,UDP调用过程比较简单,下面我们主要关注recvfrom和sendto两个过程。
二、recvfrom的内核函数调用过程
对于recvfrom函数在内核中的调用过程,我们从SYSC_recvfrom开始一步一步追踪,看到可疑的函数调用使用step进去查看即可。
追踪中可能会遇到内联函数,使得内联函数中的其他函数调用无法使用gdb进一步跟踪,这时可以直接看源代码,比如利用OpenGrok的搜索功能,找出可疑的调用目标,再加断点来验证。
跟踪到一定深度的调用栈后,可以发现,内核代码转到了net/ipv4/udp.c文件中,这里应该就是运输层udp协议相关实现的地方。
进一步追踪我们可以得到相关数据报处理的函数,在这里,如果没有数据发送过来,线程会阻塞。下面是追踪下来得到的整个调用时序。

三、sendto的内核函数调用过程
仿照recvfrom中的跟踪方式,sendto有相似的函数调用过程,如下图:
最后,recvfrom和sendto的内核函数调用过程追踪完毕,接下来,根据每一个调用过程,我们可以详细分析UDP协议在内核中的具体实现细节,这留作后续工作。当然,更进一步,我们可以从运输层追踪到网络层,详细查看IP协议的具体实现。