- Forgot to commit these for MSVC build...
[reactos.git] / reactos / drivers / net / tcpip / tcpip / fileobjs.c
index b2547ab..546df6f 100644 (file)
@@ -43,6 +43,20 @@ PADDRESS_FILE AddrSearchFirst(
     return AddrSearchNext(SearchContext);
 }
 
+BOOLEAN AddrIsBroadcast(
+    PIP_ADDRESS PossibleMatch,
+    PIP_ADDRESS TargetAddress ) {
+    IF_LIST_ITER(IF);
+
+    ForEachInterface(IF) {
+        if( AddrIsEqual( &IF->Unicast, PossibleMatch ) &&
+            AddrIsEqual( &IF->Broadcast, TargetAddress ) )
+            return TRUE;
+    } EndFor(IF);
+
+    return FALSE;
+}
+
 /*
  * FUNCTION: Searches through address file entries to find next match
  * ARGUMENTS:
@@ -80,10 +94,11 @@ PADDRESS_FILE AddrSearchNext(
             A2S(SearchContext->Address)));
 
         /* See if this address matches the search criteria */
-        if (((Current->Port    == SearchContext->Port) &&
+        if ((Current->Port    == SearchContext->Port) &&
             (Current->Protocol == SearchContext->Protocol) &&
-            (AddrIsEqual(IPAddress, SearchContext->Address))) ||
-            (AddrIsUnspecified(IPAddress))) {
+            (AddrIsEqual(IPAddress, SearchContext->Address) ||
+             AddrIsBroadcast(IPAddress, SearchContext->Address) ||
+             AddrIsUnspecified(IPAddress))) {
             /* We've found a match */
             Found = TRUE;
             break;
@@ -170,7 +185,7 @@ VOID DeleteAddress(PADDRESS_FILE AddrFile)
   CurrentEntry = AddrFile->TransmitQueue.Flink;
   while (CurrentEntry != &AddrFile->TransmitQueue) {
     NextEntry = CurrentEntry->Flink;
-    SendRequest = CONTAINING_RECORD(CurrentEntry, 
+    SendRequest = CONTAINING_RECORD(CurrentEntry,
                                    DATAGRAM_SEND_REQUEST, ListEntry);
     /* Abort the request and free its resources */
     TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
@@ -249,6 +264,7 @@ NTSTATUS FileOpenAddress(
   /* Locate address entry. If specified address is 0, a random address is chosen */
 
   /* FIXME: IPv4 only */
+  AddrFile->Family = Address->Address[0].AddressType;
   IPv4Address = Address->Address[0].Address[0].in_addr;
   if (IPv4Address == 0)
       Matched = IPGetDefaultAddress(&AddrFile->Address);
@@ -267,16 +283,18 @@ NTSTATUS FileOpenAddress(
   /* Protocol specific handling */
   switch (Protocol) {
   case IPPROTO_TCP:
-    /* FIXME: If specified port is 0, a port is chosen dynamically */
-    AddrFile->Port = TCPAllocatePort(Address->Address[0].Address[0].sin_port);
-    AddrFile->Send = NULL; /* TCPSendData */
-    break;
+      AddrFile->Port =
+          TCPAllocatePort(Address->Address[0].Address[0].sin_port);
+      AddrFile->Send = NULL; /* TCPSendData */
+      break;
 
   case IPPROTO_UDP:
       TI_DbgPrint(MID_TRACE,("Allocating udp port\n"));
-      AddrFile->Port = 
+      AddrFile->Port =
          UDPAllocatePort(Address->Address[0].Address[0].sin_port);
-      TI_DbgPrint(MID_TRACE,("Setting port %d\n", AddrFile->Port));
+      TI_DbgPrint(MID_TRACE,("Setting port %d (wanted %d)\n",
+                             AddrFile->Port,
+                             Address->Address[0].Address[0].sin_port));
       AddrFile->Send = UDPSendDatagram;
       break;
 
@@ -295,7 +313,7 @@ NTSTATUS FileOpenAddress(
 
   /* Set protocol */
   AddrFile->Protocol = Protocol;
-  
+
   /* Initialize receive and transmit queues */
   InitializeListHead(&AddrFile->ReceiveQueue);
   InitializeListHead(&AddrFile->TransmitQueue);
@@ -344,22 +362,24 @@ NTSTATUS FileCloseAddress(
   /* Set address file object exclusive to us */
   AF_SET_BUSY(AddrFile);
   AF_CLR_VALID(AddrFile);
-  
+
   TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
 
   /* Protocol specific handling */
   switch (AddrFile->Protocol) {
   case IPPROTO_TCP:
     TCPFreePort( AddrFile->Port );
+    if( AddrFile->Listener )
+       TCPClose( AddrFile->Listener );
     break;
 
   case IPPROTO_UDP:
     UDPFreePort( AddrFile->Port );
     break;
   }
-  
+
   DeleteAddress(AddrFile);
-  
+
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 
   return Status;
@@ -382,9 +402,9 @@ NTSTATUS FileOpenConnection(
   PCONNECTION_ENDPOINT Connection;
 
   TI_DbgPrint(MID_TRACE, ("Called.\n"));
-  
+
   Connection = TCPAllocateConnectionEndpoint( ClientContext );
-  
+
   if( !Connection ) return STATUS_NO_MEMORY;
 
   Status = TCPSocket( Connection, AF_INET, SOCK_STREAM, IPPROTO_TCP );
@@ -406,7 +426,7 @@ NTSTATUS FileOpenConnection(
 
 /*
  * FUNCTION: Find a connection by examining the context field.  This
- * is needed in some situations where a FIN reply is needed after a 
+ * is needed in some situations where a FIN reply is needed after a
  * socket is formally broken.
  * ARGUMENTS:
  *     Request = Pointer to TDI request structure for this request
@@ -420,10 +440,10 @@ PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) {
 
     TcpipAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql );
 
-    for( Entry = ConnectionEndpointListHead.Flink; 
+    for( Entry = ConnectionEndpointListHead.Flink;
         Entry != &ConnectionEndpointListHead;
-        Entry = Entry->Flink ) { 
-       Connection = 
+        Entry = Entry->Flink ) {
+       Connection =
            CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry );
        if( Connection->SocketContext == Context ) break;
        else Connection = NULL;
@@ -451,8 +471,10 @@ NTSTATUS FileCloseConnection(
 
   Connection = Request->Handle.ConnectionContext;
 
+  TcpipRecursiveMutexEnter( &TCPLock, TRUE );
   TCPClose(Connection);
   DeleteConnectionEndpoint(Connection);
+  TcpipRecursiveMutexLeave( &TCPLock );
 
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));