[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-users] Re: bug fix
From: |
Brett Jones |
Subject: |
[lwip-users] Re: bug fix |
Date: |
Fri, 10 Sep 2004 09:14:20 -0700 (PDT) |
The problem is that tcp protocol uses a unsigned 32 bit value for a sequence number and acknowlegement. As each packet is sent the sequence number is increased by the amount of data that is sent and normal comparisons work fine until the sequence number becomes more than a 32 bit value will hold ( 4,294,967,295 ) the sequence number rolls over and even though you have added to the sequence number the sequence number becomes less than it was before. with a signed number the problem is even worse because it rolls over at 2147483647. when you add 2 to this number it becomes -1
then lwip comparisons dont work correctly and does not think that its packets have been acknowleged (out of window) and the que becomes full. to fix this you check for rollover and if a rollover has occured you reverse the comparison logic :)
This fix has made it possible for me to transfer large amounts of data whereas a tcp connection was shutdown every 2 or so gigabytes of data transfered before.
just replace the defines for comparison in lwip with the comparison functions. There is pobably a better way to do this but this works for me :)
BTW thanks for lwip.. saved me a bunch of time,
Regards,
Brett Jones
replace these defines in tcp.h
#define TCP_SEQ_LT(a,b) ((s32_t)((a)-(b)) < 0)
#define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0)
#define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0)
#define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0)
with
u32_t TCP_SEQ_LT( u32_t a, u32_t b );
u32_t TCP_SEQ_LEQ( u32_t a, u32_t b );
u32_t TCP_SEQ_GT( u32_t a, u32_t b );
u32_t TCP_SEQ_GEQ( u32_t a, u32_t b );
then and add to tcp.c
u32_t TCP_SEQ_LT( u32_t a, u32_t b )
{
//determine if a is less than b
if( a == b )
{
return FALSE;
}
if( a > b )
{
if( a-b <= 0x7fffffff )
{
//no rollover
return FALSE;
}
//rolled over
return TRUE;
}
else
{
if( b-a <= 0x7fffffff )
{
//no rollover
return TRUE;
}
//rolled over
return FALSE;
}
}
u32_t TCP_SEQ_LEQ( u32_t a, u32_t b )
{
if( a == b )
{
return TRUE;
}
if( a > b )
{
if( a-b <= 0x7fffffff )
{
//no rollover
return FALSE;
}
//rolled over
return TRUE;
}
else
{
if( b-a <= 0x7fffffff )
{
//no rollover
return
TRUE;
}
//rolled over
return FALSE;
}
}
u32_t TCP_SEQ_GT( u32_t a, u32_t b )
{
if( a == b )
{
return FALSE;
}
if( a > b )
{
if( a-b <= 0x7fffffff )
{
//no rollover
return TRUE;
}
return FALSE;
}
else
{
if( b-a <= 0x7fffffff )
{
//no rollover
return FALSE;
}
//rolled over
return TRUE;
}
}
u32_t TCP_SEQ_GEQ( u32_t a, u32_t b )
{
if( a == b )
{
return TRUE;
}
if( a > b )
{
if( a-b <= 0x7fffffff )
{
//no rollover
return TRUE;
}
//rolled over
return FALSE;
}
else
{
if( b-a <= 0x7fffffff )
{
//no
rollover
return FALSE;
}
//rolled over
return TRUE;
}
}
"K.J. Mansley" <address@hidden> wrote:
Thanks for your contribution!
Could you provide some more explanation about the problem and the fix
please? The use of unsigned arithmetic to do < and > comparisons is
fairly standard. In particular, examples of where the existing code
gets it wrong would be very helpful.
Thanks
Kieran
PS. Things such as this are generally best sent to one of the mailing
lists rather than to me personally, as there are many more people
involved in the project who might be interested or more able to help.
On Thu, 2004-09-09 at 06:51, Brett Jones wrote:
> this code seems to fix a que full error that occurs durring large
> transfers of data.
>
> use it however you wish :)
>
> //#define TCP_SEQ_LT(a,b) ((S32)((a)-(b)) < 0)
> //#define TCP_SEQ_LEQ(a,b) ((S32)((a)-(b)) <= 0)
> //#define
TCP_SEQ_GT(a,b) ((S32)((a)-(b)) > 0)
> //#define TCP_SEQ_GEQ(a,b) ((S32)((a)-(b)) >= 0)
> S32 TCP_SEQ_LT( U32 a, U32 b )
> {
> //determine if a is less than b
> if( a == b )
> {
> return FALSE;
> }
> if( a > b )
> {
> if( a-b <= 0x7fffffff )
> {
> //no rollover
> return FALSE;
> }
> //rolled over
> return TRUE;
> }
> else
> {
> if( b-a <= 0x7fffffff )
> {
> //no rollover
> return TRUE;
> }
> //rolled over
> return FALSE;
> }
> }
> S32 TCP_SEQ_LEQ( U32 a, U32 b )
> {
> if( a == b )
> {
> return TRUE;
> }
> if( a > b )
> {
> if( a-b <= 0x7fffffff )
> {
> //no rollover
> return FALSE;
> }
> //rolled over
> r eturn TRUE;
> }
> else
> {
> if( b-a <= 0x7fffffff )
> {
>
//no rollover
> return TRUE;
> }
> //rolled over
> return FALSE;
> }
> }
> S32 TCP_SEQ_GT( U32 a, U32 b )
> {
> if( a == b )
> {
> return FALSE;
> }
> if( a > b )
> {
> if( a-b <= 0x7fffffff )
> {
> //no rollover
> return TRUE;
> }
> return FALSE;
> }
> else
> {
> if( b-a <= 0x7fffffff )
> {
> //no rollover
> return FALSE;
> }
> //rolled over
> return TRUE;
> }
> }
> S32 TCP_SEQ_GEQ( U32 a, U32 b )
> {
> if( a == b )
> {
> return TRUE;
> }
> if( a > b )
> {
> if( a-b <= 0x7fffffff )
> {
> //no rollover
> return TRUE;
> }
> //rolled over
> return FALSE;
> }
> else
> {
> if( b-a <= 0x7fffffff )
> {
> //no rollover
> return FALSE;
> }
>
//rolled over
> return TRUE;
> }
> }
>
>
>
> ______________________________________________________________________
> Do you Yahoo!?
> Yahoo! Mail - You care about security. So do we.
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!