Bug 247 - Checksum calculation crashes tcp-large-transfer
Checksum calculation crashes tcp-large-transfer
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: internet
pre-release
All All
: P3 normal
Assigned To: ns-bugs
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2008-07-01 22:06 UTC by Rajib Bhattacharjea
Modified: 2008-07-10 18:55 UTC (History)
1 user (show)

See Also:


Attachments
Fix TCP checksum crash (473 bytes, patch)
2008-07-02 00:49 UTC, Sebastien Vincent
Details | Diff
Use Buffer::Iterator::Getsize (11.25 KB, patch)
2008-07-10 18:45 UTC, Mathieu Lacage
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Rajib Bhattacharjea 2008-07-01 22:06:30 UTC
How to reproduce out of ns-3-dev:
./waf --run="tcp-large-transfer --ns3::TcpL4Protocol::CalcChecksum=true"

debug build

Platforms:
Ubuntu Linux 7.10, x86, 2.6.22-15-generic kernel, g++ (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)

MacOSX 10.4.11 on x86, gcc i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5363)
Comment 1 Sebastien Vincent 2008-07-02 00:49:43 UTC
Created attachment 192 [details]
Fix TCP checksum crash

Here a patch to fix checksum crash with TCP.

In TcpHeader::Deserialize, we calulate the checksum and we need the payload size and the previous checksum from the pseudo-header (calculating by TcpHeader::InitializeChecksum).
Comment 2 Mathieu Lacage 2008-07-02 11:48:06 UTC
(In reply to comment #1)
> Created an attachment (id=192) [details]
> Fix TCP checksum crash
> 
> Here a patch to fix checksum crash with TCP.
> 
> In TcpHeader::Deserialize, we calulate the checksum and we need the payload
> size and the previous checksum from the pseudo-header (calculating by
> TcpHeader::InitializeChecksum).

How do know the size of the tcp header before reading it (there could well be tcp options in the header)? I realize that we do the same thing for the Udp Header in UdpL4Protocol::Receive but that is not right.

I have to confess that it is not clear to me what we should do here. An option might be to add a Buffer::Iterator::GetSize method (pick a better name, please) and use that instead of setting and using the m_payloadSize member.






Comment 3 Mathieu Lacage 2008-07-02 11:58:07 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > Created an attachment (id=192) [details] [details]
> > Fix TCP checksum crash
> > 
> > Here a patch to fix checksum crash with TCP.
> > 
> > In TcpHeader::Deserialize, we calulate the checksum and we need the payload
> > size and the previous checksum from the pseudo-header (calculating by
> > TcpHeader::InitializeChecksum).
> 
> How do know the size of the tcp header before reading it (there could well be
> tcp options in the header)? I realize that we do the same thing for the Udp
> Header in UdpL4Protocol::Receive but that is not right.
> 
> I have to confess that it is not clear to me what we should do here. An option
> might be to add a Buffer::Iterator::GetSize method (pick a better name, please)
> and use that instead of setting and using the m_payloadSize member.

Another option, again, for TCP only, would be to change the signature of the InitializeChecksum method to take an extra argument, the size of the complete packet such that, in Deserialize, you could do the right thing without using m_payloadSize.

In either case, we should work harder to document the relatively subtle behavior of the TcpHeader, UdpHeader, and , Ipv4Header classes.
Comment 4 Mathieu Lacage 2008-07-09 18:26:31 UTC
vincent, can you give feedback on my last comments ?
Comment 5 Sebastien Vincent 2008-07-10 01:32:13 UTC
The TCP solution (change InitializeChecksum) is interresting and easy to do.

The UDP header is always 8 bytes (i.e. there are no UDP options in header), am I right ? So no need to change it.

But the best would be to have a unique way for UDP/TCP. With that if others want to do a new L4 Protocol (such a SCTP), they have a model to follow.

Could you explain a little bit your way to proceed with Buffer::iterator::GetSize ? I mean in the different classes (*L4Protocol, *Header).
Comment 6 Mathieu Lacage 2008-07-10 18:03:36 UTC
(In reply to comment #5)
> The TCP solution (change InitializeChecksum) is interresting and easy to do.
> 
> The UDP header is always 8 bytes (i.e. there are no UDP options in header), am
> I right ? So no need to change it.

I think so, yes.

> 
> But the best would be to have a unique way for UDP/TCP. With that if others
> want to do a new L4 Protocol (such a SCTP), they have a model to follow.

yes.

> 
> Could you explain a little bit your way to proceed with
> Buffer::iterator::GetSize ? I mean in the different classes (*L4Protocol,

Well, if we provided a Buffer::Iterator::GetSize method which were to return the size of the underlying byte buffer, you could use that in ::Deserialize and ::Serialize, and potentially, get rid of the SetPayloadSize method. 

I can't make myself like this very much but I suspect that it would pretty easy to get up and running.

> *Header).
> 

Comment 7 Mathieu Lacage 2008-07-10 18:45:14 UTC
Created attachment 197 [details]
Use Buffer::Iterator::Getsize

Here is a patch which implements this for TCP and UDP. Tested with udp-echo and tcp-large-transfer with both --ns3::UdpL4Protocl::CalcChecksum=true --ns3::TcpL4Protocol::CalcChecksum=true --ns3::Ipv4L3Protocol::CalcChecksum=true
Comment 8 Mathieu Lacage 2008-07-10 18:55:22 UTC
changeset: b5d4a04c7b68