デフォルトでは、SYNパケットが1秒以内に応答しない場合、Linuxは最初のパケットがどこかにドロップされたと仮定して別のパケットを送信します。 2秒後にもう一度、その後は4秒後に特定の制限まで。
デフォルトを1秒からより高い値(10秒など)に変更するにはどうすればよいですか?
理由
待ち時間が長く、帯域幅が低い(注:帯域幅が低く、これは典型的な帯域幅遅延製品の問題ではありません)。このチャネルは一部の設定でレイテンシが高いため、1秒以内に回答が得られるとは思わない。帯域幅が低いため、SYNを不要に再送信すると、貴重な帯域幅が消費されます。
具体的には笑、SYNパケットを送信するのに5秒以上かかることがあります(チャンネル設定によって、範囲などによって異なります)。つまり、私が別の電子メールを送信すると、さらに5秒間送信機を開いたままにし、相手の応答も聞こえなくなり、より多くの再送信が発生する可能性が高いのです。
私が試したこと
IPルーティング
私はそれをcwndのように変えることができると思います:
ip route change default via x.x.x.x initcwnd 20 initrwnd 20
だからrtt
、、、rttvar
およびrto_min
それ以上を変更しましたが、再送には何の影響もありませんでした。
setockopt/ioctl
まだ適切なソケットが見つかりませんでしたが、見つけたとしてもアプリケーションコードを変更する必要がありますか?
システム制御
繰り返しますが、設定が見つからなかっただけでなく、理想的にはノードが通常のインターネット接続を持つ可能性があるため、システム全体に適用してはいけません。
答え1
私はそれについて考えた。
バラよりこのブログ投稿タイムアウトをオーバーライドできるeBPFプログラムを作成する方法を学びます。
つまり、次のsockops
プログラムをロードする必要があります。
#include<linux/bpf.h>
#define SEC(NAME) __attribute__((section(NAME), used))
// TODO: assumes little-endian (x86, amd64)
#define bpf_ntohl(x) __builtin_bswap32(x)
SEC("sockops")
int bpf_sockmap(struct bpf_sock_ops *skops)
{
const int op = (int) skops->op;
if (op == BPF_SOCK_OPS_TIMEOUT_INIT) {
// TODO: this is in jiffies, and despite `getconf CLK_TCK` return 100, HZ is clearly 25 on my kernel.
// 5000 / 250 = 20 seconds
skops->reply = 5000;
return 1;
}
return 0;
}
char _license[] __attribute((section("license"),used)) = "GPL";
int _version SEC("version") = 1;
以下を使用してコンパイルしてロードできます。
clang $CFLAGS -target bpf -Wall -g -O2 -c set_rto.c -o set_rto.o
sudo bpftool prog load set_rto.o /sys/fs/bpf/bpf_sockop
sudo bpftool cgroup attach /sys/fs/cgroup/unified/ sock_ops pinned /sys/fs/bpf/set_rto