diff --git a/reactos/lib/drivers/lwip/src/include/arch/cc.h b/reactos/lib/drivers/lwip/src/include/arch/cc.h index 91d6b5a27d9..8a6d20066d1 100755 --- a/reactos/lib/drivers/lwip/src/include/arch/cc.h +++ b/reactos/lib/drivers/lwip/src/include/arch/cc.h @@ -15,7 +15,9 @@ free(void *mem); void * realloc(void *mem, size_t size); -#define mem_trim(_m_, _s_) realloc(_m_, _s_) +/* mem_trim() must trim the buffer without relocating it. + * Since we can't do that, we just return the buffer passed in unchanged */ +#define mem_trim(_m_, _s_) (_m_) /* Unsigned int types */ typedef unsigned char u8_t; diff --git a/reactos/lib/drivers/lwip/src/rosmem.c b/reactos/lib/drivers/lwip/src/rosmem.c index 4fdb84d3c8c..e1dccb63f48 100755 --- a/reactos/lib/drivers/lwip/src/rosmem.c +++ b/reactos/lib/drivers/lwip/src/rosmem.c @@ -31,9 +31,36 @@ free(void *mem) ExFreePoolWithTag(mem, LWIP_TAG); } +/* This is only used to trim in lwIP */ void * realloc(void *mem, size_t size) { + void* new_mem; + + /* realloc() with a NULL mem pointer acts like a call to malloc() */ + if (mem == NULL) { + return malloc(size); + } + + /* realloc() with a size 0 acts like a call to free() */ + if (size == 0) { + free(mem); + return NULL; + } + + /* Allocate the new buffer first */ + new_mem = malloc(size); + if (new_mem == NULL) { + /* The old buffer is still intact */ + return NULL; + } + + /* Copy the data over */ + RtlCopyMemory(new_mem, mem, size); + + /* Deallocate the old buffer */ free(mem); - return malloc(size); + + /* Return the newly allocated block */ + return new_mem; } \ No newline at end of file diff --git a/reactos/lib/drivers/lwip/src/rostcp.c b/reactos/lib/drivers/lwip/src/rostcp.c index 93e7eb2a787..b094775ecd8 100755 --- a/reactos/lib/drivers/lwip/src/rostcp.c +++ b/reactos/lib/drivers/lwip/src/rostcp.c @@ -631,18 +631,8 @@ LibTCPShutdownCallback(void *arg) goto done; } - if (pcb->state == CLOSE_WAIT) - { - /* This case actually results in a socket closure later (lwIP bug?) */ - msg->Input.Shutdown.Connection->SocketContext = NULL; - } - msg->Output.Shutdown.Error = tcp_shutdown(pcb, msg->Input.Shutdown.shut_rx, msg->Input.Shutdown.shut_tx); - if (msg->Output.Shutdown.Error) - { - msg->Input.Shutdown.Connection->SocketContext = pcb; - } - else + if (!msg->Output.Shutdown.Error) { if (msg->Input.Shutdown.shut_rx) { @@ -652,6 +642,10 @@ LibTCPShutdownCallback(void *arg) if (msg->Input.Shutdown.shut_tx) msg->Input.Shutdown.Connection->SendShutdown = TRUE; + + /* Shutting down both sides is like a close to LwIP, so clear the context */ + if (msg->Input.Shutdown.shut_rx && msg->Input.Shutdown.shut_tx) + msg->Input.Shutdown.Connection->SocketContext = NULL; } done: @@ -712,6 +706,7 @@ LibTCPCloseCallback(void *arg) case CLOSED: case LISTEN: case SYN_SENT: + case CLOSE_WAIT: msg->Output.Close.Error = tcp_close(pcb); if (!msg->Output.Close.Error && msg->Input.Close.Callback) @@ -719,20 +714,8 @@ LibTCPCloseCallback(void *arg) break; default: - if (msg->Input.Close.Connection->SendShutdown && - msg->Input.Close.Connection->ReceiveShutdown) - { - /* Abort the connection */ - tcp_abort(pcb); - - /* Aborts always succeed */ - msg->Output.Close.Error = ERR_OK; - } - else - { - /* Start the graceful close process (or send RST for pending data) */ - msg->Output.Close.Error = tcp_close(pcb); - } + /* Start the graceful close process (or send RST for pending data) */ + msg->Output.Close.Error = tcp_close(pcb); break; }