一、SYN报文处理:

公共部分:tcp_v4_rcv->tcp_v4_do_rcv->tcp_v4_cookie_check(无处理动作)->tcp_rcv_state_process->tcp_v4_conn_request[conn_request]->tcp_conn_request(传入两个参数tcp_request_sock_ops和tcp_request_sock_ipv4_ops,该函数内解析SYN报文的option,req初始化工作)

syncookie连接:inet_reqsk_alloc(创建request_sock)->[tcp_conn_request]tcp_v4_send_synack [send_synack](发送SYNACK)->tcp_make_synack->[tcp_conn_request]reqsk_free(syncookie下不保存request_sock,因此需要在这里进行释放)

TFO连接:inet_reqsk_alloc(创建request_sock)->[tcp_conn_request]tcp_try_fastopen(当不需要syncookie的时候尝试fastopen)->tcp_fastopen_create_child(设置TFO的重传定时器,接收随着SYN报文的数据)->tcp_v4_syn_recv_sock[syn_recv_sock]->tcp_create_openreq_child(创建SYN_RCVD状态的newsk,sock_copy复制listen状态的成员值)->[tcp_v4_syn_recv_sock]inet_ehash_nolisten(把newsk插入到ehash散列表)->[tcp_conn_request]tcp_v4_send_synack [send_synack](发送SYNACK)->tcp_make_synack->[tcp_conn_request]inet_csk_reqsk_queue_add(把req插入到accept队列)

普通连接:inet_reqsk_alloc(创建request_sock)->[tcp_conn_request]inet_csk_reqsk_queue_hash_add->reqsk_queue_hash_req(把req插入ehash散列表中并设置普通连接SYNACK的重传定时器)->inet_ehash_insert->[inet_csk_reqsk_queue_hash_add]inet_csk_reqsk_queue_added(更新半连接逻辑队列qlen的长度)->[tcp_conn_request]tcp_v4_send_synack [send_synack](发送SYNACK)->tcp_make_synack

tcp_conn_request:

1、判断是否使能syncookie,首先需要内核编译启用CONFIG_SYN_COOKIES选项,下面两种场景下会启用syncookie

  • tcp_syncookies=2

  • tcp_syncookies=1,半连接逻辑队列满、当前状态不是timewait转换过来的

2、accept队列满,且当前半连接队列有未重传的SYNACK请求,则直接丢弃SYN连接请求报文

3、非timwait切换非syncookie场景下,如果tcp_tw_recycle参数有效,则执行更严格的PAWS校验,如果tcp_tw_recycle无效且参数tcp_syncookies=0,则在半连接队列中预留1/4的空间给TCP metric中已经proved的destination。

二、SYNACK的处理

tcp_v4_rcv->tcp_v4_do_rcv->tcp_rcv_state_process->tcp_rcv_synsent_state_process

tcp_rcv_synsent_state_process:

ACK标志位有效的正常流程:

1、检测收到数据包的ack number、TSopt、RST、SYN等的有效性

2、初始化mtup、fack、mss等

3、调用tcp_finish_connect完成连接

4、如果是TFO,需要进入tcp_rcv_fastopen_synack处理TFO相关内容,如重传未被ACK的数据并重启重传定时器

5、如果写操作被挂起、或者TCP_QUICKACK选项设置为0、或者TCP_DEFER_ACCEPT设置为1,那么设置延迟ACK,正确节省一个ACK报文的消耗。

ACK标志位无效的时候

1、检测RST是否有效

2、进行paws检查

3、如果SYN标志位有效,则切换到TCP_SYN_RECV状态,发送SYNACK进行TCP同开的处理。

tcp_finish_connect:更新状态为TCP_ESTABLISHED

1、初始化metrics

2、触发拥塞控制模块init接口来进行拥塞控制模块的初始化

3、初始化rcvbuf和sndbuf

4、初始化keepalive

5、判断是否启动数据包处理的快速路径

6、通过sock_def_wakeup[sk->sk_state_change]唤醒等待的连接

sock_def_wakeup[sk->sk_state_change]

当sk被添加到prequeue或者backlog的时候最终会被tcp_v4_do_rcv处理,请参考release_sock

三、最后的ACK处理:

syncookie连接:tcp_v4_rcv->tcp_v4_do_rcv->tcp_v4_cookie_check->cookie_v4_check->inet_reqsk_alloc(创建request_sock)->[cookie_v4_check]tcp_get_cookie_sock->tcp_v4_syn_recv_sock[syn_recv_sock]->tcp_create_openreq_child(创建SYN_RCVD状态的newsk,sock_copy复制listen状态的成员值)->[tcp_v4_syn_recv_sock]inet_ehash_nolisten(把newsk插入到ehash队列)->[tcp_v4_do_rcv] tcp_child_process->tcp_rcv_state_process(把newsk从SYN_RCVD切换到ESTABLISHED)->sock_def_readable[parent->sk_data_ready](唤醒sk->sk_wq中的等待进程)

TFO连接:tcp_v4_rcv->tcp_v4_do_rcv(tcp_v4_rcv还可能切换到其他函数)->tcp_rcv_state_process[把TFO的sock从SYN_RCVD切换到ESTABLISHED]->tcp_check_req(仅做报文有效性检查会提前return,不处理defer_accept处理,也不调用tcp_v4_syn_recv_sock)->reqsk_fastopen_remove(从fastopen逻辑队列移除这个TFO连接)

普通连接:tcp_v4_rcv(查找之前创建并插入到ehash的request_sock,状态为NEW_SYN_RCVD)->tcp_check_req(报文有效性检测,如PAWS、系列号是否窗口内、纯SYN包的SYNACK重传处理、defer_accept处理等等)->tcp_v4_syn_recv_sock[syn_recv_sock]->tcp_create_openreq_child(创建SYN_RCVD状态的newsk,sock_copy复制listen状态的成员值)->[tcp_v4_syn_recv_sock]inet_ehash_nolisten(把newsk插入到ehash散列表,并替换出之前插入的req)->[tcp_check_req]inet_csk_complete_hashdance(更新半连接队列的长度qlen=qlen-1,并把req插入到accept队列)->[tcp_v4_rcv]tcp_child_process->tcp_rcv_state_process(把newsk从SYN_RCVD切换到ESTABLISHED)

tcp_v4_syn_recv_sock:

Accept队列满或者不能新建立newsk的时候返回Null,静默丢弃三次握手最后的ACK确认报文。

__inet_inherit_port[tcp_v4_syn_recv_sock]:

listen后建立的新连接不一定和listen的socket端口一致,tproxy场景可能不一致。

tcp_check_req:

接收到PAWS校验失败且系列号不相符的SYN报文时候,普通连接回复RST报文并从半连接队列删除req,TFO会把sock加入TFO RST逻辑队列

收到RST报文的时候,普通连接直接从半连接队列删除req并不回复RST,TFO会把sock加入TFO RST逻辑队列

四个队列:

Accept队列:表示等待用户层accept的连接,队列为icsk_accept_queue   sk->sk_ack_backlog

半连接逻辑队列: 表示非TFO、非syncookie下的TCP普通连接,已经接收到SYN报文但是还没接收到SYNACK报文的SOCK数量,实际保存在ehash散列表中,队列长度(&inet_csk(sk)->icsk_accept_queue)->qlen

fastopen逻辑队列:表示接收到SYN报文但是还没有进入ESTABLISHED状态的TFO sock数量,TFO sock存在ehash散列表里面,队列长度(&inet_csk(sk)->icsk_accept_queue)->fastopenq.qlen   tcp_fastopen_create_child中增加队列长度   当TFO连接进入ESTABLISHED或者直接进入FIN_WAIT1状态时候在reqsk_fastopen_remove函数中削减队列

fastopen rst队列:&inet_csk(sk)->icsk_accept_queue->fastopenq->{rskq_rst_head,rskq_rst_tail}    RST处理的差异需要额外注意一下    存活60s。关于这个RST队列描述如下:

To protect the server, it is important to limit the maximum number of

total pending TFO connection requests, i.e., PendingFastOpenRequests

(Section 4.2).  When the limit is exceeded, the server temporarily

disables TFO entirely as described in "Server Cookie Handling"

(Section 4.1.2).  Then, subsequent TFO requests will be downgraded to

regular connection requests, i.e., with the data dropped and only

SYNs acknowledged.  This allows regular SYN flood defense techniques

[RFC4987] like SYN cookies to kick in and prevent further service

disruption.

The main impact of SYN floods against the standard TCP stack is not

directly from the floods themselves costing TCP processing overhead

or host memory, but rather from the spoofed SYN packets filling up

the often small listener's queue.

On the other hand, TFO SYN floods can cause damage directly if

admitted without limit into the stack.  The reset (RST) packets from

the spoofed host will fuel rather than defeat the SYN floods as

compared to the non-TFO case, because the attacker can flood more

SYNs with data and incur more cost in terms of data processing

resources.  For this reason, a TFO server needs to monitor the

connections in SYN-RCVD being reset in addition to imposing a

reasonable max queue length.  Implementations may combine the two,

e.g., by continuing to account for those connection requests that

have just been reset against the listener's PendingFastOpenRequests

until a timeout period has passed.

TCP源码—连接建立的更多相关文章

  1. TCP源码—epoll源码及测试

    一.epoll_create & epoll_create1 SYSCALL_DEFINE1(epoll_create, int, size) sys_epoll_create->sys ...

  2. TCP源码—系统调用

    1.socket SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) sys_socket->sock_create-& ...

  3. Linux进阶之Linux破解密码、yum源配置、防火墙设置及源码包安装

    一.老师语录: 所有要求笔试的公司都是垃圾公司 笔试(是考所有的涉及到的点) 要有自己的卖点.专长(给自己个标签)(至少一个) 生产环境中,尽量使用mv(mv到一个没用的目录下),少使用rm 二.防火 ...

  4. Redis源码阅读---连接建立

    对于并发请求很高的生产环境,单个Redis满足不了性能要求,通常都会配置Redis集群来提高服务性能.3.0之后的Redis支持了集群模式. Redis官方提供的集群功能是无中心的,命令请求可以发送到 ...

  5. TCP三次握手Linux源码解析

    TCP是面向连接的协议.面向连接的传输层协议在原点和重点之间建立了一条虚拟路径,同属于一个报文的所有报文段都沿着这条虚拟路径发送,为整个报文使用一条虚拟路径能够更容易地实施确认过程以及对损伤或者丢失报 ...

  6. 我为 Netty 贡献源码 | 且看 Netty 如何应对 TCP 连接的正常关闭,异常关闭,半关闭场景

    欢迎关注公众号:bin的技术小屋,本文图片加载不出来的话可查看公众号原文 本系列Netty源码解析文章基于 4.1.56.Final版本 写在前面..... 本文是笔者肉眼盯 Bug 系列的第三弹,前 ...

  7. TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端

    目录 说明 TCP/UDP通信主要结构 管理多个Socket的解决方案 框架中TCP部分的使用 框架中UDP部分的使用 框架源码结构 补充说明 源码地址 说明 之前有好几篇博客在讲TCP/UDP通信方 ...

  8. 清晰易懂TCP通信原理解析(附demo、简易TCP通信库源码、解决沾包问题等)C#版

    目录 说明 TCP与UDP通信的特点 TCP中的沾包现象 自定义应用层协议 TCPLibrary通信库介绍 Demo演示 未完成功能 源码下载 说明 我前面博客中有多篇文章讲到了.NET中的网络编程, ...

  9. tcprstat源码分析之tcp数据包分析

    tcprstat是percona用来监测mysql响应时间的.不过对于任何运行在TCP协议上的响应时间,都可以用.本文主要做源码分析,如何使用tcprstat请大家查看博文<tcprstat分析 ...

随机推荐

  1. php源码建博客5--建库建表-配置文件-错误日志

    主要: 整理框架 建库建表 配置文件类 错误日志记录 --------------本篇后文件结构:-------------------------------------- blog ├─App │ ...

  2. php源码建博客4--实现MVC结构微型框架

    主要: 常量优化路径 自动加载类 优化入口文件 安全访问项目目录 --------------文件结构:-------------------------------------- blog├─App ...

  3. 帝国cms全文搜索 增加自定义字段搜索

    帝国cms全站搜索功能只能调出固定的几个字段,如果想搜索其他字段的值,这时我们应该怎么办呢?开拓族网站有这个需求,所以研究了一下帝国的全站搜索,后来发现在/e/sch/index.php中可以直接对数 ...

  4. Facade(外观模式或门面模式)

    常用的模式之一. 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 完美地体现了依赖倒转原则和迪米特法则的思想. Facade模式应用场景: 首先 ...

  5. C语言学习记录_2019.02.04

    逻辑性变量的定义符:bool,在C语言中只有true和false: 定义方式:bool t = true; 逻辑运算符: !:逻辑非 &&:逻辑与 ||:逻辑或 表达区间的错误形式:4 ...

  6. JZ2440开发板:修改ARM芯片时钟(学习笔记)

    想要修改ARM芯片的时钟,需要去查询芯片手册和原理图,获取相关的信息(见下方图片) 首先来看时钟的结构图 根据结构图可以看出,时钟源有两种选择:1. XTIpll和XTOpll所连接的晶振 2. EX ...

  7. 9-客户端集成IdentityServer

    1-创建客户端的webapi项目 E:\coding\netcore\IdentityServerSample>dotnet new webapi --name IdentityCredenti ...

  8. 无限滚动HTML UL结构

    http://framework7.taobao.org/docs/infinite-scroll.html#.VUjA7NOqqko

  9. 5 Ways to Prevent the 300ms Click Delay on Mobile Devices

    http://www.sitepoint.com/5-ways-prevent-300ms-click-delay-mobile-devices/

  10. 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1

    原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1 事件聚合器EventAggregator [7.1updated]除了app部分,没 ...