linux没有tcptimestamp

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux没有tcptimestamp相关的知识,希望对你有一定的参考价值。

Linux中没有TCP Timestamp选项,它是一个由Windows操作系统提供的网络协议特性,用于优化TCP连接质量。它可以通过在数据段中添加一个特殊的字段来实现对TCP连接质量的优化,这种字段就是时间戳。这种机制可以通过回复发送时间戳,帮助探测网络延迟并实现网络优化,不过因为Linux不支持TCP Timestamp选项,所以无法实现这种功能。 参考技术A 敬,而是这玩意儿没鸟用。

还是 TCP Timestamps 的精度问题,本文仅针对 Linux TCP,不针对别的实现,看一下为什么它没鸟用。

源码分析,看我添加的注释:

static bool tcp_ack_update_rtt(struct sock *sk, const int flag,
long seq_rtt_us, long sack_rtt_us,
long ca_rtt_us, struct rate_sample *rs)

const struct tcp_sock *tp = tcp_sk(sk);

/* Prefer RTT measured from ACK's timing to TS-ECR. This is because
* broken middle-boxes or peers may corrupt TS-ECR fields. But
* Karn's algorithm forbids taking RTT if some retransmitted data
* is acked (RFC6298).
*/
// 不要优先选择时间戳计算 RTT,但这里是另一个理由。
if (seq_rtt_us < 0)
seq_rtt_us = sack_rtt_us;

/* RTTM Rule: A TSecr value received in a segment is used to
* update the averaged RTT measurement only if the segment
* acknowledges some new data, i.e., only if it advances the
* left edge of the send window.
* See draft-ietf-tcplw-high-performance-00, section 3.3.
*/
// 到此为止,看看 seq_rtt_us,ca_rtt_us 的单位,us,这是微秒,1000 us = 1 ms
if (seq_rtt_us < 0 && tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
flag & FLAG_ACKED)
u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr;
// TCP 时间戳单位是 ms,这里 delta 是两个 ms 相见,只有 ms 精度。
if (likely(delta < INT_MAX / (USEC_PER_SEC / TCP_TS_HZ)))
if (!delta)
delta = 1;
// seq_rtt_us 的最小值是 1000,这里就是问题所在。
// 曾经,没有 delta = max(delta, 1),那时 delta 最小值就是 0。
seq_rtt_us = delta * (USEC_PER_SEC / TCP_TS_HZ);
ca_rtt_us = seq_rtt_us;


rs->rtt_us = ca_rtt_us; /* RTT of last (S)ACKed packet (or -1) */
if (seq_rtt_us < 0)
return false;

/* ca_rtt_us >= 0 is counting on the invariant that ca_rtt_us is
* always taken together with ACK, SACK, or TS-opts. Any negative
* values will be skipped with the seq_rtt_us < 0 check above.
*/
tcp_update_rtt_min(sk, ca_rtt_us, flag);
tcp_rtt_estimator(sk, seq_rtt_us);
tcp_set_rto(sk);

/* RFC6298: only reset backoff on valid RTT measurement. */
inet_csk(sk)->icsk_backoff = 0;
return true;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
发生重传且没有序列被 SACKed ,若开启 Timestamps,Linux TCP 使用 tsecr 和当前 ms 的差计算 RTT,这在 ms 精度时代是个优化,但在 us 精度时代就是累赘。

上述代码来自 5.10 内核,检测到乱序或丢包时,灌入 tcp_update_rtt_min 和 tcp_rtt_estimator 的 RTT 参数最小值为 1000,这对于 IDC 网络而言实在太大了,在 50 us 级 RTT 的连接中,1000 us 就是个噪点,它会拉偏 RTT 的移动指数平均值,进而拉偏 RTO。

检测到乱序或丢包,对端立即回复 ACK,此时实际 RTT 足够小到排除掉对端任何 Delay,若丢包属于随机丢包而非拥塞,该 RTT 有希望更新 rtt_min,但为了避免精度损失导致 delta == 0 异常,增加 delta = max(delta, 1) 约束,从而将足够大的值注入计算,反而帮了倒忙。

可若不增加 delta = max(delta, 1) 约束,又会遇到 0 这个极小异常点,怎么都不行。

看下面的脚本:

#!/usr/local/bin/stap

global dsrtt

probe kernel.function("tcp_ack_update_rtt")

srtt = (@cast($sk,"struct tcp_sock")->srtt_us);
dport =(@cast($sk, "struct sock")->__sk_common->skc_dport);
if (dport == 0x8913) // 过滤 iperf 端口
dsrtt <<< srtt



probe timer.s(2)
printf("-----------\n")
print(@hist_log(dsrtt))
delete dsrtt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
分别设置 net.ipv4.tcp_timestamps 为 1 或 0,观察一下分布,可呈现:
​
如果将 sack 也关闭,GBN 将持续使用 Timestamps 计算 RTT,结果就是持续值为 1000 us 的采样值被灌入移指平均计算。关掉 sack ,持续采样,不再 delete,分布如下:

所以,在 IDC 环境,请关闭 Timestamps。

在公网环境,这个问题不大,广域网 RTT 大于 1 ms,时间戳损失的精度有限,2.9 - 1.1 约等于 2,按 ms 精度计算,结果是 1,大约损失一半,这是损失的最大误差,在普遍 RTT 均大于 10 ms 的环境,偶尔的计算精度损失不会带来问题。

然而,对于 BBR ,即便精度损失不会带来计算问题,也还是会影响 BBR 的状态机。问题出在下面代码:

static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs)

struct tcp_sock *tp = tcp_sk(sk);
struct bbr *bbr = inet_csk_ca(sk);
bool filter_expired;

/* Track min RTT seen in the min_rtt_win_sec filter window: */
filter_expired = after(tcp_jiffies32,
bbr->min_rtt_stamp + bbr_min_rtt_win_sec * HZ);
if (rs->rtt_us >= 0 &&
(rs->rtt_us <= bbr->min_rtt_us ||
(filter_expired && !rs->is_ack_delayed)))
bbr->min_rtt_us = rs->rtt_us;
bbr->min_rtt_stamp = tcp_jiffies32;

...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在 Recovery 状态用时间戳计算 RTT,精度损失将使 rs->rtt_us <= bbr->min_rtt_us 恒成立,进而持续 reset min_rtt_stamp,也就进不去 ProbeRTT 状态了。该问题已解决,去掉等号即可:
[PATCH net] tcp: only postpone PROBE_RTT if RTT is < current min_rtt estimate
无论如何,Timestamps 总是在帮倒忙。
参考技术B linux没有tcptimestamp是因为linux和tcptimestamp两者之间是互相不兼容的,导致linux无法对tcptimestamp进行解析和储存数据,所以也就出现了没有tcptimestamp存在的情况了。 参考技术C 是的,Linux没有tcptimestamp特性。这是一项在TCP/IP协议中用来记录TCP/IP数据包发送时间的功能,但Linux内核并未实现这个功能。 参考技术D Linux不支持TCP Timestamp选项,但是可以使用其他技术来精确时间同步。具体而言,可以使用Network Time Protocol (NTP)协议来让linux服务器与其他NTP服务器保持时间同步。另外,也可以通过定期手动更新时间来保证linux服务器的时间准确性。

linux没有wifi


layout: default
title: linux没有wifi
category: [技术, 安全]
comments: true
---

linux的wifi出现问题的介绍

几次重装linux系统,经常出现没有wifi的状况

错误详情

之前安装过CentOS,Kylin,OpenSU,等等经常出现没有wifi的状况,虽说猜测是遇到驱动问题,但是一直没有花时间去尝试解决.

今天再次遇到这个问题,而且已经重装两次了,还没有解决,只能直接找解决方案了.

目前的系统是ubuntu gnome 13.10,电脑是hp ProBook 6540b

解决方案

技术分享图片

  1. dmesg | grep b43 (找到问题)
    dmesg用于检测和控制内核缓冲,帮助用户了解系统的启动信息。
    如上图所示:系统提示到Linux Wireless下载firmware,我们直接点击Linux Wireless,打开之后发现The old website for now has a copy of the old content:Old Linux Wireless,因此我们需要参考的是Old Linux Wireless上的内容。如果显示的不是此内容,则参考上面的文章。

  2. sudo apt-get install firmware-b43-installer(不建议,最好通过网站下载)
    下载安装b43-fwcutter是因为b43-fwcutter tool will extract firmware from the Windows driver
    我们可以选择直接通过http://bues.ch/b43/fwcutter/b43-fwcutter-018.tar.bz2下载,得到的版本是version 018 of b43-fwcutter,文件默认下载在下载目录中。

  3. 根据内核版本下载对应的驱动程序,参考Old Linux Wireless,如图二所示,根据我自己版本驱动我直接在http://www.lwfinger.com/b43-firmware/broadcom-wl-5.100.138.tar.bz2下载。下载的文件和b43-fwcutter在同一个目录下。
    接下来我们进入下载目录,步骤4567是对b43-fwcutter进行解压,编译和安装,步骤9,10是对驱动文件解压和安装。

  4. tar xjf b43-fwcutter-018.tar.bz2

  5. cd b43-fwcutter-018

  6. make

  7. sudo make install

  8. cd ..

  9. tar xjf broadcom-wl-5.100.138.tar.bz2

  10. sudo b43-fwcutter -w /lib/firmware broadcom-wl-5.100.138/linux/wl_apsta.o

  11. modprobe b43(加载b43驱动)

  12. sudo shutdown -r now

大功告成

附录

  1. lspci -vv | grep Network (确定无线网卡的类型)
    lspci 显示当前主机的所有硬件配备
    -v 显示PCI接口装置的详细信息
    -vv 显示PCI接口设备的更详细的信息
    | 管道
    grep Network 查找Network关键字所在的行
    或者使用这里的命令lspci -nn -d 14e4:(注意:)
  2. uname -a(确定内核版本)

技术分享图片

最后wifi显示出来,终于可以连上wifi了.

技术分享图片

说明

写这篇文章是作为使用linux的笔记.图片没有另外拍照,就没有重新上图了,不过确实正好解决问题.

参考文章
linux无法连接wifi,不显示wifi - CSDN博客
https://blog.csdn.net/yiranant/article/details/46445055

以上是关于linux没有tcptimestamp的主要内容,如果未能解决你的问题,请参考以下文章

linux没有gs命令

linux没有wifi

linux为啥没有病毒

启动菜单没有linux启动选项

Linux基础命令

Linux find 命令从跟目录下查找为啥会没有显示没有权限的错误