ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tcp.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS TCP/IP protocol driver
00004  * FILE:        transport/tcp/tcp.c
00005  * PURPOSE:     Transmission Control Protocol
00006  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
00007  *              Art Yerkes (arty@users.sf.net)
00008  * REVISIONS:
00009  *   CSH 01/08-2000  Created
00010  *   arty 12/21/2004 Added accept
00011  */
00012 
00013 #include "precomp.h"
00014 
00015 LONG TCP_IPIdentification = 0;
00016 static BOOLEAN TCPInitialized = FALSE;
00017 PORT_SET TCPPorts;
00018 
00019 #include "lwip/pbuf.h"
00020 #include "lwip/ip.h"
00021 #include "lwip/init.h"
00022 #include "lwip/arch.h"
00023 
00024 #include "rosip.h"
00025 
00026 NPAGED_LOOKASIDE_LIST TdiBucketLookasideList;
00027 
00028 VOID NTAPI
00029 DisconnectTimeoutDpc(PKDPC Dpc,
00030                      PVOID DeferredContext,
00031                      PVOID SystemArgument1,
00032                      PVOID SystemArgument2)
00033 {
00034     PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext;
00035     PLIST_ENTRY Entry;
00036     PTDI_BUCKET Bucket;
00037 
00038     LockObjectAtDpcLevel(Connection);
00039 
00040     /* We timed out waiting for pending sends so force it to shutdown */
00041     TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
00042 
00043     while (!IsListEmpty(&Connection->SendRequest))
00044     {
00045         Entry = RemoveHeadList(&Connection->SendRequest);
00046         
00047         Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
00048         
00049         Bucket->Information = 0;
00050         Bucket->Status = STATUS_FILE_CLOSED;
00051         
00052         CompleteBucket(Connection, Bucket, FALSE);
00053     }
00054     
00055     while (!IsListEmpty(&Connection->ShutdownRequest))
00056     {
00057         Entry = RemoveHeadList( &Connection->ShutdownRequest );
00058         
00059         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
00060         
00061         Bucket->Status = STATUS_TIMEOUT;
00062         Bucket->Information = 0;
00063         
00064         CompleteBucket(Connection, Bucket, FALSE);
00065     }
00066     
00067     UnlockObjectFromDpcLevel(Connection);
00068     
00069     DereferenceObject(Connection);
00070 }
00071 
00072 VOID ConnectionFree(PVOID Object)
00073 {
00074     PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Object;
00075     KIRQL OldIrql;
00076 
00077     TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
00078 
00079     TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
00080     RemoveEntryList(&Connection->ListEntry);
00081     TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
00082 
00083     ExFreePoolWithTag( Connection, CONN_ENDPT_TAG );
00084 }
00085 
00086 PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext )
00087 {
00088     PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)
00089         ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT), CONN_ENDPT_TAG);
00090 
00091     if (!Connection)
00092         return Connection;
00093 
00094     TI_DbgPrint(DEBUG_CPOINT, ("Connection point file object allocated at (0x%X).\n", Connection));
00095 
00096     RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
00097 
00098     /* Initialize spin lock that protects the connection endpoint file object */
00099     KeInitializeSpinLock(&Connection->Lock);
00100     InitializeListHead(&Connection->ConnectRequest);
00101     InitializeListHead(&Connection->ListenRequest);
00102     InitializeListHead(&Connection->ReceiveRequest);
00103     InitializeListHead(&Connection->SendRequest);
00104     InitializeListHead(&Connection->ShutdownRequest);
00105     InitializeListHead(&Connection->PacketQueue);
00106 
00107     /* Initialize disconnect timer */
00108     KeInitializeTimer(&Connection->DisconnectTimer);
00109     KeInitializeDpc(&Connection->DisconnectDpc, DisconnectTimeoutDpc, Connection);
00110 
00111     /* Save client context pointer */
00112     Connection->ClientContext = ClientContext;
00113 
00114     Connection->RefCount = 1;
00115     Connection->Free = ConnectionFree;
00116 
00117     /* Add connection endpoint to global list */
00118     ExInterlockedInsertTailList(&ConnectionEndpointListHead,
00119                                 &Connection->ListEntry,
00120                                 &ConnectionEndpointListLock);
00121 
00122     return Connection;
00123 }
00124 
00125 NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
00126                     UINT Family, UINT Type, UINT Proto )
00127 {
00128     NTSTATUS Status;
00129     KIRQL OldIrql;
00130 
00131     LockObject(Connection, &OldIrql);
00132 
00133     TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Called: Connection %x, Family %d, Type %d, "
00134                            "Proto %d, sizeof(CONNECTION_ENDPOINT) = %d\n",
00135                            Connection, Family, Type, Proto, sizeof(CONNECTION_ENDPOINT)));
00136 
00137     Connection->SocketContext = LibTCPSocket(Connection);
00138     if (Connection->SocketContext)
00139         Status = STATUS_SUCCESS;
00140     else
00141         Status = STATUS_INSUFFICIENT_RESOURCES;
00142 
00143     UnlockObject(Connection, OldIrql);
00144 
00145     TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Leaving. Status = 0x%x\n", Status));
00146 
00147     return Status;
00148 }
00149 
00150 NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection )
00151 {
00152     KIRQL OldIrql;
00153 
00154     LockObject(Connection, &OldIrql);
00155 
00156     FlushAllQueues(Connection, STATUS_CANCELLED);
00157 
00158     LibTCPClose(Connection, FALSE, TRUE);
00159 
00160     UnlockObject(Connection, OldIrql);
00161 
00162     DereferenceObject(Connection);
00163 
00164     return STATUS_SUCCESS;
00165 }
00166 
00167 VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
00168 /*
00169  * FUNCTION: Receives and queues TCP data
00170  * ARGUMENTS:
00171  *     IPPacket = Pointer to an IP packet that was received
00172  * NOTES:
00173  *     This is the low level interface for receiving TCP data
00174  */
00175 {
00176     TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to lwIP\n",
00177                            IPPacket->TotalSize,
00178                            IPPacket->HeaderSize));
00179     
00180     LibIPInsertPacket(Interface->TCPContext, IPPacket->Header, IPPacket->TotalSize);
00181 }
00182 
00183 NTSTATUS TCPStartup(VOID)
00184 /*
00185  * FUNCTION: Initializes the TCP subsystem
00186  * RETURNS:
00187  *     Status of operation
00188  */
00189 {
00190     NTSTATUS Status;
00191 
00192     Status = PortsStartup( &TCPPorts, 1, 0xfffe );
00193     if (!NT_SUCCESS(Status))
00194     {
00195         return Status;
00196     }
00197 
00198     ExInitializeNPagedLookasideList(&TdiBucketLookasideList,
00199                                     NULL,
00200                                     NULL,
00201                                     0,
00202                                     sizeof(TDI_BUCKET),
00203                                     TDI_BUCKET_TAG,
00204                                     0);
00205     
00206     /* Initialize our IP library */
00207     LibIPInitialize();
00208     
00209     /* Register this protocol with IP layer */
00210     IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
00211     
00212     TCPInitialized = TRUE;
00213 
00214     return STATUS_SUCCESS;
00215 }
00216 
00217 
00218 NTSTATUS TCPShutdown(VOID)
00219 /*
00220  * FUNCTION: Shuts down the TCP subsystem
00221  * RETURNS:
00222  *     Status of operation
00223  */
00224 {
00225     if (!TCPInitialized)
00226         return STATUS_SUCCESS;
00227 
00228     ExDeleteNPagedLookasideList(&TdiBucketLookasideList);
00229     
00230     LibIPShutdown();
00231 
00232     /* Deregister this protocol with IP layer */
00233     IPRegisterProtocol(IPPROTO_TCP, NULL);
00234 
00235     TCPInitialized = FALSE;
00236 
00237     PortsShutdown( &TCPPorts );
00238 
00239     return STATUS_SUCCESS;
00240 }
00241 
00242 NTSTATUS TCPTranslateError(const err_t err)
00243 {
00244     NTSTATUS Status;
00245 
00246     switch (err)
00247     {
00248         case ERR_OK: Status = STATUS_SUCCESS; return Status; //0
00249         case ERR_MEM: Status = STATUS_INSUFFICIENT_RESOURCES; break; //-1
00250         case ERR_BUF: Status = STATUS_BUFFER_TOO_SMALL; break; //-2
00251         case ERR_TIMEOUT: Status = STATUS_TIMEOUT; break; // -3
00252         case ERR_RTE: Status = STATUS_NETWORK_UNREACHABLE; break; //-4
00253         case ERR_INPROGRESS: Status = STATUS_PENDING; return Status; //-5
00254         case ERR_VAL: Status = STATUS_INVALID_PARAMETER; break; //-6
00255         case ERR_WOULDBLOCK: Status = STATUS_CANT_WAIT; break; //-7
00256         case ERR_USE: Status = STATUS_ADDRESS_ALREADY_EXISTS; break; //-8
00257         case ERR_ISCONN: Status = STATUS_UNSUCCESSFUL; break; //-9 (FIXME)
00258         case ERR_ABRT: Status = STATUS_LOCAL_DISCONNECT; break; //-10
00259         case ERR_RST: Status = STATUS_REMOTE_DISCONNECT; break; //-11
00260         case ERR_CLSD: Status = STATUS_FILE_CLOSED; break; //-12
00261         case ERR_CONN: Status = STATUS_INVALID_CONNECTION; break; //-13
00262         case ERR_ARG: Status = STATUS_INVALID_PARAMETER; break; //-14
00263         case ERR_IF: Status = STATUS_UNEXPECTED_NETWORK_ERROR; break; //-15
00264         default:
00265             DbgPrint("Invalid error value: %d\n", err);
00266             ASSERT(FALSE);
00267             Status = STATUS_UNSUCCESSFUL;
00268             break;
00269     }
00270     
00271     DbgPrint("TCP operation failed: 0x%x (%d)\n", Status, err);
00272 
00273     return Status;
00274 }
00275 
00276 NTSTATUS TCPConnect
00277 ( PCONNECTION_ENDPOINT Connection,
00278   PTDI_CONNECTION_INFORMATION ConnInfo,
00279   PTDI_CONNECTION_INFORMATION ReturnInfo,
00280   PTCP_COMPLETION_ROUTINE Complete,
00281   PVOID Context )
00282 {
00283     NTSTATUS Status;
00284     struct ip_addr bindaddr, connaddr;
00285     IP_ADDRESS RemoteAddress;
00286     USHORT RemotePort;
00287     TA_IP_ADDRESS LocalAddress;
00288     PTDI_BUCKET Bucket;
00289     PNEIGHBOR_CACHE_ENTRY NCE;
00290     KIRQL OldIrql;
00291 
00292     TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Called\n"));
00293 
00294     Status = AddrBuildAddress
00295         ((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress,
00296          &RemoteAddress,
00297          &RemotePort);
00298 
00299     if (!NT_SUCCESS(Status))
00300     {
00301         TI_DbgPrint(DEBUG_TCP, ("Could not AddrBuildAddress in TCPConnect\n"));
00302         return Status;
00303     }
00304 
00305     /* Freed in TCPSocketState */
00306     TI_DbgPrint(DEBUG_TCP,
00307                 ("Connecting to address %x:%x\n",
00308                  RemoteAddress.Address.IPv4Address,
00309                  RemotePort));
00310 
00311     LockObject(Connection, &OldIrql);
00312 
00313     if (!Connection->AddressFile)
00314     {
00315         UnlockObject(Connection, OldIrql);
00316         return STATUS_INVALID_PARAMETER;
00317     }
00318 
00319     if (AddrIsUnspecified(&Connection->AddressFile->Address))
00320     {
00321         if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
00322         {
00323             UnlockObject(Connection, OldIrql);
00324             return STATUS_NETWORK_UNREACHABLE;
00325         }
00326 
00327         bindaddr.addr = NCE->Interface->Unicast.Address.IPv4Address;
00328     }
00329     else
00330     {
00331         bindaddr.addr = Connection->AddressFile->Address.Address.IPv4Address;
00332     }
00333 
00334     Status = TCPTranslateError(LibTCPBind(Connection,
00335                                           &bindaddr,
00336                                           Connection->AddressFile->Port));
00337     
00338     if (NT_SUCCESS(Status))
00339     {
00340         /* Check if we had an unspecified port */
00341         if (!Connection->AddressFile->Port)
00342         {
00343             /* We did, so we need to copy back the port */
00344             Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE);
00345             if (NT_SUCCESS(Status))
00346             {
00347                 /* Allocate the port in the port bitmap */
00348                 Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port);
00349                     
00350                 /* This should never fail */
00351                 ASSERT(Connection->AddressFile->Port != 0xFFFF);
00352             }
00353         }
00354 
00355         if (NT_SUCCESS(Status))
00356         {
00357             connaddr.addr = RemoteAddress.Address.IPv4Address;
00358 
00359             Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
00360             if (!Bucket)
00361             {
00362                 UnlockObject(Connection, OldIrql);
00363                 return STATUS_NO_MEMORY;
00364             }
00365             
00366             Bucket->Request.RequestNotifyObject = (PVOID)Complete;
00367             Bucket->Request.RequestContext = Context;
00368             
00369             InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
00370         
00371             Status = TCPTranslateError(LibTCPConnect(Connection,
00372                                                      &connaddr,
00373                                                      RemotePort));
00374         }
00375     }
00376 
00377     UnlockObject(Connection, OldIrql);
00378 
00379     TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Leaving. Status = 0x%x\n", Status));
00380 
00381     return Status;
00382 }
00383 
00384 NTSTATUS TCPDisconnect
00385 ( PCONNECTION_ENDPOINT Connection,
00386   UINT Flags,
00387   PLARGE_INTEGER Timeout,
00388   PTDI_CONNECTION_INFORMATION ConnInfo,
00389   PTDI_CONNECTION_INFORMATION ReturnInfo,
00390   PTCP_COMPLETION_ROUTINE Complete,
00391   PVOID Context )
00392 {
00393     NTSTATUS Status = STATUS_INVALID_PARAMETER;
00394     PTDI_BUCKET Bucket;
00395     KIRQL OldIrql;
00396     LARGE_INTEGER ActualTimeout;
00397 
00398     TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Called\n"));
00399 
00400     LockObject(Connection, &OldIrql);
00401 
00402     if (Connection->SocketContext)
00403     {
00404         if (Flags & TDI_DISCONNECT_RELEASE)
00405         {
00406             if (IsListEmpty(&Connection->SendRequest))
00407             {
00408                 Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
00409             }
00410             else if (Timeout && Timeout->QuadPart == 0)
00411             {
00412                 FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE);
00413                 TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
00414                 Status = STATUS_TIMEOUT;
00415             }
00416             else 
00417             {
00418                 /* Use the timeout specified or 1 second if none was specified */
00419                 if (Timeout)
00420                 {
00421                     ActualTimeout = *Timeout;
00422                 }
00423                 else
00424                 {
00425                     ActualTimeout.QuadPart = -1000000;
00426                 }
00427 
00428                 /* We couldn't complete the request now because we need to wait for outstanding I/O */
00429                 Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
00430                 if (!Bucket)
00431                 {
00432                     UnlockObject(Connection, OldIrql);
00433                     return STATUS_NO_MEMORY;
00434                 }
00435 
00436                 Bucket->Request.RequestNotifyObject = (PVOID)Complete;
00437                 Bucket->Request.RequestContext = Context;
00438 
00439                 InsertTailList(&Connection->ShutdownRequest, &Bucket->Entry);
00440 
00441                 ReferenceObject(Connection);
00442                 if (KeCancelTimer(&Connection->DisconnectTimer))
00443                 {
00444                     DereferenceObject(Connection);
00445                 }
00446                 KeSetTimer(&Connection->DisconnectTimer, ActualTimeout, &Connection->DisconnectDpc);
00447 
00448                 Status = STATUS_PENDING;
00449             }
00450         }
00451 
00452         if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
00453         {
00454             FlushReceiveQueue(Connection, STATUS_FILE_CLOSED, FALSE);
00455             FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE);
00456             FlushShutdownQueue(Connection, STATUS_FILE_CLOSED, FALSE);
00457             Status = TCPTranslateError(LibTCPShutdown(Connection, 1, 1));
00458         }
00459     }
00460     else
00461     {
00462         /* We already got closed by the other side so just return success */
00463         Status = STATUS_SUCCESS;
00464     }
00465 
00466     UnlockObject(Connection, OldIrql);
00467 
00468     TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Leaving. Status = 0x%x\n", Status));
00469 
00470     return Status;
00471 }
00472 
00473 NTSTATUS TCPReceiveData
00474 ( PCONNECTION_ENDPOINT Connection,
00475   PNDIS_BUFFER Buffer,
00476   ULONG ReceiveLength,
00477   PULONG BytesReceived,
00478   ULONG ReceiveFlags,
00479   PTCP_COMPLETION_ROUTINE Complete,
00480   PVOID Context )
00481 {
00482     PTDI_BUCKET Bucket;
00483     PUCHAR DataBuffer;
00484     UINT DataLen, Received;
00485     NTSTATUS Status;
00486 
00487     TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Called for %d bytes (on socket %x)\n",
00488                            ReceiveLength, Connection->SocketContext));
00489 
00490     NdisQueryBuffer(Buffer, &DataBuffer, &DataLen);
00491 
00492     Status = LibTCPGetDataFromConnectionQueue(Connection, DataBuffer, DataLen, &Received);
00493 
00494     if (Status == STATUS_PENDING)
00495     {
00496         Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
00497         if (!Bucket)
00498         {
00499             TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Failed to allocate bucket\n"));
00500 
00501             return STATUS_NO_MEMORY;
00502         }
00503     
00504         Bucket->Request.RequestNotifyObject = Complete;
00505         Bucket->Request.RequestContext = Context;
00506 
00507         ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
00508         TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Queued read irp\n"));
00509 
00510         TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Leaving. Status = STATUS_PENDING\n"));
00511 
00512         (*BytesReceived) = 0;
00513     }
00514     else
00515     {
00516         (*BytesReceived) = Received;
00517     }
00518 
00519     return Status;
00520 }
00521 
00522 NTSTATUS TCPSendData
00523 ( PCONNECTION_ENDPOINT Connection,
00524   PCHAR BufferData,
00525   ULONG SendLength,
00526   PULONG BytesSent,
00527   ULONG Flags,
00528   PTCP_COMPLETION_ROUTINE Complete,
00529   PVOID Context )
00530 {
00531     NTSTATUS Status;
00532     PTDI_BUCKET Bucket;
00533     KIRQL OldIrql;
00534 
00535     LockObject(Connection, &OldIrql);
00536 
00537     TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Called for %d bytes (on socket %x)\n",
00538                            SendLength, Connection->SocketContext));
00539 
00540     TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Connection = %x\n", Connection));
00541     TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Connection->SocketContext = %x\n",
00542                            Connection->SocketContext));
00543 
00544     Status = TCPTranslateError(LibTCPSend(Connection,
00545                                           BufferData,
00546                                           SendLength,
00547                                           FALSE));
00548     
00549     TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Send: %x, %d\n", Status, SendLength));
00550 
00551     /* Keep this request around ... there was no data yet */
00552     if (Status == STATUS_PENDING)
00553     {
00554         /* Freed in TCPSocketState */
00555         Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
00556         if (!Bucket)
00557         {
00558             UnlockObject(Connection, OldIrql);
00559             TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Failed to allocate bucket\n"));
00560             return STATUS_NO_MEMORY;
00561         }
00562         
00563         Bucket->Request.RequestNotifyObject = Complete;
00564         Bucket->Request.RequestContext = Context;
00565         *BytesSent = 0;
00566         
00567         InsertTailList( &Connection->SendRequest, &Bucket->Entry );
00568         TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Queued write irp\n"));
00569     }
00570     else if (Status == STATUS_SUCCESS)
00571     {
00572         *BytesSent = SendLength;
00573     }
00574     else
00575     {
00576         *BytesSent = 0;
00577     }
00578 
00579     UnlockObject(Connection, OldIrql);
00580 
00581     TI_DbgPrint(DEBUG_TCP, ("[IP, TCPSendData] Leaving. Status = %x\n", Status));
00582 
00583     return Status;
00584 }
00585 
00586 UINT TCPAllocatePort(const UINT HintPort)
00587 {
00588     if (HintPort)
00589     {
00590         if (AllocatePort(&TCPPorts, HintPort))
00591             return HintPort;
00592         else
00593         {
00594             TI_DbgPrint(MID_TRACE,("We got a hint port but couldn't allocate it\n"));
00595             return (UINT)-1;
00596         }
00597     }
00598     else
00599         return AllocatePortFromRange( &TCPPorts, 1024, 5000 );
00600 }
00601 
00602 VOID TCPFreePort(const UINT Port)
00603 {
00604     DeallocatePort(&TCPPorts, Port);
00605 }
00606 
00607 NTSTATUS TCPGetSockAddress
00608 ( PCONNECTION_ENDPOINT Connection,
00609   PTRANSPORT_ADDRESS Address,
00610   BOOLEAN GetRemote )
00611 {
00612     PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
00613     struct ip_addr ipaddr;
00614     NTSTATUS Status;
00615     KIRQL OldIrql;
00616     
00617     AddressIP->TAAddressCount = 1;
00618     AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
00619     AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
00620 
00621     LockObject(Connection, &OldIrql);
00622 
00623     if (GetRemote)
00624     {
00625         Status = TCPTranslateError(LibTCPGetPeerName(Connection->SocketContext,
00626                                     &ipaddr,
00627                                     &AddressIP->Address[0].Address[0].sin_port));
00628     }
00629     else
00630     {
00631         Status = TCPTranslateError(LibTCPGetHostName(Connection->SocketContext,
00632                                     &ipaddr,
00633                                     &AddressIP->Address[0].Address[0].sin_port));
00634     }
00635 
00636     UnlockObject(Connection, OldIrql);
00637     
00638     AddressIP->Address[0].Address[0].in_addr = ipaddr.addr;
00639     
00640     RtlZeroMemory(&AddressIP->Address[0].Address[0].sin_zero,
00641                   sizeof(AddressIP->Address[0].Address[0].sin_zero));
00642 
00643     return Status;
00644 }
00645 
00646 BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp )
00647 {
00648     PLIST_ENTRY Entry;
00649     PLIST_ENTRY ListHead[5];
00650     KIRQL OldIrql;
00651     PTDI_BUCKET Bucket;
00652     UINT i = 0;
00653     BOOLEAN Found = FALSE;
00654 
00655     ListHead[0] = &Endpoint->SendRequest;
00656     ListHead[1] = &Endpoint->ReceiveRequest;
00657     ListHead[2] = &Endpoint->ConnectRequest;
00658     ListHead[3] = &Endpoint->ListenRequest;
00659     ListHead[4] = &Endpoint->ShutdownRequest;
00660 
00661     LockObject(Endpoint, &OldIrql);
00662 
00663     for( i = 0; i < 5; i++ )
00664     {
00665         for( Entry = ListHead[i]->Flink;
00666              Entry != ListHead[i];
00667              Entry = Entry->Flink )
00668         {
00669             Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
00670             if( Bucket->Request.RequestContext == Irp )
00671             {
00672                 RemoveEntryList( &Bucket->Entry );
00673                 ExFreeToNPagedLookasideList(&TdiBucketLookasideList, Bucket);
00674                 Found = TRUE;
00675                 break;
00676             }
00677         }
00678     }
00679 
00680     UnlockObject(Endpoint, OldIrql);
00681 
00682     return Found;
00683 }
00684 
00685 /* EOF */

Generated on Sun May 27 2012 04:17:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.