简述

     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. DRF自带的Request和Response对象(DRF基类APIView)

    # 转载请留言联系 1.Request对象 DRF传入视图的request对象,不再是Django默认的HttpRequest对象,而是扩展了HttpRequest类的Request类的对象. RES ...

  2. JavaScript的for循环语句

    语法格式 for(初始化值;循环的条件;每一次循环的递增值){ // 循环的条件结果为true,则执行循环体中的代码 } 示例(打印出1-10之间的整数): for(var a=1;a<=10; ...

  3. docker从零开始(二)容器初体验

    使用定义容器 Dockerfile Dockerfile定义容器内所需要的环境.对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具 ...

  4. [BZOJ4006][JLOI2015]管道连接 状压dp+斯坦纳树

    4006: [JLOI2015]管道连接 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1020  Solved: 552[Submit][Statu ...

  5. 理解和上手Redux

    顾名思义本文分两个部分,理解和上手,第一部分我先讲个故事,这个故事也许不是特别形象,但对大家理解Redux一定有所帮助.第二部分我举个例子. 先讲个故事: 一个餐厅(应用),我是顾客(用户),这个餐厅 ...

  6. Nessus home与Nexpose community 对比

    转载请注明来源:http://www.cnblogs.com/phoenix--/p/3345569.html 更新:Nessus home版限制了,总量:16,Nexpose限制了总量为32,全部没 ...

  7. RAID磁盘恢复方法之一Winhex镜像硬盘与镜像中恢复数据图文

    winhex镜像硬盘和ghost备份是完全不同的,ghost只能克隆或者镜像分区内正常的数据,删除的数据他是不会克隆的,所以在数据恢复应用中,ghost对我们来讲作用就不大了,而使用winhex备份( ...

  8. 神器mimikatz使用命令方法总结

    神器mimikatz使用命令方法总结 文章地址:http://www.isharepc.com/300.html mimikatz是一款功能强大的轻量级调试神器,通过它你可以提升进程权限注入进程读取进 ...

  9. 静态页面表单中js验证

    笔记: 1. onblur事件:onblur 事件会在对象失去焦点时发生.http://www.w3school.com.cn/jsref/event_onblur.asp onkeyup事件:onk ...

  10. (2)Flutter vscode安装

    1. vscode搜索Flutter 点击安装Flutter会自动安装Flutter和Dart 2.打开项目 在vscode File-openFolder打开之前创建的项目 成功显示 如果创建一个新 ...