简述

     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. 《Java编程思想》笔记 第二十一章 并发

    1.定义任务 实现Runnable 接口的类就是任务类(任务类不一定是实现Runnable接口的类). 实现Runnable 接口,重写run()方法,run方法的返回值只能是 void 任务类就是表 ...

  2. tushare 安装

    1.pip install lxml 2.pip install pandas 3.pip install requests 4.pip install lxml 5.pip install tush ...

  3. docker从零开始网络(七) 配置daemon和容器

    启用IPv6支持 在Docker容器或swarm服务中使用IPv6之前,需要在Docker守护程序中启用IPv6支持.之后,您可以选择将IPv4或IPv6(或两者)与任何容器,服务或网络一起使用. 注 ...

  4. python中的enumerate使用

    enumerate函数用于遍历序列中的元素以及它们的下标,多用于在for循环中得到计数,enumerate参数为可遍历的变量,如 字符串,列表等 一般情况下对一个列表或数组既要遍历索引又要遍历元素时, ...

  5. Redis安装-CentOs7

    官方地址 确保gcc已经安装 $ yum list installed | grep gcc $ yum install gcc 下载.提取和编辑Redis: $ wget http://downlo ...

  6. [ThinkPHP] 独立分组配置,坑!!!

    'APP_GROUP_LIST'=>'Index,Admin', //逗号后面别跟空格啊,真是逗

  7. (12)python 标准库

    模块 如果模块和自己写的程序不在同一个目录,可以通过sys.path.append(路径)把程序引入 import sys sys.path.append('C:/abc')#注意 \ 的方向 意思是 ...

  8. UTC时间

    世界的每个地区都有自己的本地时间,在Internet及无线电通信时,时间的统一非常重要! 整个地球分为二十四时区,每个时区都有自己的本地时间.在国际无线电通信中,为统一而普遍使用一个标准时间,称为通用 ...

  9. 洛谷 P3397 地毯 【二维差分标记】

    题目背景 此题约为NOIP提高组Day2T1难度. 题目描述 在n*n的格子上有m个地毯. 给出这些地毯的信息,问每个点被多少个地毯覆盖. 输入输出格式 输入格式: 第一行,两个正整数n.m.意义如题 ...

  10. openssl生成证书链多级证书

    操作系统CentOS6.6 注:windows版本的Openssl无法做这个实验,由于所有编译的window版本openssl没有对openssl目录重新定向,导致在windows下找不到pki目录 ...