JasonWang's Blog

投屏中的服务发现协议

投屏是指将某个终端的音视频或者其他内容通过有线或者无线的形式投射到其他终端上的一种协议。目前常见的投屏协议有DLNA/Airplay/Mirracast/Chromecast:

  • DLNA(Digital Living Network Alliance): DNLA是由英特尔、索尼、微软等消费电子巨头在2003年建立的一个文件共享协议,目前很多的电视都会支持DLNA协议,用于手机与电视之间共享视频与图片等资源。
  • Airplay: Airplay是苹果公司开发的一个私有的投屏协议,实际包含了视频投屏与屏幕镜像等几个功能(音视频数据流包括交互控制协议都有是加密的),可以用于播放音频、视频,也可以把本地的图片投屏到电视上进行浏览。目前国内很多支持Airplay的投屏协议都是基于秘钥破解进行开发的。
为什么iperf测试时UDP会出现高丢包率

这两天质量的同学反馈说iperf测试时结果很差,跟实际的千兆带宽差别很大。确认了半天,发现内核的各项参数都已经完全按照千兆的目标速率进行配置了,那为什么还是会出现TCP/UDP带宽不足的问题? 记得当时优化参数时,自己摸底测试的TCP结果挺好的,都达到了预期的900Mbps以上,看起来最近有什么修改导致了这个测试结果差异。

偶然的一个机会查看内核配置时,发现最近有人打开了trace功能,看起来很可能是这个修改导致了网络性能的下降了。拿早前未开启trace功能的版本一对比,果真是trace功能影响了TCP的带宽。

Linux网络优化之AVB/TSN

这是Linux网络优化系列的第四篇文章,也是最后一篇了。最近有点忙,没有抽出时间来梳理这些知识点, 看了下文章历史,这个优化系列文章前后持续了大半年时间,今天总算达成了目标*_*。

背景

自从互联网诞生以来, 音视频(Audio/Video, AV)在网络上传输已经是稀松平常的事情. 那么, 为什么还需要一个新的基于以太网的协议来传输AV数据了? 传统的音视频传输都是点对点单向连接, 比如音频通常使用I2SSPDIF/AES; 视频则使用SDI或者HDMI, 这种专用的单向连接在多设备情况下往往容易出现杂乱无章的连接线束:

Linux网络优化之DPDK与XDP

在前面的一篇文章Linux网络优化之链路层优化中,我们已经看到,随着网卡速率超过1Gbps,增加到10Gbps/100Gbps时,CPU已经很难处理如此大量的数据包了。总结来说,主要有如下瓶颈:

  • 内核协议栈处理在L3(IP)/L4(TCP)的数据处理上,消耗了比较多的时间,会导致网络延迟与传输受限
  • 高速网卡会在短时间内产生大量中断,导致CPU频繁发生上下文切换,性能收到影响,进而影响网络吞吐

针对10Gbps/100Gbps等高速网卡中存在的延迟与带宽受限问题,Intel在2010年提出了DPDK(Data Plane Development Kit)基于用户空间的解决方案,并开源了实现方案, 目前DPDK支持包括Intel/ARM等多个芯片架构的指令集; 同样是Intel的工程师在2018年提出了XDP(eXpress Data Path),与DPDK不一样的是,XDP基于现有内核socket接口,与eBPF相结合实现网卡与用户空间的数据传输,从而避免了内核协议栈的处理延迟。

Linux网络优化之TCP优化

TCP(Transmision Control Protocol)即传输控制协议, 位于TCP/IP协议栈的第三层(L3), 是一种提供了可靠连接的字节流协议; TCP是目前使用最为广泛的协议之一, HTTP/MQTT/FTP等诸多应用层协议都是基于TCP实现的, 更多关于TCP协议相关的具体内容可以参考标准文档RFC793以及早前写的一篇聊一聊TCP协议.

在上一篇文章中讲到了高速以太网如1Gbps/10Gpbs中Linux网络L2(链路层)的一些优化方法, 包括了offload(卸荷)以及scaling(缩放)两种技术. 随着高速网络的不断普及, 1Gbps/10Gpbs以太网已经被广泛使用, 40Gbps/100Gbps也已经制定标准, TCP也在随着网络带宽的提升而不断进化.这篇文章我们就来看下如何在高速以太网下对TCP相关的参数的进行调优.

Linux网络优化之链路层优化

现在车内网络都开始内卷到1Gbps了, 有同学给我反馈说以太网的吞吐量上不来, 跟理论带宽差距很大, 之前虽然优化了一波TCP相关的参数, 但估计不能解决全部问题. 遂决定重新学习下网络优化, 从底层链路对开发平台上的网络进行改善. 趁着这个机会, 索性写一个系列文章-Linux网络优化, 用来总结下Linux网络优化的一些方法与技术, 目前计划从如下几篇文章展开(希望不要放飞了):

这篇文章主要讲第一个话题: Linux是如何在数据链路层L2对网络数据的接收与发送进行优化的.

如何用pktgen测试网卡性能?

在优化网络性能时, 不可避免要对网络的带宽进行测试. 通常大家可能都会使用iperf来执行网络链路的吞吐量测试, 但iperf只能测试TCP/IP协议层的速度, 这个带宽数据跟TCP/UDP协议的参数配置以及应用层缓冲区的大小都有关系. 有时, 我们希望直接测试网卡本身的实际吞吐量, 看看网卡实际的发包能力. Linux内核提供了pktgen工具用以产生数据包, 向网卡注入TCP/UDP数据. 这里, 我们就来看下具体如何通过pktgen来测试网卡性能.

ARP cache不更新导致的网络问题

最近碰到了一个很奇怪的问题, Android系统(Linux内核4.15)唤醒后, SoC(高通平台)跟TBox(Telematics Box)TCP的连接会偶发变慢, 需要等超过10s才能连接上. 发送ping包给TBox, 通过strace看进程一直提示EAGAIN的错误.从字面意义来说EAGAIN(Resource temporarily unavailable)是内核告知ping进程当前没有可用的数据包可以接收. 可是, 问题来了:

  • 为什么ping一直会收到EAGAIN的错误? 内核在什么时候会返回该错误?
  • 为什么ping收不到数据包, TBox回包到底去了哪里?

幸亏好这个问题比较容易重现, 折腾了两天才最终把问题的的来龙去脉搞清楚. 接下来就来看看这个问题的现象以及背后发生的根因, 最后给出几个相应的对策.

Linux网络协议之数据发送流程

最近抽空学习下Linux网络协议栈, 读源码时总会前一天梳理完, 等两天再来看却发现又忘记的差不多, 只能再过一遍, 没有对协议栈构建一个系统性的框架. 于是想着要把看过的代码逻辑整理下来, 算是对这段时间学习的总结, 也方便后面的查阅.

在之前的一篇有关网络协议的文章从NAPI说一说Linux内核数据的接收流程简单的讲到了Linux的数据接收流程, 但主要是集中在数据链路层与设备驱动之间的交互, 并没有涉及到IP网络层以及TCP传输层的逻辑.对于Linux系统来说, TCP数据的传输大致要经历如下几个步骤:

  • 用户进程创建socket并创建相应数据的buffer, 通过send函数发送给服务端
  • 内核收到数据后, 将用户空间的buffer数据拷贝到内核协议栈
  • 内核协议栈需要经过TCP层(L4)/IP层(L3)/数据链路层(L2)最后发送到网卡
  • CPU与网卡的数据传输一般通过DMA进行, 完成后网卡发送中断告知CPU, 此时内核会释放之前分配的buffer

这篇文章, 我们着重来看下数据传输中内核部分的流程, 并梳理下Linux协议栈大致的结构与初始化步骤, 主要分为如下两个部分:

  • Linux内核协议栈的初始化流程
  • 数据是如何从TCP传输层发送到设备驱动的
IPV6地址的那些事儿

前阵子在Android下调试一个只有IPv6地址的网络设备时,发现通过ping6来测试网络连通时提示错误:

1
2
3
4

ping6 fe80::47af:e871:3c63:a272
connect: Invalid argument

stackoverflow上有人说这是一个link-local address本地链路地址,