lwip-users
[Top][All Lists]
Advanced

[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!
reply via email to

[Prev in Thread] Current Thread [Next in Thread]