MPTCP 源码分析(五) 接收端窗口值
- SYN队列处理:当服务端收到SYN的时候,此连接请求request_sock将被存放于listening socket的SYN队列,服务端发送SYN/ACK并等待相应的ACK。
- accept队列处理:一旦等待的ACK收到,服务端将会创建新的socket,并将连接请求从listening socket的SYN队列移到其accept队列。

"net/ipv4/tcp_input.c" line of
req = inet_reqsk_alloc(rsk_ops);
if (!req)
goto drop;
static inline void tcp_openreq_init(struct request_sock *req,
struct tcp_options_received *rx_opt,
struct sk_buff *skb)
{
struct inet_request_sock *ireq = inet_rsk(req); req->rcv_wnd = ; /* So that tcp_send_synack() knows! */
req->cookie_ts = ;
tcp_rsk(req)->rcv_isn = TCP_SKB_CB(skb)->seq;
tcp_rsk(req)->rcv_nxt = TCP_SKB_CB(skb)->seq + ;
tcp_rsk(req)->snt_synack = ;
req->mss = rx_opt->mss_clamp;
req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : ;
ireq->tstamp_ok = rx_opt->tstamp_ok;
ireq->sack_ok = rx_opt->sack_ok;
ireq->snd_wscale = rx_opt->snd_wscale;
ireq->wscale_ok = rx_opt->wscale_ok;
ireq->acked = ;
ireq->ecn_ok = ;
ireq->mptcp_rqsk = ;
ireq->saw_mpc = ;
ireq->ir_rmt_port = tcp_hdr(skb)->source;
ireq->ir_num = ntohs(tcp_hdr(skb)->dest);
}
"include/net/tcp.h" line of
struct sock *tcp_create_openreq_child(struct sock *sk,
struct request_sock *req,
struct sk_buff *skb);
"net/ipv4/tcp_minisocks.c" line of
newtp->window_clamp = req->window_clamp;
newtp->rcv_ssthresh = req->rcv_wnd;
newtp->rcv_wnd = req->rcv_wnd;
newtp->rx_opt.wscale_ok = ireq->wscale_ok;

"net/mptcp/mptcp_output.c" line of
u16 mptcp_select_window(struct sock *sk)
{
u16 new_win = tcp_select_window(sk);
struct tcp_sock *tp = tcp_sk(sk);
struct tcp_sock *meta_tp = mptcp_meta_tp(tp); meta_tp->rcv_wnd = tp->rcv_wnd;
meta_tp->rcv_wup = meta_tp->rcv_nxt; return new_win;
}
"net/ipv4/tcp_output.c" line of
u16 tcp_select_window(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
/* The window must never shrink at the meta-level. At the subflow we
279 * have to allow this. Otherwise we may announce a window too large
280 * for the current meta-level sk_rcvbuf.
281 */
u32 cur_win = tcp_receive_window(mptcp(tp) ? tcp_sk(mptcp_meta_sk(sk)) : tp);
u32 new_win = tp->__select_window(sk);
"net/mptcp/mptcp_output.c" line of
u32 __mptcp_select_window(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp);
struct sock *meta_sk = mptcp_meta_sk(sk);
int mss, free_space, full_space, window; /* MSS for the peer's data. Previous versions used mss_clamp
779 * here. I don't know if the value based on our guesses
780 * of peer's MSS is better for the performance. It's more correct
781 * but may be worse for the performance because of rcv_mss
782 * fluctuations. --SAW 1998/11/1
783 */
mss = icsk->icsk_ack.rcv_mss;
free_space = tcp_space(meta_sk);
full_space = min_t(int, meta_tp->window_clamp,
tcp_full_space(meta_sk)); if (mss > full_space)
mss = full_space; if (free_space < (full_space >> )) {
icsk->icsk_ack.quick = ; if (tcp_memory_pressure)
/* TODO this has to be adapted when we support different
797 * MSS's among the subflows.
798 */
meta_tp->rcv_ssthresh = min(meta_tp->rcv_ssthresh,
4U * meta_tp->advmss); if (free_space < mss)
return ;
} if (free_space > meta_tp->rcv_ssthresh)
free_space = meta_tp->rcv_ssthresh; /* Don't do rounding if we are using window scaling, since the
810 * scaled window will not line up with the MSS boundary anyway.
811 */
window = meta_tp->rcv_wnd;
if (tp->rx_opt.rcv_wscale) {
window = free_space; /* Advertise enough space so that it won't get scaled away.
817 * Import case: prevent zero window announcement if
818 * 1<<rcv_wscale > mss.
819 */
if (((window >> tp->rx_opt.rcv_wscale) << tp->
rx_opt.rcv_wscale) != window)
window = (((window >> tp->rx_opt.rcv_wscale) + )
<< tp->rx_opt.rcv_wscale);
} else {
/* Get the largest window that is a nice multiple of mss.
826 * Window clamp already applied above.
827 * If our current window offering is within 1 mss of the
828 * free space we just keep it. This prevents the divide
829 * and multiply from happening most of the time.
830 * We also don't do any window rounding when the free space
831 * is too small.
832 */
if (window <= free_space - mss || window > free_space)
window = (free_space / mss) * mss;
else if (mss == full_space &&
free_space > window + (full_space >> ))
window = free_space;
} return window;
}
- 收到的MSS( icsk->icsk_ack.rcv_mss)
- 套接字缓冲区总的空间(tcp_full_space)
- 套接字缓冲区的空闲空间(tcp_space)
- meta_tp->rcv_ssthresh /* Current window clamp */
MPTCP 源码分析(五) 接收端窗口值的更多相关文章
- Vue系列---理解Vue.nextTick使用及源码分析(五)
_ 阅读目录 一. 什么是Vue.nextTick()? 二. Vue.nextTick()方法的应用场景有哪些? 2.1 更改数据后,进行节点DOM操作. 2.2 在created生命周期中进行DO ...
- vuex 源码分析(五) action 详解
action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...
- jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解
$.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或 ...
- Vue.js 源码分析(五) 基础篇 方法 methods属性详解
methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head&g ...
- ABP源码分析五:ABP初始化全过程
ABP在初始化阶段做了哪些操作,前面的四篇文章大致描述了一下. 为个更清楚的描述其脉络,做了张流程图以辅助说明.其中每一步都涉及很多细节,难以在一张图中全部表现出来.每一步的细节(会涉及到较多接口,类 ...
- java动态代理——代理方法的假设和验证及Proxy源码分析五
前文地址 https://www.cnblogs.com/tera/p/13419025.html 本系列文章主要是博主在学习spring aop的过程中了解到其使用了java动态代理,本着究根问底的 ...
- motan源码分析五:cluster相关
上一章我们分析了客户端调用服务端相关的源码,但是到了cluster里面的部分我们就没有分析了,本章将深入分析cluster和它的相关支持类. 1.clustersupport的创建过程,上一章的Ref ...
- MPTCP 源码分析(一) MPTCP的三次握手
简述: MPTCP依然按照正常的TCP进行三次握手,只是在握手过程中增加了MPTCP特有的信息. 建立过程 三次握手过程如下图所示: 左边客户端发送的第一个SYN包携带有客户端 ...
- MyBatis框架的使用及源码分析(五) DefaultSqlSessionFactory和DefaultSqlSession
我们回顾<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 一文的示例 private static SqlSessionFactory getSessionF ...
随机推荐
- [ Openstack ] Openstack-Mitaka 高可用之 Rabbitmq-server 集群部署
目录 Openstack-Mitaka 高可用之 概述 Openstack-Mitaka 高可用之 环境初始化 Openstack-Mitaka 高可用之 Mariadb-Galera集群 ...
- elasticsearch SpanNearQuery inOrder参数
一直没有注意还有一个inOrder参数: public SpanNearQuery(SpanQuery[] clauses, int slop, boolean inOrder) When inOrd ...
- spring FieldRetrievingFactoryBean
Spring : 基于XML Schema的配置(一): http://www.tuicool.com/articles/mMjY3uI http://www.cnblogs.com/jifeng/a ...
- k8s创建资源的两种方式
命令 vs 配置文件 Kubernetes 支持两种方式创建资源: 1. 用 kubectl 命令直接创建 kubectl run nginx-deployment --image=nginx: -- ...
- hdu 1422(贪心)
重温世界杯 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submiss ...
- Python 进阶 之 @property
@property是一个装饰器,由Python原生库所支持,无需import @property 的作用是将函数变成属性,一般作用于类内的成员函数. 先贴个代码来描述一下@poperty存在的意义: ...
- Go简单的Goroutine示例
最简单的,接下来,会是竞争,加锁... package main import ( "fmt" "runtime" "sync" ) var ...
- 好的web前端是如何拿到30万年薪的?
2018年前端开发不再像过去几年里新技术框架层出不穷,而是各种组件,模块,很多东西都有痕迹可寻,技术都在原来的基础上有了革新和沉淀. 前端招聘方面也在紧跟技术发展,大量“滥竽充数”的速成开发者开始失去 ...
- 【互动问答分享】第5期决胜云计算大数据时代Spark亚太研究院公益大讲堂
Spark亚太研究院100期公益大讲堂 [第5期互动问答分享] Q1:spark怎样支持即席,应该不是spark sql吧,是hive on spark么? Spark1.0 以前支持即席查询的技术是 ...
- python的垃圾回收机制和析构函数__del__
析构函数__del__定义:在类里定义,如果不定义,Python 会在后台提供默认析构函数. 析构函数__del__调用: A.使用del 显式的调用析构函数删除对象时:del对象名: class F ...