2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: transport/tcp/accept.c
5 * PURPOSE: Transmission Control Protocol Listen/Accept code
6 * PROGRAMMERS: Art Yerkes (arty@users.sf.net)
8 * arty 12/21/2004 Created
13 NTSTATUS
TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener
,
14 PCONNECTION_ENDPOINT Connection
,
15 PTDI_REQUEST_KERNEL Request
) {
19 PTA_IP_ADDRESS RequestAddressReturn
;
20 PTDI_CONNECTION_INFORMATION WhoIsConnecting
;
22 ASSERT_LOCKED(&TCPLock
);
24 /* Unpack TDI info -- We need the return connection information
25 * struct to return the address so it can be filtered if needed
26 * by WSAAccept -- The returned address will be passed on to
27 * userland after we complete this irp */
28 WhoIsConnecting
= (PTDI_CONNECTION_INFORMATION
)
29 Request
->ReturnConnectionInformation
;
31 Status
= TCPTranslateError
32 ( OskitTCPAccept( Listener
->SocketContext
,
33 &Connection
->SocketContext
,
37 Request
->RequestFlags
& TDI_QUERY_ACCEPT
? 0 : 1 ) );
39 TI_DbgPrint(DEBUG_TCP
,("Status %x\n", Status
));
41 if( NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
) {
42 RequestAddressReturn
= WhoIsConnecting
->RemoteAddress
;
44 TI_DbgPrint(DEBUG_TCP
,("Copying address to %x (Who %x)\n",
45 RequestAddressReturn
, WhoIsConnecting
));
47 RequestAddressReturn
->TAAddressCount
= 1;
48 RequestAddressReturn
->Address
[0].AddressLength
= OutAddrLen
;
50 /* BSD uses the first byte of the sockaddr struct as a length.
51 * Since windows doesn't do that we strip it */
52 RequestAddressReturn
->Address
[0].AddressType
=
53 (OutAddr
.sin_family
>> 8) & 0xff;
55 RtlCopyMemory( &RequestAddressReturn
->Address
[0].Address
,
56 ((PCHAR
)&OutAddr
) + sizeof(USHORT
),
57 sizeof(RequestAddressReturn
->Address
[0].Address
[0]) );
59 TI_DbgPrint(DEBUG_TCP
,("Done copying\n"));
62 TI_DbgPrint(DEBUG_TCP
,("Status %x\n", Status
));
67 /* This listen is on a socket we keep as internal. That socket has the same
68 * lifetime as the address file */
69 NTSTATUS
TCPListen( PCONNECTION_ENDPOINT Connection
, UINT Backlog
) {
70 NTSTATUS Status
= STATUS_SUCCESS
;
71 SOCKADDR_IN AddressToBind
;
73 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
76 ASSERT_KM_POINTER(Connection
->SocketContext
);
77 ASSERT_KM_POINTER(Connection
->AddressFile
);
79 TI_DbgPrint(DEBUG_TCP
,("TCPListen started\n"));
81 TI_DbgPrint(DEBUG_TCP
,("Connection->SocketContext %x\n",
82 Connection
->SocketContext
));
84 AddressToBind
.sin_family
= AF_INET
;
85 memcpy( &AddressToBind
.sin_addr
,
86 &Connection
->AddressFile
->Address
.Address
.IPv4Address
,
87 sizeof(AddressToBind
.sin_addr
) );
88 AddressToBind
.sin_port
= Connection
->AddressFile
->Port
;
90 TI_DbgPrint(DEBUG_TCP
,("AddressToBind - %x:%x\n", AddressToBind
.sin_addr
, AddressToBind
.sin_port
));
92 Status
= TCPTranslateError( OskitTCPBind( Connection
->SocketContext
,
94 sizeof(AddressToBind
) ) );
96 if (NT_SUCCESS(Status
))
97 Status
= TCPTranslateError( OskitTCPListen( Connection
->SocketContext
, Backlog
) );
99 TcpipRecursiveMutexLeave( &TCPLock
);
101 TI_DbgPrint(DEBUG_TCP
,("TCPListen finished %x\n", Status
));
106 VOID
TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener
,
107 PCONNECTION_ENDPOINT Connection
) {
108 PLIST_ENTRY ListEntry
;
112 KeAcquireSpinLock(&Listener
->Lock
, &OldIrql
);
114 ListEntry
= Listener
->ListenRequest
.Flink
;
115 while ( ListEntry
!= &Listener
->ListenRequest
) {
116 Bucket
= CONTAINING_RECORD(ListEntry
, TDI_BUCKET
, Entry
);
118 if( Bucket
->AssociatedEndpoint
== Connection
) {
119 RemoveEntryList( &Bucket
->Entry
);
120 exFreePool( Bucket
);
124 ListEntry
= ListEntry
->Flink
;
127 KeReleaseSpinLock(&Listener
->Lock
, OldIrql
);
130 NTSTATUS
TCPAccept ( PTDI_REQUEST Request
,
131 PCONNECTION_ENDPOINT Listener
,
132 PCONNECTION_ENDPOINT Connection
,
133 PTCP_COMPLETION_ROUTINE Complete
,
139 TI_DbgPrint(DEBUG_TCP
,("TCPAccept started\n"));
141 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
143 Status
= TCPServiceListeningSocket( Listener
, Connection
,
144 (PTDI_REQUEST_KERNEL
)Request
);
146 TcpipRecursiveMutexLeave( &TCPLock
);
148 if( Status
== STATUS_PENDING
) {
149 Bucket
= exAllocatePool( NonPagedPool
, sizeof(*Bucket
) );
152 Bucket
->AssociatedEndpoint
= Connection
;
153 Bucket
->Request
.RequestNotifyObject
= Complete
;
154 Bucket
->Request
.RequestContext
= Context
;
155 IoMarkIrpPending((PIRP
)Context
);
156 ExInterlockedInsertTailList( &Listener
->ListenRequest
, &Bucket
->Entry
, &Listener
->Lock
);
158 Status
= STATUS_NO_MEMORY
;
161 TI_DbgPrint(DEBUG_TCP
,("TCPAccept finished %x\n", Status
));