LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Networking (https://www.linuxquestions.org/questions/linux-networking-3/)
-   -   Unexpected TCP Retransmission. (https://www.linuxquestions.org/questions/linux-networking-3/unexpected-tcp-retransmission-946124/)

$ubbu 05-21-2012 06:40 AM

Unexpected TCP Retransmission.
 
Hi

I am writing a KERNEL module which modifies the received SKB(from protocol stack) according to my need and transmits the new SKB. While doing this I face a problem as described below.

A web client (where my kernel module is loaded) requests for a HTML page (30KB) from web server. I have disabled compression in the web server. So the entire html page is supposed to be sent by the server in multiple TCP segments.

But when I capture the packets through Wireshark, I see the web server after sending 3 segments, instead of sending 4th segment it starts retransmitting the first segment again despite all 3 segments are acknowledged (Delayed ACK) by the client before the retransmission occurs. So my question is why does the server retransmits the first segment even after receiving the ACK for it?

fyi,

Just to make sure the way I form the SKB is not the culprit, I called the function which forms a new SKB but still while transmission I freed the new SKB and sent ONLY the SKB which I received from protocol stack . But still I see the same problem as described above.

Please let me know if I am not clear.

Thanks,
$ubbu.

$ubbu 05-22-2012 02:19 AM

Any reply please?

nini09 05-23-2012 02:24 PM

Is ACK sequence number correct you response to server?

$ubbu 05-23-2012 10:56 PM

Yes I do adjust the ACK and seq no accordingly. So as expected the ACK sent by the web client (after adjusting the seq no) is getting dropped by web server. Hence retransmission happens from the server side.

The reason for drop is the checksum calculation for outgoing ACK is wrong. But I use the same checksum calculation for the HTTP GET Request which gets passed. So I am unable to figure out why the checksum for outgoing ACK is wrong while the checksum for HTTP GET request is correct?

Any thoughts? Thanks for your reply..

nini09 05-24-2012 02:22 PM

How do you know the checksum is wrong? There are two seq number in ACK packet. Are you sure both is correct?

$ubbu 05-25-2012 10:41 AM

2 seq no, whats that? Wireshark shows incorrect checksum for outgoing ACK's by webclient.

nini09 05-29-2012 02:17 PM

There are two sequence number, Sequence Number and Acknowledgment Number. If Wireshark shows incorrect checksum for outgoing ACK, that means your program is worng even if HTTP GET is correct.

$ubbu 05-31-2012 03:43 AM

As I said earlier both the ack no and seq no are adjusted correctly. Neways I got it to resolve the checksum error but couldnt understand the reason behind it.

Case 1: When I dont see the checksum error I do the following.

1. I dont compute TCP checksum in xmit_hook after adjusting the sequence number.
2. I do compute TCP checksum in recv_hook after adjusting the acknowledgement number.
3. The TCP checksum offload is disabled by the following command (#ethtool --offload eth0 rx off tx off)

Case 2: When I see the checksum error I do the following.

1. I do compute TCP checksum in xmit_hook after adjusting the sequence number.
2. I do compute TCP checksum in recv_hook after adjusting the acknowledgement number.
3. The TCP checksum offload is disabled by the following command (#ethtool --offload eth0 rx off tx off)


As per my understanding Case 1 should fail while Case 2 should pass but its behaving exactly opposite to what I think :) What am I missing here?

In Case 1 When I dont explicitly calculate the checksum and when I turn off the Checksum offload calculation I expect the HTTP communication failure but instead I see HTTP communication happening correctly and checksum is also calculated correctly (by the hardware?). But why does this happen when I have turned off? And why does case 2 fails?

Any thoughts please!!!

nini09 05-31-2012 02:40 PM

It look like your code doesn't pass TCP/IP stack completely, only working on SKB. I don't know where is your hook position.

$ubbu 05-31-2012 11:55 PM

Yup it doesnt pass TCP/IP stack completely. In xmit_hook I steal the packets (only if needed) while in recv_hook I just recompute checksum and accept all the packets.

My hook positions for

xmit_hook is NF_INET_POST_ROUTING chain and recv_hook is NF_INET_LOCAL_IN.

Let me know if you need any other info. Thanks!!

nini09 06-01-2012 02:09 PM

If so, your case 1 make sense. For sending side, the TCP/IP stack will recalculate checksum before sending to meduim. For receiving side, TCP socket will check checksum.


All times are GMT -5. The time now is 10:23 PM.