[LWIP]
authorCameron Gutman <aicommander@gmail.com>
Sun, 12 Jun 2011 18:25:16 +0000 (18:25 +0000)
committerCameron Gutman <aicommander@gmail.com>
Sun, 12 Jun 2011 18:25:16 +0000 (18:25 +0000)
- Implement LibTCPShutdown
[IP]
- Replace an incredibly broken implementation of TCPDisconnect which caused memory corruption with a working one using LibTCPShutdown

svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52200

lib/drivers/ip/transport/tcp/tcp.c
lib/drivers/lwip/src/include/rosip.h
lib/drivers/lwip/src/rostcp.c

index 6f34881..d85857c 100644 (file)
@@ -316,19 +316,15 @@ NTSTATUS TCPDisconnect
 
     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 = LibTCPShutdown(Connection->SocketContext, 1, 1);
     }
     
-    Status = STATUS_SUCCESS;
-    
-    DbgPrint("LibTCPClose: %x\n", Status);
+    DbgPrint("LibTCPShutdown: %x\n", Status);
 
     UnlockObject(Connection, OldIrql);
 
index 6967246..f62ab19 100755 (executable)
@@ -18,6 +18,7 @@ err_t LibTCPBind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port);
 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);
index 25e16d0..38847d2 100755 (executable)
@@ -517,6 +517,73 @@ LibTCPConnect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
     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 */