TCPの再送

[c2kの通信](https://qiita.com/yamori813/items/cdc366e87565065dbcc5)がときどき引っかかるので、調べてみました。

ncで他のホストとつないで、送受信を試したところ、受信は問題ないのですが、送信が遅れることがあります。

netstat -p tcpで見ると再送が確認できます。

```
c2k$ netstat -p tcp | grep ret
                5 data packets (1308 bytes) retransmitted
        5 retransmit timeouts
        0 SYN,ACKs retransmitted
```

余談ですがFreeBSDではnetstat -p tcp -sとする必要があります。

tcpdumpで調べてみます。

```
15:48:22.606967 IP 10.0.1.42.8000 > 10.0.1.38.41165: Flags [P.], seq 12:14, ack 5, win 4197, options [nop,nop,TS val 26 ecr 8371388], length 2
15:48:22.649268 IP 10.0.1.38.41165 > 10.0.1.42.8000: Flags [.], ack 14, win 1027, options [nop,nop,TS val 8372173 ecr 26], length 0
15:48:23.021169 IP 10.0.1.42.8000 > 10.0.1.38.41165: Flags [P.], seq 14:16, ack 5, win 4197, options [nop,nop,TS val 26 ecr 553648154], length 2
15:48:24.018251 IP 10.0.1.42.8000 > 10.0.1.38.41165: Flags [P.], seq 14:18, ack 5, win 4197, options [nop,nop,TS val 28 ecr 8372173], length 4
15:48:24.060274 IP 10.0.1.38.41165 > 10.0.1.42.8000: Flags [.], ack 18, win 1027, options [nop,nop,TS val 8373584 ecr 28], length 0
```

1,2行目は問題なく送信にackが返っていますが、3行目の送信にackが返ってこないので、4行目の再送を行い5行目のackが返っています。

3行目はecrが他の送信より大きくなってるのが原因の可能性があります。なんでかな？

~~pingでは送受信ともまったく問題がないのはTCPレイヤーでの問題のためのようです。~~

~~ifドライバの問題ではなさそうです。~~

とは考えにくいです。やっぱifドライバだと思います。

~~上のtcpdumpは対向で実行していて、2行目のackは送ったもののどこかで遅延して処理されていない状態で3行目の送信が行われたのではないでしょうか。その後に2行目のackが処理されて、再送処理になったのではないででしょうか。~~

PFEのドライバはかろうじてパケットを送受信が出来ているだけで、実用レベルには程遠いです。

NXPはDPDKにコードを提供しているようですが、PFEのドキュメントも公開してほしいです。あまりに難解でコードだけでは仕様の把握が困難です。と思ったのですが、いまさら仕様を把握するほど暇な人はいないと思われ、シンプルで再現性の高いコードの提供が唯一の救済方法かもしれません。

DPDKのコードにはファームウエアの処理がまったくなくて、ブートローダーがダウンロードしたファームウエアをそのまま使うことを前提にしているようです。なのでブートローダーがファームウエアをダウンロードしていない場合は動かないと思います。NXPも結構いい加減です。

NXPのドライバー屋さんにしてみると、なんで、流れ流れてやってきた、こんなわけ分からんデバイスのドライバーかかにゃならんのって気になったのかもしれません。

このデバイスのファームウエアは普通はASICの中に隠蔽されるものが、そとに出ちゃってるのではないでしょうか。うまくいけば画期的だったかもしれませんが、会社がなくなりなんだか分からなくなったとしかいえません。

再調査

```
11:35:31.298913 IP 10.0.1.42.65535 > 10.0.1.41.sunproxyadmin: Flags [P.], seq 14:16, ack 1, win 4197, options [nop,nop,TS val 930 ecr 0], length 2
        0x0000:  4500 0036 0000 0000 4006 6470 0a00 012a  E..6....@.dp...*
        0x0010:  0a00 0129 ffff 1f91 79c4 62b9 1614 28cf  ...)....y.b...(.
        0x0020:  8018 1065 aa80 0000 0101 080a 0000 03a2  ...e............
        0x0030:  0000 0000 0000                           ......
11:35:39.298905 IP 10.0.1.42.65535 > 10.0.1.41.sunproxyadmin: Flags [P.], seq 14:16, ack 1, win 4197, options [nop,nop,TS val 946 ecr 733], length 2
        0x0000:  4500 0036 0000 0000 4006 6470 0a00 012a  E..6....@.dp...*
        0x0010:  0a00 0129 ffff 1f91 79c4 62b9 1614 28cf  ...)....y.b...(.
        0x0020:  8018 1065 aa70 0000 0101 080a 0000 03b2  ...e.p..........
        0x0030:  0000 02dd 640a                           ....d.
11:35:39.544045 IP 10.0.1.41.sunproxyadmin > 10.0.1.42.65535: Flags [.], ack 16, win 4197, options [nop,nop,TS val 763 ecr 946], length 0
        0x0000:  4500 0034 0000 4000 4006 2472 0a00 0129  E..4..@.@.$r...)
        0x0010:  0a00 012a 1f91 ffff 1614 28cf 79c4 62bb  ...*......(.y.b.
        0x0020:  8010 1065 0e65 0000 0101 080a 0000 02fb  ...e.e..........
        0x0030:  0000 03b2                                ....
```

一番上が壊れたパケットで、その下が正常なパケットで、その下がackです。

0x0030からがTCPヘッダーのoptionのecrとdataですが、壊れています。

~~c2kのPFEのDMA(HIF)は一つのパケットを複数のディスクリプタで処理する事も出来るけど、なんかバグがあるような気がします。~~

mbufをまとめて一つのローカルバッファにコピーすればまともになるような気がしますが、面倒だしBSDの流儀から反するのでやりません。

自分がmbuf壊していたみたいです。^ ^;