2
votes

I am using a TP-Link router TL-WR710N with OpenWRT as an IPv4-to-IPv6 translater/gateway with the following socat-command:

socat TCP4-LISTEN:80,fork,su=nobody TCP6:[xx:xx:xx::xx]:80

On the IPv4-side is a PC which sends a large amount of data (for example 300kB) via TCP. On the Ipv6-side is an embedded-device with a very small stack, which can only process 1 Ethernet-frame at once.

The router buffers up to 300k of the data and send it frame by frame to the embedded-device. Sometimes the router sends the TCP-packets in the wrong order, such as:

Sender(TP-Link router)     Receiver(embedded sys)
packet 1                   Ack 1
packet 3                   Ack 1
packet 2                   Ack 2
packet 4                   Ack 2
transmission pause (400ms)
packet 3                   Ack 3
packet 5                   Ack 3
packet 4                   Ack 4
packet 6                   Ack 4
transmission pause (1,2s)
packet 5                   Ack 5
packet 7                   Ack 5
packet 6                   Ack 6
packet 8                   Ack 6
transmission pause (5s)
...

In a system with a large receive-buffer this isn't a problem, because it can reorder the received packages. But in my small embedded device reordering isn't possible. The (re-)transmissions pauses get longer and longer until the embedded device runs into a timeout.

To solve this issue i have tried to reduce the socat-buffer of the router to the size of one packet on the ipv6-side, so it has to receive a new packet bevor it can send a new packet. But this approach didn't work because the socat-application-buffer is not the only buffer, there is also the router-buffer. Does anybody have an idea to manage this?

actual state:
1. [ PC (300kB) ]  ------ [ Router         ] ------ [       Embedded-device ]
2. [ PC         ]  ------ [ (300kB) Router ] ------ [       Embedded-device ]
3. [ PC         ]  ------ [ Router (299kB) ] ------ [ (1kB) Embedded-device ]
4. [ PC         ]  ------ [ Router (298kB) ] ------ [ (2kB) Embedded-device ]
5. .....

should state:
1. [ PC (300kB) ]  ------ [ Router ] ------ [       Embedded-device ]
2. [ PC (299kB) ]  ------ [ Router ] ------ [ (1kB) Embedded-device ]
3. [ PC (298kB) ]  ------ [ Router ] ------ [ (2kB) Embedded-device ]
4. [ PC (297kB) ]  ------ [ Router ] ------ [ (3kB) Embedded-device ]
5. .....

I'm also interested in a solution where the (re-)transmission pause is less than 1s and will not increase.

1
Did you try the rcvbuf option to set the maximum window size on the TCP4-LISTEN side?vlp

1 Answers

2
votes

The following option reduced the buffer and paketsize and it worked for me

echo "net.ipv4.tcp_wmem= 700 700 700"$'\n'"net.ipv4.tcp_rmem= 700 700 700" >> /etc/sysctl.conf

or per editor:

net.ipv4.tcp_wmem= 700 700 700
net.ipv4.tcp_rmem= 700 700 700