Branch setupapi (again)
[reactos.git] / reactos / drivers / lib / ip / transport / tcp / accept.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: transport/tcp/tcp.c
5 * PURPOSE: Transmission Control Protocol Listen/Accept code
6 * PROGRAMMERS: Art Yerkes (arty@users.sf.net)
7 * REVISIONS:
8 * arty 12/21/2004 Created
9 */
10
11 #include "precomp.h"
12
13 NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
14 PCONNECTION_ENDPOINT Connection,
15 PTDI_REQUEST_KERNEL Request ) {
16 NTSTATUS Status;
17 SOCKADDR_IN OutAddr;
18 OSK_UINT OutAddrLen;
19 PTA_ADDRESS RequestAddressReturn;
20 SOCKADDR_IN AddressConnecting;
21 PTDI_CONNECTION_INFORMATION WhoIsConnecting;
22
23 /* Unpack TDI info -- We need the return connection information
24 * struct to return the address so it can be filtered if needed
25 * by WSAAccept -- The returned address will be passed on to
26 * userland after we complete this irp */
27 WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)
28 Request->ReturnConnectionInformation;
29
30 Status = TCPTranslateError
31 ( OskitTCPAccept( Listener->SocketContext,
32 &Connection->SocketContext,
33 &OutAddr,
34 sizeof(OutAddr),
35 &OutAddrLen,
36 Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) );
37
38 TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
39
40 if( NT_SUCCESS(Status) && Status != STATUS_PENDING ) {
41 TI_DbgPrint(DEBUG_TCP,("Copying address to %x (Who %x)\n",
42 RequestAddressReturn, WhoIsConnecting));
43
44 RequestAddressReturn = (PTA_ADDRESS)WhoIsConnecting->RemoteAddress;
45 RequestAddressReturn->AddressLength = OutAddrLen;
46 RequestAddressReturn->AddressType =
47 AddressConnecting.sin_family;
48 TI_DbgPrint(DEBUG_TCP,("Copying address proper: from %x to %x,%x\n",
49 ((PCHAR)&AddressConnecting) +
50 sizeof(AddressConnecting.sin_family),
51 RequestAddressReturn->Address,
52 RequestAddressReturn->AddressLength));
53 RtlCopyMemory( RequestAddressReturn->Address,
54 ((PCHAR)&AddressConnecting) +
55 sizeof(AddressConnecting.sin_family),
56 RequestAddressReturn->AddressLength );
57 TI_DbgPrint(DEBUG_TCP,("Done copying\n"));
58 }
59
60 TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
61
62 return Status;
63 }
64
65 /* This listen is on a socket we keep as internal. That socket has the same
66 * lifetime as the address file */
67 NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
68 NTSTATUS Status = STATUS_SUCCESS;
69 SOCKADDR_IN AddressToBind;
70
71 TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
72
73 TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
74 Connection->SocketContext));
75
76 ASSERT(Connection);
77 ASSERT_KM_POINTER(Connection->SocketContext);
78 ASSERT_KM_POINTER(Connection->AddressFile);
79
80 TcpipRecursiveMutexEnter( &TCPLock, TRUE );
81
82 AddressToBind.sin_family = AF_INET;
83 memcpy( &AddressToBind.sin_addr,
84 &Connection->AddressFile->Address.Address.IPv4Address,
85 sizeof(AddressToBind.sin_addr) );
86 AddressToBind.sin_port = Connection->AddressFile->Port;
87
88 TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
89
90 OskitTCPBind( Connection->SocketContext,
91 Connection,
92 &AddressToBind,
93 sizeof(AddressToBind) );
94
95 Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext,
96 Backlog ) );
97
98 TcpipRecursiveMutexLeave( &TCPLock );
99
100 TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
101
102 return Status;
103 }
104
105 VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
106 PCONNECTION_ENDPOINT Connection ) {
107 PLIST_ENTRY ListEntry;
108 PTDI_BUCKET Bucket;
109
110 TcpipRecursiveMutexEnter( &TCPLock, TRUE );
111
112 for( ListEntry = Listener->ListenRequest.Flink;
113 ListEntry != &Listener->ListenRequest;
114 ListEntry = ListEntry->Flink ) {
115 Bucket = CONTAINING_RECORD(ListEntry, TDI_BUCKET, Entry);
116
117 if( Bucket->Request.Handle.ConnectionContext == Connection ) {
118 #ifdef MEMTRACK
119 UntrackFL( __FILE__, __LINE__, Bucket->Request.RequestContext );
120 #endif
121 RemoveEntryList( ListEntry );
122 ExFreePool( Bucket );
123 }
124 }
125
126 TcpipRecursiveMutexLeave( &TCPLock );
127 }
128
129 NTSTATUS TCPAccept
130 ( PTDI_REQUEST Request,
131 PCONNECTION_ENDPOINT Listener,
132 PCONNECTION_ENDPOINT Connection,
133 PTCP_COMPLETION_ROUTINE Complete,
134 PVOID Context ) {
135 NTSTATUS Status;
136 PTDI_BUCKET Bucket;
137
138 TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
139
140 TcpipRecursiveMutexEnter( &TCPLock, TRUE );
141
142 Status = TCPServiceListeningSocket( Listener, Connection,
143 (PTDI_REQUEST_KERNEL)Request );
144
145 if( Status == STATUS_PENDING ) {
146 Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) );
147 Bucket->AssociatedEndpoint = Connection;
148 Bucket->Request.RequestNotifyObject = Complete;
149 Bucket->Request.RequestContext = Context;
150 InsertHeadList( &Listener->ListenRequest, &Bucket->Entry );
151 }
152
153 TcpipRecursiveMutexLeave( &TCPLock );
154
155 TI_DbgPrint(DEBUG_TCP,("TCPAccept finished %x\n", Status));
156 return Status;
157 }