一、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. day04-decorator

    # Author: 刘佳赐-Isabelle # Email: jiaci.liu@gmail.com ''' 练习题: 1.整理装饰器的形成过程,背诵装饰器的固定格式 2.编写装饰器,在每次执行被装 ...

  2. python3 练习题100例 (三)

    题目三:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? #!/usr/bin/env python3 # -*- coding: utf-8 -*- &qu ...

  3. linux动态链接库

    前言 静态链接库会编译进可执行文件,并被加载到内存,会造成空间浪费 静态链接库对程序的更新.部署.发布带来麻烦.如果静态库更新了,使用它的应用程序都需要重新编译.发布给用户(对于玩家来说,可能是一个很 ...

  4. Divisibility题解

    From lyh 学长 2018.5.3 信(liang)心(liang)杯T3 一道略弱的数论题. 题目描述 给定 n个数,问是否能从中选出恰好 k个数,使得这些数两两之差可以被 m 整除. 输入输 ...

  5. 20145209 2016-2017-2 《Java程序设计》第4周学习总结

    20145209 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 继承是面向对象最显著的一个特性.继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性 ...

  6. 你想找的Python资料这里全都有!没有你找不到!史上最全资料合集

    你想找的Python资料这里全都有!没有你找不到!史上最全资料合集 2017年11月15日 13:48:53 技术小百科 阅读数:1931   GitHub 上有一个 Awesome - XXX 系列 ...

  7. 一个体验好的Windows 任务栏缩略图开发心得

    本文来自网易云社区 作者:孙有军 前言: 对于一个追求极致体验的软件来说,利用好系统的每一点优秀的特性,将会大大提高软件的品质. Windows vista以来任务栏缩略图,及Win + TAB的程序 ...

  8. Android性能优化来龙去脉总结

    WeTest 导读 一款app除了要有令人惊叹的功能和令人发指交互之外,在性能上也应该追求丝滑的要求,这样才能更好地提高用户体验. 以下是本人在工作中对经历过的性能优化的一些总结,依据故事的发展路线, ...

  9. WPF & EF & Prism useful links

    Prism Attributes for MEF https://msdn.microsoft.com/en-us/library/ee155691%28v=vs.110%29.aspx Generi ...

  10. 基于阿里云服务器Linux系统安装配置Redis

    一.Redis简介 Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(有 ...