摘要: 前置说明 本文例子中涉及两个模块hello.ko和world.ko,其中hello导出符号供world使用; insmod 该命令将模块的代码和数据装入内核,然后使用内核的符号表继续模块中任何未解析的符号。insmod不会修改模块的磁盘文件,而仅仅修改内存中的副本。insmod可以接受一些命令行选项 阅读全文
posted @ 2019-10-28 21:56 AlexAlex 阅读(1446) 评论(0) 推荐(1)
摘要: 典型的模块Makefile如下所示; 1 ifneq ($(KERNELRELEASE),) 2 obj-m := hello.o 3 else 4 KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 PWD :=$(shell pwd) 6 def 阅读全文
posted @ 2019-10-28 21:48 AlexAlex 阅读(793) 评论(0) 推荐(0)
摘要: 注册helper nf_conntrack_ftp_init是连接跟踪ftp模块的初始化函数,可以看到其调用了nf_conntrack_helpers_register来注册helper; 1 static int __init nf_conntrack_ftp_init(void) 2 { 3 i 阅读全文
posted @ 2019-10-28 21:45 AlexAlex 阅读(1872) 评论(0) 推荐(0)
摘要: 初始化 iptable_mangle_table_init函数通过调用ipt_register_table完成mangle表注册和钩子函数注册的功能;该流程与iptable_filter的函数调用的函数一致,此处不再重复分析,详情请移步<iptable_filter分析>; 1 static int 阅读全文
posted @ 2019-10-28 21:43 AlexAlex 阅读(880) 评论(0) 推荐(0)
摘要: 初始化 iptable_nat_table_init函数通过调用ipt_register_table完成NAT表注册和钩子函数注册的功能;该流程与iptable_filter的函数调用的函数一致,此处不再重复分析,详情请移步<iptable_filter分析>; 1 static int __net 阅读全文
posted @ 2019-10-28 21:41 AlexAlex 阅读(1664) 评论(0) 推荐(0)
摘要: ipv4_conntrack_defrag ipv4_conntrack_defrag对输入包进行检查,如果是分片包,则调用nf_ct_ipv4_gather_frags函数进行重组; 1 static unsigned int ipv4_conntrack_defrag(void *priv, 2 阅读全文
posted @ 2019-10-28 21:36 AlexAlex 阅读(1668) 评论(0) 推荐(0)
摘要: 基础参数初始化 nf_conntrack_init_start函数完成连接跟踪基础参数的初始化,包括了hash,slab,扩展项,GC任务等; 1 int nf_conntrack_init_start(void) 2 { 3 int max_factor = 8; 4 int ret = -ENO 阅读全文
posted @ 2019-10-28 21:33 AlexAlex 阅读(1015) 评论(0) 推荐(0)
摘要: Netfilter通过连接跟踪来记录和跟踪连接的状态,为状态防火墙和NAT提供基础支持; 钩子点与钩子函数 下图为钩子点和钩子函数的关系图,其中ipv4_conntrack_defrag、ipv4_conntrack_in、ipv4_helper、ipv4_confirm为连接跟踪相关的钩子函数,其 阅读全文
posted @ 2019-10-28 21:30 AlexAlex 阅读(1183) 评论(0) 推荐(0)
摘要: 概述 本文主要对filter表的初始化流程,以及钩子函数的规则match流程的源码进行分析; 源码分析 所在钩子点: 1 /* 在LOCAL_IN,FORWARD, LOCAL_OUT钩子点工作 */ 2 #define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL 阅读全文
posted @ 2019-10-28 21:26 AlexAlex 阅读(1145) 评论(0) 推荐(0)
摘要: 概述 通过钩子点和优先级的代码追溯,得到如下对应关系图,图中横坐标为钩子点,纵坐标为优先级,每个钩子点上的钩子函数按照优先级排布; 详细分析 5个钩子点如下所示,在这个五个钩子点上的钩子函数按照上面的优先级从小到大排列; 1 /* IP Hooks */ 2 /* After promisc dro 阅读全文
posted @ 2019-10-28 21:21 AlexAlex 阅读(1167) 评论(0) 推荐(1)
摘要: 概述 本文主要分析table,rule,match,target的作用和其数据结构之间的关系,为后面的匹配流程做铺垫,通过本文中代码流程的分析,可以得到如下的关系图: 详细分析 table iptables分为五种: filter:This is the default table (if no - 阅读全文
posted @ 2019-10-28 21:20 AlexAlex 阅读(1280) 评论(0) 推荐(0)
摘要: 本篇主要从三层协议栈调用函数NF_HOOK说起,不断深入,分析某个钩子点中所有钩子函数的调用流程,但是本文不包含规则介绍和核心的规则匹配流程,后续文章将继续分析; NF_HOOK函数先调用了nf_hook继续执行调用钩子函数处理,处理之后,如果接受,则调用输入的回调函数okfn,继续数据包的下一步处 阅读全文
posted @ 2019-10-28 21:16 AlexAlex 阅读(3478) 评论(0) 推荐(0)
摘要: 通过注册流程代码的分析,能够明确钩子函数的注册流程,理解存储钩子函数的数据结构,如下图(点击图片可查看原图); 废话不多说,开始分析; nf_hook_ops是注册的钩子函数的核心结构,字段含义如下所示,一般待注册的钩子函数会组成一个nf_hook_ops数组,在注册过程中调用nf_register 阅读全文
posted @ 2019-10-28 21:14 AlexAlex 阅读(4482) 评论(0) 推荐(1)
摘要: 概述 在协议栈的三层IPv4(IPv6还没看,不清楚)数据包的处理过程中,可能经过Netfilter的五个钩子点,分别为NF_INET_PRE_ROUTING、NF_INET_LOCAL_IN、NF_INET_FORWARD、NF_INET_LOCAL_OUT、NF_INET_POST_ROUTIN 阅读全文
posted @ 2019-10-28 21:11 AlexAlex 阅读(5767) 评论(2) 推荐(4)
摘要: netlink的特点 netlink提供了一种在用户态和内核态之间进行数据传递的方式; (1) 是一种异步的通信机制,传递的数据会放在socket的缓存队列中; (2) 内核可以主动发送数据给用户空间; (3) 能够在内核模块中使用; (4) 支持组播; (5) 使用套接字编程; 测试例程 用户态例 阅读全文
posted @ 2019-10-28 20:50 AlexAlex 阅读(598) 评论(0) 推荐(0)
摘要: 概述 arp_process为ARP输入包的核心处理流程; 若输入为ARP请求且查路由成功,则进行如下判断:输入到本地,则进行应答;否则,允许转发,则转发,本文代码不包含转发流程; 若输入为ARP应答或者查路由失败,则更新邻居项; 源码分析 1 static int arp_process(stru 阅读全文
posted @ 2019-10-28 20:48 AlexAlex 阅读(1666) 评论(0) 推荐(0)
摘要: 概述 arp_rcv是ARP包的入口函数,ARP模块在二层注册了类型为ETH_P_ARP的数据包回调函数arp_rcv,当收到ARP包时,二层进行分发,调用arp_rcv; arp_rcv对ARP输入包的合法性进行检查,然后经过netfilter的ARP_IN钩子点,之后调用arp_process处 阅读全文
posted @ 2019-10-28 20:47 AlexAlex 阅读(1156) 评论(0) 推荐(0)
摘要: 概述 neigh_hh_output-缓存输出,直接拷贝二层头部,然后输出; neigh_connected_output-快速输出,用于连接状态的输出;需要重新构建二层头部,然后输出; neigh_resolve_output-慢速输出,用于非连接状态的输出;需要对邻居项状态进行检查,然后重新构造 阅读全文
posted @ 2019-10-28 20:45 AlexAlex 阅读(675) 评论(0) 推荐(0)
摘要: 概述 arp_solicit用来发送ARP请求,首先会根据ARP_ANNOUNCE参数来选取源地址,然后判断是否达到内核发送次数上限,未达到则调用内核arp_send_dst函数发送,如果达到上限,则继续判断是否达到应用程序请求发送次数上限,未达到则通知应用程序发送ARP请求; 源码分析 1 /* 阅读全文
posted @ 2019-10-28 20:45 AlexAlex 阅读(1595) 评论(0) 推荐(0)
摘要: 概述 在分配邻居子系统之后,会设置定时器来处理那些需要定时器处理的状态,定时器回调函数为neigh_timer_handler;函数会根据状态机变换规则对状态进行切换,切换状态后,如果需要更新输出函数则更新,并更新定时器下一次超时时间;其中NUD_INCOMPLETE | NUD_PROBE状态需要 阅读全文
posted @ 2019-10-28 20:44 AlexAlex 阅读(1032) 评论(0) 推荐(0)
摘要: 概述 neigh_update函数用来更新指定的邻居项,更新内容是硬件地址和状态,更新之后,会根据新状态设置其输出函数,CONNECTED状态则使用快速输出,否则使用慢速输出;如果是由原来的无效状态变为现在的有效状态,则需要将数据包缓存队列中的数据包发送出去; 该函数在邻居子系统中被频繁调用;arp 阅读全文
posted @ 2019-10-28 20:42 AlexAlex 阅读(1378) 评论(0) 推荐(0)
摘要: 概述 邻居项查找是通过neigh_lookup相关函数来进行的; ___neigh_lookup_noref,该函数根据输出设备和主键值(IPv4为下一跳ip地址)在邻居项hash表中查找,找到则返回该项; neigh_lookup,该函数调用了___neigh_lookup_noref函数,并且在 阅读全文
posted @ 2019-10-28 20:41 AlexAlex 阅读(1692) 评论(0) 推荐(0)
摘要: 概述 IP层输出数据包会根据路由的下一跳查询邻居项,如果不存在则会调用__neigh_create创建邻居项,然后调用邻居项的output函数进行输出; __neigh_create完成邻居项的创建,进行初始化之后,加入到邻居项hash表,然后返回,其中,如果hash表中有与新建邻居项相同的项会复用 阅读全文
posted @ 2019-10-28 20:40 AlexAlex 阅读(1167) 评论(0) 推荐(0)
摘要: 概述 邻居子系统支持多种实现,例如ARP,ND等,这些实现需要在其初始化的时候,调用neigh_table_init将邻居表项添加到全局邻居子系统数组中,并对实例中的字段(如hash,定时器等)进行相关初始化; 源码分析 分析过程以ARP为例,引出邻居表的初始化,在arp_init初始化中,调用ne 阅读全文
posted @ 2019-10-28 20:39 AlexAlex 阅读(1114) 评论(0) 推荐(0)
摘要: 概述 ip_fragment函数用于判断是否进行分片,在没有设置DF标记的情况下进入分片,如果设置了DF标记,则继续判断,如果不允许DF分片或者收到的最大分片大于MTU大小,则回复ICMP,释放skb,其余情况仍然需要走分片; ip_do_fragment是详细的分片流程,整个过程分为快速分片和慢速 阅读全文
posted @ 2019-10-28 20:37 AlexAlex 阅读(3208) 评论(0) 推荐(0)
摘要: 概述 ip层在构造好ip头,检查完分片之后,会调用邻居子系统的输出函数neigh_output进行输出,输出分为有二层头缓存和没有两种情况,有缓存时调用neigh_hh_output进行快速输出,没有缓存时,则调用邻居子系统的输出回调函数进行慢速输出; 源码分析 1 static inline in 阅读全文
posted @ 2019-10-28 20:36 AlexAlex 阅读(1910) 评论(0) 推荐(1)
摘要: 概述 ip_output-设置输出设备和协议,然后经过POST_ROUTING钩子点,最后调用ip_finish_output; ip_finish_output-对skb进行分片判断,需要分片,则分片后输出,不需要分片则知直接输出; ip_finish_output2-对skb的头部空间进行检查, 阅读全文
posted @ 2019-10-28 20:36 AlexAlex 阅读(2973) 评论(0) 推荐(1)
摘要: 概述 将要从本地发出的数据包,会在构造了ip头之后,调用ip_local_out函数,该函数设置数据包的总长度和校验和,然后经过netfilter的LOCAL_OUT钩子点进行检查过滤,如果通过,则调用dst_output函数,实际上调用的是ip数据包输出函数ip_output; 源码分析 1 in 阅读全文
posted @ 2019-10-28 20:35 AlexAlex 阅读(2379) 评论(1) 推荐(0)
摘要: 概述 ip_queue_xmit是ip层提供给tcp层发送回调,大多数tcp发送都会使用这个回调,tcp层使用tcp_transmit_skb封装了tcp头之后,调用该函数,该函数提供了路由查找校验、封装ip头和ip选项的功能,封装完成之后调用ip_local_out发送数据包; ip_build_ 阅读全文
posted @ 2019-10-28 20:34 AlexAlex 阅读(2200) 评论(0) 推荐(0)
摘要: 概述 tcp_transmit_skb的作用是复制或者拷贝skb,构造skb中的tcp首部,并将调用网络层的发送函数发送skb;在发送前,首先需要克隆或者复制skb,因为在成功发送到网络设备之后,skb会释放,而tcp层不能真正的释放,是需要等到对该数据段的ack才可以释放;然后构造tcp首部和选项 阅读全文
posted @ 2019-10-28 20:33 AlexAlex 阅读(2312) 评论(0) 推荐(0)
摘要: 概述 tcp_write_xmit函数完成对待发送数据的分段发送,过程中会遍历发送队列,进行窗口检查,需要TSO分段则分段,然后调用tcp_transmit_skb发送数据段; 源码分析 1 static bool tcp_write_xmit(struct sock *sk, unsigned i 阅读全文
posted @ 2019-10-28 14:44 AlexAlex 阅读(2357) 评论(0) 推荐(0)
摘要: 概述 sendmsg系统调用在tcp层的实现是tcp_sendmsg函数,该函数完成以下任务:从用户空间读取数据,拷贝到内核skb,将skb加入到发送队列的任务,调用发送函数;函数在执行过程中会锁定控制块,避免软中断在tcp层的影响;函数核心流程为,在发送数据时,查看是否能够将数据合并到发送队列中最 阅读全文
posted @ 2019-10-28 14:43 AlexAlex 阅读(1976) 评论(0) 推荐(0)
摘要: 概述 recvmsg系统调用在tcp层的实现是tcp_recvmsg函数,该函数完成从接收队列中读取数据复制到用户空间的任务;函数在执行过程中会锁定控制块,避免软中断在tcp层的影响;函数会涉及从接收队列receive_queue,预处理队列prequeue和后备队列backlog中读取数据;其中从 阅读全文
posted @ 2019-10-28 14:42 AlexAlex 阅读(2439) 评论(0) 推荐(0)
摘要: 概述 快速路径:用于处理预期的,理想情况下的数据段,在这种情况下,不会对一些边缘情形进行检测,进而达到快速处理的目的; 慢速路径:用于处理那些非预期的,非理想情况下的数据段,即不满足快速路径的情况下数据段的处理; 首部预测字段格式:首页预测字段,实际上是与TCP首部中的【头部长度+保留字段+标记字段 阅读全文
posted @ 2019-10-28 14:41 AlexAlex 阅读(1417) 评论(0) 推荐(0)
摘要: tcp_data_queue作用为数据段的接收处理,其中分为多种情况: (1) 无数据,释放skb,返回; (2) 预期接收的数据段,a. 进行0窗口判断;b. 进程上下文,复制数据到用户空间;c. 不满足b或者b未完整拷贝此skb的数据段,则加入到接收队列;d. 更新下一个期望接收的序号;e. 若 阅读全文
posted @ 2019-10-28 14:39 AlexAlex 阅读(1965) 评论(0) 推荐(0)
摘要: tcp_queue_rcv用于将接收到的skb加入到接收队列receive_queue中,首先会调用tcp_try_coalesce进行分段合并到队列中最后一个skb的尝试,若失败则调用__skb_queue_tail添加该skb到队列尾部; 1 static int __must_check tc 阅读全文
posted @ 2019-10-28 14:38 AlexAlex 阅读(1283) 评论(0) 推荐(0)
摘要: 概述 tcp_rcv_established用于处理已连接状态下的输入,处理过程根据首部预测字段分为快速路径和慢速路径; 1. 在快路中,对是有有数据负荷进行不同处理: (1) 若无数据,则处理输入ack,释放该skb,检查是否有数据发送,有则发送; (2) 若有数据,检查是否当前处理进程上下文,并 阅读全文
posted @ 2019-10-28 14:31 AlexAlex 阅读(2554) 评论(0) 推荐(0)
摘要: 在未开启tcp_low_latency的情况下,软中断将skb送上来,加入到prequeue中,然后 在未启用tcp_low_latency且有用户进程在读取数据的情况下,skb入队到prequeue,入队之后,若达到队列长度上限或者内存上限,则将队列中的skb出队,调用tcp_v4_do_rcv处 阅读全文
posted @ 2019-10-28 14:25 AlexAlex 阅读(988) 评论(0) 推荐(0)
摘要: tcp_v4_rcv函数为TCP的总入口,数据包从IP层传递上来,进入该函数;其协议操作函数结构如下所示,其中handler即为IP层向TCP传递数据包的回调函数,设置为tcp_v4_rcv; 1 static struct net_protocol tcp_protocol = { 2 .earl 阅读全文
posted @ 2019-10-28 13:44 AlexAlex 阅读(3521) 评论(0) 推荐(1)
摘要: 概述 以前的TCP请求控制块没有独立的状态,而是依赖于他们的父控制块的状态,也就是TCP_LISTEN状态,现在要把请求控制块加入到全局的ehash中,所以需要一个状态,而TCP_SYN_RECV状态被fast open sokets使用了,所以新加了一个TCP_NEW_SYN_RECV状态; 以下 阅读全文
posted @ 2019-10-28 13:38 AlexAlex 阅读(2348) 评论(0) 推荐(0)
摘要: 概述 在主动关闭方发送了FIN之后,进入FIN_WAIT_1状态,在此状态收到了ACK,则进入FIN_WAIT_2状态,而FIN_WAIT_2后续要做的工作是等待接收对端发过来的FIN包,并且发送ACK,进而进入到TIME_WAIT状态;本文主要关注从FIN_WAIT_1进入FIN_WAIT_2状态 阅读全文
posted @ 2019-10-28 13:35 AlexAlex 阅读(7520) 评论(0) 推荐(0)
摘要: 概述 本文对两个LINGER相关的套接字选项进行源码层面的分析,以更明确其各自的作用和区别; man page SO_LINGER,该选项是socket层面的选项,通过struct linger结构来设置信息,如果启用该选项,那么使用close()和shutdown()(注意:虽然manpage这么 阅读全文
posted @ 2019-10-28 13:15 AlexAlex 阅读(2147) 评论(0) 推荐(0)
摘要: 在调用close系统调用关闭套接字时,如果套接字引用计数已经归零,则需继续向上层调用其close实现,tcp为tcp_close;本文仅介绍tcp部分,前置部分请参考本博关于close系统调用的文章; 1 void tcp_close(struct sock *sk, long timeout) 2 阅读全文
posted @ 2019-10-28 13:11 AlexAlex 阅读(1117) 评论(0) 推荐(0)
摘要: 概述 shutdown系统调用在tcp层会调用两个函数,对于ESTABLISHED状态需要调用tcp_shutdown关闭连接,对于LISTEN和SYN_SENT状态则需要以非阻塞模式调用tcp_disconnect断开连接;本文除了对这两个函数进行分析以外,还会分析在shutdown关闭了读或者写 阅读全文
posted @ 2019-10-28 13:10 AlexAlex 阅读(1022) 评论(0) 推荐(0)
摘要: 概述 本文主要对MSS相关的几个字段结合源码流程进行分析; 字段含义 user_mss(tcp_options_received)–用户配置的mss,优先级最高; mss_clamp(tcp_options_received)–对端通告的mss,即为对端能接受的最大mss,对端通告的mss与user 阅读全文
posted @ 2019-10-28 11:39 AlexAlex 阅读(1672) 评论(0) 推荐(0)
摘要: 假设两台设备双方均发送syn给对端,在发送syn之后状态处于SYN_SENT状态,此时双方均收到对端的发来的syn,则立即进入SYN_RECV状态,并且都向对端回复syn+ack,在收到syn+ack之后,连接从SYN_RECV状态切换到ESTABLISHED状态; 在发送syn进入SYN_SENT 阅读全文
posted @ 2019-10-28 11:33 AlexAlex 阅读(821) 评论(0) 推荐(0)
摘要: 假定客户端主动打开,发送syn包到服务器,服务器创建连接请求控制块加入到队列,进入TCP_NEW_SYN_RECV 状态,发送syn+ack给客户端,并启动定时器,等待客户端回复最后一个握手ack; tcp_v4_rcv上来的包,会判断连接状态,当状态为TCP_NEW_SYN_RECV时,期望得到对 阅读全文
posted @ 2019-10-28 10:33 AlexAlex 阅读(1262) 评论(0) 推荐(0)
摘要: 假定客户端执行主动打开,发送syn包到服务器,服务器执行完该包的第一次握手操作后,调用af_ops->send_synack向客户端发送syn+ack包,该回调实际调用tcp_v4_send_synack函数; 1 int tcp_conn_request(struct request_sock_o 阅读全文
posted @ 2019-10-28 10:27 AlexAlex 阅读(2184) 评论(0) 推荐(0)
摘要: 假定客户端执行主动打开,服务器执行被动打开,客户端发送syn包到服务器,服务器接收该包,进行建立连接请求的相关处理,即第一次握手;本文主要分析第一次握手中被动打开端的处理流程,主动打开端的处理请查阅本博客内另外的文章; IPv4携带的TCP报文最终会进入到tcp_v4_do_rcv函数,服务器准备接 阅读全文
posted @ 2019-10-28 10:20 AlexAlex 阅读(1624) 评论(0) 推荐(0)
摘要: 假设客户端执行主动打开,已经经过第一次握手,即发送SYN包到服务器,状态变为SYN_SENT,服务器收到该包后,回复SYN+ACK包,客户端收到该包,进行主动打开端的第二次握手部分;流程中涉及到的函数和细节非常多,本篇只对主流程予以分析; 在ESTABLISHED和TIME_WAIT以外的状态时接收 阅读全文
posted @ 2019-10-28 10:12 AlexAlex 阅读(1762) 评论(0) 推荐(0)
摘要: 假定客户端执行主动打开,并且已经收到服务器发送的第二次握手包SYN+ACK,在经过一系列处理之后,客户端发送第三次握手包ACK到服务器;其流程比较简单,主要是分配skb,初始化ack包并发送;需要注意的一点是,标记纯ACK包竟然用了skb->truesize=2,好吧; 阅读全文
posted @ 2019-10-28 10:12 AlexAlex 阅读(532) 评论(0) 推荐(1)
摘要: 在tcp_ack接收ACK处理函数中,如果确认当前走慢速路径,那么会调用tcp_ack_update_window函数检查窗口是否需要更新并更新之,并且更新未确认数据的位置,即更新窗口左边沿; 1 static int tcp_ack(struct sock *sk, const struct sk 阅读全文
posted @ 2019-10-28 10:09 AlexAlex 阅读(5122) 评论(0) 推荐(0)
摘要: 滑动窗口的发送窗口示意图如下,其中由对端通告的窗口窗口大小为6,窗口中和窗口外的数据分别表示为:1-3发送并已经被确认的数据段,4-6发送但尚未被确认的数据段,7-9能够发送尚未发送的数据段,10-…位于窗口外不能够被发送的数据; 窗口边沿的移动示意图如下,当接收方确认数据后,这个滑动窗口不时的向右 阅读全文
posted @ 2019-10-28 10:01 AlexAlex 阅读(637) 评论(0) 推荐(0)
摘要: TCP 的那些事儿(上) TCP 的那些事儿(下) 阅读全文
posted @ 2019-10-28 10:00 AlexAlex 阅读(53) 评论(0) 推荐(0)
摘要: 时间戳选项发送方在每个报文段中放置一个时间戳值。接收方在确认中返回这个数值,从而允许发送方为每一个收到的ACK计算RTT(我们必须说“每一个收到的ACK”而不是“每一个收到的报文段”,是因为TCP通常用一个ACK来确认多个报文段)。我们提到过目前很多实现为每个窗口值计算一个RTT,对于包含8个报文段 阅读全文
posted @ 2019-10-28 09:59 AlexAlex 阅读(6086) 评论(0) 推荐(0)
摘要: 窗口扩大选项使TCP的窗口定义从16bit增加到32bit。这并不是通过修改TCP首部来实现的,TCP首部仍然使用16bit,而是通过定义一个选项实现对16bit的扩大操作来完成的。于是TCP在内部将实际的窗口大小维持为32bit的值; 窗口扩大选项的取值范围为0<=shif.cnt<=14;最大值 阅读全文
posted @ 2019-10-28 09:58 AlexAlex 阅读(5799) 评论(1) 推荐(0)
摘要: 最大报文段长度(MSS)表示TCP传往另一端的最大数据库的长度。当一个连接建立时,连接的双方都要通告各自需要接收的MSS选项(MSS选项只能出现在SYN报文段中)。如果一方不接收来自另一方的MSS值,则MSS就定为默认值536字节(这个默认值允许20字节的IP首部和20字节的TCP首部以适合576字 阅读全文
posted @ 2019-10-28 09:57 AlexAlex 阅读(4611) 评论(0) 推荐(0)
摘要: 路径MTU 当在同一个网络上的两台主机互相通信时,该网络的MTU是非常重要的。当时如果两台主机之间的通信要通过多个网络,那么每个网络的链路层就可能有不同的MTU。重要的不是两台主机所在网络的MTU,而是两台通信主机路径中的最小MTU,称为路径MTU; 两台主机之间的路径MTU不一定是个常数,它取决于 阅读全文
posted @ 2019-10-28 09:55 AlexAlex 阅读(1648) 评论(0) 推荐(0)
摘要: tcp客户端与服务器端建立连接需要经过三次握手过程,本文主要分析客户端主动打开中的第一次握手部分,即客户端发送syn段到服务器端; tcp_v4_connect为发起连接主流程,首先对必要参数进行检查,获取路由信息,改变连接状态成SYN_SENT,再调用inet_hash_connect将控制块加入 阅读全文
posted @ 2019-10-28 09:54 AlexAlex 阅读(1797) 评论(0) 推荐(0)
摘要: inet_csk_accept函数实现了tcp协议accept操作,其主要完成的功能是,从已经完成三次握手的队列中取控制块,如果没有已经完成的连接,则需要根据阻塞标记来来区分对待,若非阻塞则直接返回,若阻塞则需要在一定时间范围内阻塞等待; 1 /* 2 * This will accept the 阅读全文
posted @ 2019-10-28 09:49 AlexAlex 阅读(1317) 评论(0) 推荐(0)
摘要: 说明 前面从stackoverflow上找了一篇讲这两个选项的文章,文章内容很长,读到最后对Linux中的这两个选项还是有些迷茫,所以重新写一篇文章来做一个总结; 本文只总结TCP单播部分,并且只讨论该选项的bind()系统调用部分,UDP,组播,开启选项之后数据包的调度等不做讨论; man手册中对 阅读全文
posted @ 2019-10-28 09:45 AlexAlex 阅读(1223) 评论(0) 推荐(0)
摘要: 说明:该文章中部分代码未能完全理解透彻,可能对您造成误解,请慎读; 并建议您先阅读本博另外一篇文章:<Linux TCP套接字选项 之 SO_REUSEADDR && SO_REUSEPORT> 另:该文章将会持续更新改进; TCP的接口绑定通过函数inet_csk_get_port函数执行,其中包 阅读全文
posted @ 2019-10-28 09:40 AlexAlex 阅读(801) 评论(0) 推荐(0)
摘要: C语言中!!的作用是?看例子; 1 #include <stdio.h> 2 3 int main() 4 { 5 int test = 666; 6 7 printf("test=%d !test=%d !!test=%d\n", test, !test, !!test); 8 9 return 阅读全文
posted @ 2019-10-28 09:01 AlexAlex 阅读(1424) 评论(0) 推荐(0)
摘要: 说明 本文下面内容基本上是截取自stackoverflow,针对这两个选项,在另外一篇文章中做了总结,请移步<Linux TCP套接字选项 之 SO_REUSEADDR && SO_REUSEPORT> 原文部分翻译 基本知识点 TCP/UDP连接是由一个五元组(如下)标识的,不允许存在多个连接具有 阅读全文
posted @ 2019-10-28 08:50 AlexAlex 阅读(764) 评论(0) 推荐(0)