Author: cgutman Date: Sun Jun 12 18:25:16 2011 New Revision: 52200
URL: http://svn.reactos.org/svn/reactos?rev=52200&view=rev Log: [LWIP] - Implement LibTCPShutdown [IP] - Replace an incredibly broken implementation of TCPDisconnect which caused memory corruption with a working one using LibTCPShutdown
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/include/rosip.h branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Sun Jun 12 18:25:16 2011 @@ -316,19 +316,15 @@
if (Flags & TDI_DISCONNECT_RELEASE) { - /* FIXME */ - LibTCPClose(Connection->SocketContext); + Status = LibTCPShutdown(Connection->SocketContext, 0, 1); }
if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) { - /* FIXME */ - LibTCPClose(Connection->SocketContext); - } - - Status = STATUS_SUCCESS; - - DbgPrint("LibTCPClose: %x\n", Status); + Status = LibTCPShutdown(Connection->SocketContext, 1, 1); + } + + DbgPrint("LibTCPShutdown: %x\n", Status);
UnlockObject(Connection, OldIrql);
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/include/rosip.h URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/include/rosip.h [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/include/rosip.h [iso-8859-1] Sun Jun 12 18:25:16 2011 @@ -18,6 +18,7 @@ struct tcp_pcb *LibTCPListen(struct tcp_pcb *pcb, u8_t backlog); err_t LibTCPSend(struct tcp_pcb *pcb, void *dataptr, u16_t len); err_t LibTCPConnect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port); +err_t LibTCPShutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); err_t LibTCPClose(struct tcp_pcb *pcb); err_t LibTCPGetPeerName(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t *port); err_t LibTCPGetHostName(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t *port);
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c [iso-8859-1] Sun Jun 12 18:25:16 2011 @@ -517,6 +517,73 @@ return ERR_MEM; }
+struct shutdown_callback_msg +{ + /* Synchronization */ + KEVENT Event; + + /* Input */ + struct tcp_pcb *Pcb; + int shut_rx; + int shut_tx; + + /* Output */ + err_t Error; +}; + +static +void +LibTCPShutdownCallback(void *arg) +{ + struct shutdown_callback_msg *msg = arg; + + msg->Error = tcp_shutdown(msg->Pcb, msg->shut_rx, msg->shut_tx); + + KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE); +} + +err_t +LibTCPShutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) +{ + struct shutdown_callback_msg *msg; + err_t ret; + + DbgPrint("[lwIP, LibTCPShutdown] Called\n"); + + if (!pcb) + { + DbgPrint("[lwIP, LibTCPShutdown] Done... NO pcb\n"); + return ERR_CLSD; + } + + msg = ExAllocatePool(NonPagedPool, sizeof(struct shutdown_callback_msg)); + if (msg) + { + KeInitializeEvent(&msg->Event, NotificationEvent, FALSE); + + msg->Pcb = pcb; + msg->shut_rx = shut_rx; + msg->shut_tx = shut_tx; + + tcpip_callback_with_block(LibTCPShutdownCallback, msg, 1); + + if (WaitForEventSafely(&msg->Event)) + ret = msg->Error; + else + ret = ERR_CLSD; + + ExFreePool(msg); + + DbgPrint("[lwIP, LibTCPShutdown] pcb = 0x%x\n", pcb); + + DbgPrint("[lwIP, LibTCPShutdown] Done\n"); + + return ret; + } + + return ERR_MEM; +} + struct close_callback_msg { /* Synchronization */