简述:
     MPTCP在发送数据方面和TCP的区别是可以从多条路径中选择一条
路径来发送数据。MPTCP在接收数据方面与TCP的区别是子路径对无序包
进行重排后,MPTCP的mpcb需要多所有子路径的包进行排序。查看图1可知。
                                   +-------------------------------+
| Application |
+---------------+ +-------------------------------+
| Application | | MPTCP |
+---------------+ + - - - - - - - + - - - - - - - +
| TCP | | Subflow (TCP) | Subflow (TCP) |
+---------------+ +-------------------------------+
| IP | | IP | IP |
+---------------+ +-------------------------------+ Figure 1: Comparison of Standard TCP and MPTCP Protocol Stacks
 
 
数据序号映射(Data Sequence Mapping) 
     由于所有的数据会通过不同的子路径发送,在接收端MPTCP需要对数据进行重新排序。
因此我们需要数据序号映射。数据序号映射定义从子路径序列空间到数据序列空间的映射。
子路径的序列空间是子路径自身的序列号,而数据序列空间维护着所有需发送的数据。如下图
  红色子路径上的子路径序号分别是1、2,其数据序号是1000、1002。而下面的蓝色的子路径上的子路径序号和
数据序号分别是200,1001。这说明从下面的蓝色子路径已经发送了199个报文,而上面的红色子路径才开始发送。
在MPTCP协议定义如下:
                      1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+--------------------------------------------------------------+
| |
| Data Sequence Number (8 octets) |
| |
+--------------------------------------------------------------+
| Subflow Sequence Number (4 octets) |
+-------------------------------+------------------------------+
| Data-Level Length (2 octets) | Zeros (2 octets) |
+-------------------------------+------------------------------+
 
 
内核中的实现:
     函数mptcp_write_dss_mapping对 Data Sequeue Number  和  Subflow Sequence Number进行了赋值。实现如下:
"net/mptcp/mptcp_output.c" line  of
static int mptcp_write_dss_mapping(struct tcp_sock *tp, struct sk_buff *skb,
__be32 *ptr)
{
struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
__be32 *start = ptr;
__u16 data_len; *ptr++ = htonl(tcb->seq); /* data_seq */ /* If it's a non-data DATA_FIN, we set subseq to 0 (draft v7) */
if (mptcp_is_data_fin(skb) && skb->len == )
*ptr++ = ; /* subseq */
else
*ptr++ = htonl(tp->write_seq - tp->mptcp->snt_isn); /* subseq */
第325行和331行分别对子路径序号和数据序号进行了赋值。
###
data_seq and subseq
The mapping is identify by the relative subflow seq, the data seq and
the data len. Basically, it means that isn+sub_seq->isn+sub_seq+len at
the subflow-level corresponds to data_seq->data_seq+len at the
connection-level.
###
 
数据接收中的重组
     内核使用三种队列接收数据,分别是:Backlog queue(sk->backlog)、Prequeue queue(tp->ucopy.prequeue)
和 Receive queue (sk->receeive_queue)。MPTCP的实现增加了一个新的队列out-of-order queue对于各个子路径
收到的数据进行重组。内核中 tcp_v4_rcv()的关键实现如下:
"net/ipv4/tcp_ipv4.c" line  of
if (mptcp(tcp_sk(sk))) {
meta_sk = mptcp_meta_sk(sk); bh_lock_sock_nested(meta_sk);
if (sock_owned_by_user(meta_sk))
skb->sk = sk;
} else {
meta_sk = sk;
bh_lock_sock_nested(sk);
} ret = ;
if (!sock_owned_by_user(meta_sk)) {
#ifdef CONFIG_NET_DMA
struct tcp_sock *tp = tcp_sk(meta_sk);
if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
tp->ucopy.dma_chan = net_dma_find_channel();
if (tp->ucopy.dma_chan)
ret = tcp_v4_do_rcv(sk, skb);
else
#endif
{
if (!tcp_prequeue(meta_sk, skb))
ret = tcp_v4_do_rcv(sk, skb);
}
} else if (unlikely(sk_add_backlog(meta_sk, skb,
meta_sk->sk_rcvbuf + meta_sk->sk_sndbuf))) {
bh_unlock_sock(meta_sk);
NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
goto discard_and_relse;
}
bh_unlock_sock(meta_sk);
从第1757和1760可以看出skb只进入meta的backlog和prequeue,而和子路径的sock没有什么关系。因此,我们得出包的入队操作如下:
1.进入meta_sk的backlog
2.进入meta_sk的prequeue
3.进入子路径的receive_queue
第1和2种入队操作后续操作和正常TCP一致,如果是第3种情况,后续将通过函数mptcp_queue_skb()进入tcp_sk(meta_sk)->out_of_order_queue。
 
结论:
1.MPTCP利用自身的Data Sequeue Number  和  Subflow Sequence Number进行了数据在各种子路径间的传输。此实现独立于TCP。
2.为了实现子路径的数据重组,MPTCP利用了队列out_of_order_queue。
 
   
 
 
问题:
1. DATA_ACK作用是?

The Data ACK is analogous to the behavior of the  standard TCP
 cumulative ACK -- indicating how much data has been  successfully received (with no holes). The Data ACK specifies the next data sequence number it expects to
receive.


MPTCP 源码分析(四) 发送和接收数据的更多相关文章

  1. RocketMQ 源码分析 —— Message 发送与接收

    1.概述 Producer 发送消息.主要是同步发送消息源码,涉及到 异步/Oneway发送消息,事务消息会跳过. Broker 接收消息.(存储消息在<RocketMQ 源码分析 —— Mes ...

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

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

  3. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  4. ifconfig源码分析之与内核交互数据

    <ifconfig源码分析之与内核交互数据>本文档的Copyleft归rosetta所有,使用GPL发布,可以自由拷贝.转载,转载时请保持文档的完整性.参考资料:<Linux设备驱动 ...

  5. 鸿蒙内核源码分析(管道文件篇) | 如何降低数据流动成本 | 百篇博客分析OpenHarmony源码 | v70.01

    百篇博客系列篇.本篇为: v70.xx 鸿蒙内核源码分析(管道文件篇) | 如何降低数据流动成本 | 51.c.h.o 文件系统相关篇为: v62.xx 鸿蒙内核源码分析(文件概念篇) | 为什么说一 ...

  6. ABP源码分析四:Configuration

    核心模块的配置 Configuration是ABP中设计比较巧妙的地方.其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配 ...

  7. ABP源码分析四十七:ABP中的异常处理

    ABP 中异常处理的思路是很清晰的.一共五种类型的异常类. AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationExce ...

  8. docker 源码分析 四(基于1.8.2版本),Docker镜像的获取和存储

    前段时间一直忙些其他事情,docker源码分析的事情耽搁了,今天接着写,上一章了解了docker client 和 docker daemon(会启动一个http server)是C/S的结构,cli ...

  9. [Hadoop] - TaskTracker源码分析(状态发送)

    TaskTracker节点向JobTracker汇报当前节点的运行时信息时候,是将运行状态信息同心跳报告一起发送给JobTracker的,主要包括TaskTracker的基本信息.节点资源使用信息.各 ...

随机推荐

  1. [ Python - 14 ] python进程及线程编程

    什么是进程: 简单来讲,进程就是操作系统中运行的程序或任务,进程和程序的区别在于进程是动态的,而程序是静态的.进程是操作系统资源管理的最小单位. 什么是线程: 线程是进程的一个实体,是cpu调度和分派 ...

  2. 某dp题2

    P2401 不等数列 题目描述 将1到n任意排列,然后在排列的每两个数之间根据他们的大小关系插入">"和"<".问在所有排列中,有多少个排列恰好有k ...

  3. java异常基本知识

    Throwable     |--Error     |--Exception         |--RuntimeException                异常体系的特点:异常体系中的所有类 ...

  4. SecureCRT的安装、介绍、简单操作

    网上看到一篇名为<SecureCRT的使用方法和技巧(详细使用教程)>的secureCRT教程,可能软件版本与我不一样我安装的是8.1. 原文来源:http://www.jb51.net/ ...

  5. CF 917A The Monster 【括号匹配】

    [链接]:CF Examples inputCopy ((?)) outputCopy 4 inputCopy ??()?? outputCopy 7 说明 For the first sample ...

  6. 博弈论与SG函数

    巴什博奕: 两个顶尖聪明的人在玩游戏,有n个石子,每人可以随便拿1−m个石子,不能拿的人为败者,问谁会胜利 结论: 设当前的石子数为\(n=k∗(m+1)\)即\(n%(m+1)==0\)时先手一定失 ...

  7. [LOJ6436]神仙的游戏

    感觉border的性质还是挺神奇的 一个border的性质是$S$有长度为$len$的border当且仅当对$\forall i\equiv j\left(\bmod(n-len)\right)$有$ ...

  8. 【分块】hdu5057 Argestes and Sequence

    分块,v[i][j][k]表示第i块内第j位是k的元素数.非常好写.注意初始化 要注意题意,①第i位是从右往左算的. ②若x没有第i位,则用前导零补齐10位.比如103---->00000001 ...

  9. java 面向接口编程的理解

    初学者可能在学习中会有很多疑惑,为什么要这样,明明可以那样实现,这样做的好处又是什么? 可能会的人觉得很简单很容易理解,甚至可能觉得问的问题很智障,但对于小白来说可能是苦思冥想都不得其解的. 自己身为 ...

  10. SpringMVC(流程+第一个Demo)

    一.流程图 用户发送请求至前端控制器DispatcherServlet DispatcherServlet收到请求调用HandlerMapping处理器映射器. 处理器映射器根据请求url找到具体的处 ...