一、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. Mysql 关于处理NULL值的相关函数和操作符

    操作符 <=> NULL-safe equal. This operator performs an equality comparison like the = operator, bu ...

  2. hive 入门

    hive-site.xml 配置 <configuration> <property> <name>javax.jdo.option.ConnectionURL&l ...

  3. STM32学习日志

    今天是开学第二周周末 写这篇博客纯属是为了记住一些学到的知识,大佬勿喷.. 首先学32要知道一些选型知识,32中常用的芯片类型(某宝常卖的开发板芯片大多是这几种):C8T6,RBT6,RCT6,VET ...

  4. UART学习之路(四)VerilogHDL实现的简单UART,VIVADO下完成仿真

    用VerilogHDL实现UART并完成仿真就算是对UART整个技术有了全面的理解,同时也算是Verilog入门了.整个UART分为3部分完成,发送模块(Transmitter),接收模块(Recei ...

  5. 黑匣子_KEY

    黑匣子 (box.pas/c/cpp) [ 问题描述] 某研究小组成员想发明一个黑匣子( 当然不是飞机上那个), 而是一个具有特殊功能的箱子. 这个箱子具有两个功能: 1. 存放一些正整数 x: 2. ...

  6. Dota2一直 正在登录服务器的解决办法

    然后:1: c:\Windows\System32\drivers\etc\ 2:双击hosts文件,用记事本方式打开3:复制以下并粘贴至以记事本方式打开的hosts最后面111.221.33.253 ...

  7. Linker加载so失败问题分析

    WeTest 导读 近期测试反馈一个问题,在旧版本微视基础上覆盖安装新版本的微视APP,首次打开拍摄页录制视频合成时高概率出现crash. 那么我们直奔主题,看看日志: 另外复现的日志中还出现如下信息 ...

  8. Prism MEF example

    Related Attributes These attributes are under namespace System.ComponentModel.Composition Import The ...

  9. Qt-QML-Charts-ChartView-编译错误-ASSERT: "!"No style available without QApplication!

    昨天本来是回家想好好琢磨一下使用Chart来绘制曲线的,奈何在建立项目的时候也就卡住了,加上心情比较烦躁,也没有耐心寻找答案就草草了事.所以今天继续搞定这个. 上图是Qt 的编译错误截图 QML de ...

  10. js 加密 crypto-js des加密

    js 加密 crypto-js    https://www.npmjs.com/package/crypto-js   DES  举例:   js 引入:   <script src=&quo ...