简述

     TCP使用定时器函数tcp_retransmit_timer进行数据重发,MPTCP需要重发数据的时候,
不仅仅在原路径发送数据,而且会在另外一条子路径进行重发。这样考虑的原因是:
考虑网络中间件设备的影响, 保证子路径上数据序列号的完整性。目前的版本0.89依然如此实现,
以后应该会优化。
 
内核实现
     MPTCP的结构如下图所示:
  如上图所示:每一个slave subsock 和 master subsock实际上维持着一个正常的TCP链路,因此,他们都具有
重发定时器tcp_write_timer。MPTCP实现的思路就是:每个子链路发送失败的时候,将发送失败的SKB拷贝一份
到meta sock。然后让meta sock 再次选择另外一条子路径发送。
     如下是对tcp_retransmit_timer的修改:
"net/ipv4/tcp_timer.c"  line  of 

 out:;
if (mptcp(tp)) {
mptcp_reinject_data(sk, );
mptcp_set_rto(sk);
}
}

函数mptcp_reinject_data的实现如下:

"net/mptcp/mptcp_output.c" line  of
/* Inserts data into the reinject queue */
void mptcp_reinject_data(struct sock *sk, int clone_it)
{
struct sk_buff *skb_it, *tmp;
struct tcp_sock *tp = tcp_sk(sk);
struct sock *meta_sk = tp->meta_sk; /* It has already been closed - there is really no point in reinjecting */
if (meta_sk->sk_state == TCP_CLOSE)
return; skb_queue_walk_safe(&sk->sk_write_queue, skb_it, tmp) {
struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it);
/* Subflow syn's and fin's are not reinjected.
250 *
251 * As well as empty subflow-fins with a data-fin.
252 * They are reinjected below (without the subflow-fin-flag)
253 */
if (tcb->tcp_flags & TCPHDR_SYN ||
(tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) ||
(tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len))
continue; __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it);
} skb_it = tcp_write_queue_tail(meta_sk);
/* If sk has sent the empty data-fin, we have to reinject it too. */
if (skb_it && mptcp_is_data_fin(skb_it) && skb_it->len == &&
TCP_SKB_CB(skb_it)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index)) {
__mptcp_reinject_data(skb_it, meta_sk, NULL, );
} mptcp_push_pending_frames(meta_sk); tp->pf = ;
}
第259行的__mptcp_reinject_data函数将出现超时的sk->sk_write_queue的数据拷贝到 meta_sk 的reinject queue。
而269行的函数mptcp_push_pending_frames将会对reinject queue中的数据进行发送,其调用关系如下:
mptcp_push_pending_frames
                                        =》__tcp_push_pending_frames
                                             =》tcp_sk(sk)->write_xmit
                                                  =》mptcp_write_xmit
                                                       =》mptcp_next_segment
                                                            =》__mptcp_next_segment
                                                            =》get_available_subflow
 
结论 :
1.子路径出现重发数据的情况下,MPTCP会选择另外一条路径发送同样的数据。

MPTCP 源码分析(六) 数据重发的更多相关文章

  1. MPTCP 源码分析(五) 接收端窗口值

    简述:      在TCP协议中影响数据发送的三个因素分别为:发送端窗口值.接收端窗口值和拥塞窗口值. 本文主要分析MPTCP中各个子路径对接收端窗口值rcv_wnd的处理.   接收端窗口值的初始化 ...

  2. HDFS源码分析之数据块及副本状态BlockUCState、ReplicaState

    关于数据块.副本的介绍,请参考文章<HDFS源码分析之数据块Block.副本Replica>. 一.数据块状态BlockUCState 数据块状态用枚举类BlockUCState来表示,代 ...

  3. jQuery 源码分析(十) 数据缓存模块 data详解

    jQuery的数据缓存模块以一种安全的方式为DOM元素附加任意类型的数据,避免了在JavaScript对象和DOM元素之间出现循环引用,以及由此而导致的内存泄漏. 数据缓存模块为DOM元素和JavaS ...

  4. ABP源码分析六:依赖注入的实现

    ABP的依赖注入的实现有一个本质两个途径:1.本质上是依赖于Castle这个老牌依赖注入的框架.2.一种实现途径是通过实现IConventionalDependencyRegistrar的实例定义注入 ...

  5. SOFA 源码分析 — 链路数据透传

    前言 SOFA-RPC 支持数据链路透传功能,官方解释: 链路数据透传功能支持应用向调用上下文中存放数据,达到整个链路上的应用都可以操作该数据. 使用方式如下,可分别向链路的 request 和 re ...

  6. springMVC源码分析--HttpMessageConverter数据转化(一)

    之前的博客我们已经介绍了很多springMVC相关的模块,接下来我们介绍一下springMVC在获取参数和返回结果值方面的处理.虽然在之前的博客老田已经分别介绍了参数处理器和返回值处理器: (1)sp ...

  7. Hadoop源码分析之数据节点的握手,注册,上报数据块和心跳

    转自:http://www.it165.net/admin/html/201402/2382.html 在上一篇文章Hadoop源码分析之DataNode的启动与停止中分析了DataNode节点的启动 ...

  8. Android 7.0 Gallery图库源码分析3 - 数据加载及显示流程

    前面分析Gallery启动流程时,说了传给DataManager的data的key是AlbumSetPage.KEY_MEDIA_PATH,value值,是”/combo/{/local/all,/p ...

  9. 11.源码分析---SOFARPC数据透传是实现的?

    先把栗子放上,让大家方便测试用: Service端 public static void main(String[] args) { ServerConfig serverConfig = new S ...

随机推荐

  1. C++类中引用成员和常量成员的初始化(初始化列表)

    如果一个类是这样定义的: Class A { public: A(int pram1, int pram2, int pram3); privite: int a; int &b; const ...

  2. P1029 最大公约数和最小公倍数问题

    题目描述 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件: 1.P,Q是正整数 2.要求P,Q以x0为 ...

  3. 【SQL】约束与触发器1

    一.外键 1.1特点 表A的外键,一定是其他某个表B的主键或有UNIQUE声明的属性. A的外键的值,一定是对应表B中相应的属性值.(空值除外) 1.2声明方法 方法1:属性名 类型 REFERENC ...

  4. CentOS7配置阿里云yum源和EPEL源

    配置阿里云yum源(参考:http://mirrors.aliyun.com/help/centos) 1.备份 [root@bogon ~]# cd /etc/yum.repos.d/ [root@ ...

  5. (十)while和until循环

    (1)while循环 语法:当条件测试成立(真),执行循环体 while 条件测试 do 循环体 done 1)while批量创建用户1 从user.txt读取到的行数据赋予给变量user值 #!/b ...

  6. linux程序与进程内存结构

    1.可执行文件结构: 1)代码区:包含操作码和操作对象.常量数据(const声明).立即数,代码区是共享的, 只提供只读. 2)全局/静态数据区:包含被初始化的全局数据和初始化静态数据. 3)未初始化 ...

  7. oracle tablespace usage status

    select a.tablespace_name, a.bytes / 1024 / 1024 "Sum MB", (a.bytes - b.bytes) / 1024 / 102 ...

  8. REST SOAP XML-RPC分析比较

    本文的标题“REST与SOAP之比较”确实有些让人误解.REST是代表性状态传输的名称首字母缩写,与其说它是标准,不如说是一种风格.然而,在我的前一篇文章中,正如我们所讨论的,众多从事Web服务的软件 ...

  9. JVM的参数配置

    JVM管理的内存叫堆.在32Bit操作系统上有1.5G-2G的限制,而64Bit的就没有. JVM初始分配的内存由-Xms指定,默认是物理内存的1/64但小于1G. JVM最大分配的内存由-Xmx指定 ...

  10. [BZOJ2111][ZJOI2010]Perm排列计数(组合数学)

    题意就是求一个n个点的堆的合法形态数. 显然,给定堆中所有数的集合,则这个堆的根是确定的,而由于堆是完全二叉树,所以每个点左右子树的大小也是确定的. 设以i为根的堆的形态数为F(i),所以F(i)+= ...