[DELAYIMP] Fix 2 Clang-Cl warnings about __pfnDliNotifyHook2Default and __pfnDliFailu...
[reactos.git] / sdk / lib / drivers / 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/accept.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 #include "rosip.h"
14
15 extern NPAGED_LOOKASIDE_LIST TdiBucketLookasideList;
16
17 NTSTATUS TCPCheckPeerForAccept(PVOID Context,
18 PTDI_REQUEST_KERNEL Request)
19 {
20 struct tcp_pcb *newpcb = (struct tcp_pcb*)Context;
21 NTSTATUS Status;
22 PTDI_CONNECTION_INFORMATION WhoIsConnecting;
23 PTA_IP_ADDRESS RemoteAddress;
24 struct ip_addr ipaddr;
25
26 if (Request->RequestFlags & TDI_QUERY_ACCEPT)
27 DbgPrint("TDI_QUERY_ACCEPT NOT SUPPORTED!!!\n");
28
29 WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)Request->ReturnConnectionInformation;
30 RemoteAddress = (PTA_IP_ADDRESS)WhoIsConnecting->RemoteAddress;
31
32 RemoteAddress->TAAddressCount = 1;
33 RemoteAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
34 RemoteAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
35
36 Status = TCPTranslateError(LibTCPGetPeerName(newpcb,
37 &ipaddr,
38 &RemoteAddress->Address[0].Address[0].sin_port));
39
40 RemoteAddress->Address[0].Address[0].in_addr = ipaddr.addr;
41
42 return Status;
43 }
44
45 /* This listen is on a socket we keep as internal. That socket has the same
46 * lifetime as the address file */
47 NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog)
48 {
49 NTSTATUS Status = STATUS_SUCCESS;
50 struct ip_addr AddressToBind;
51 KIRQL OldIrql;
52 TA_IP_ADDRESS LocalAddress;
53
54 ASSERT(Connection);
55
56 LockObject(Connection, &OldIrql);
57
58 ASSERT_KM_POINTER(Connection->AddressFile);
59
60 TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Called\n"));
61
62 TI_DbgPrint(DEBUG_TCP, ("Connection->SocketContext %x\n",
63 Connection->SocketContext));
64
65 AddressToBind.addr = Connection->AddressFile->Address.Address.IPv4Address;
66
67 Status = TCPTranslateError(LibTCPBind(Connection,
68 &AddressToBind,
69 Connection->AddressFile->Port));
70
71 if (NT_SUCCESS(Status))
72 {
73 /* Check if we had an unspecified port */
74 if (!Connection->AddressFile->Port)
75 {
76 /* We did, so we need to copy back the port */
77 Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE);
78 if (NT_SUCCESS(Status))
79 {
80 /* Allocate the port in the port bitmap */
81 Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port);
82
83 /* This should never fail */
84 ASSERT(Connection->AddressFile->Port != 0xFFFF);
85 }
86 }
87 }
88
89 if (NT_SUCCESS(Status))
90 {
91 Connection->SocketContext = LibTCPListen(Connection, Backlog);
92 if (!Connection->SocketContext)
93 Status = STATUS_UNSUCCESSFUL;
94 }
95
96 UnlockObject(Connection, OldIrql);
97
98 TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Leaving. Status = %x\n", Status));
99
100 return Status;
101 }
102
103 BOOLEAN TCPAbortListenForSocket
104 ( PCONNECTION_ENDPOINT Listener,
105 PCONNECTION_ENDPOINT Connection)
106 {
107 PLIST_ENTRY ListEntry;
108 PTDI_BUCKET Bucket;
109 KIRQL OldIrql;
110 BOOLEAN Found = FALSE;
111
112 LockObject(Listener, &OldIrql);
113
114 ListEntry = Listener->ListenRequest.Flink;
115 while (ListEntry != &Listener->ListenRequest)
116 {
117 Bucket = CONTAINING_RECORD(ListEntry, TDI_BUCKET, Entry);
118
119 if (Bucket->AssociatedEndpoint == Connection)
120 {
121 DereferenceObject(Bucket->AssociatedEndpoint);
122 RemoveEntryList( &Bucket->Entry );
123 ExFreeToNPagedLookasideList(&TdiBucketLookasideList, Bucket);
124 Found = TRUE;
125 break;
126 }
127
128 ListEntry = ListEntry->Flink;
129 }
130
131 UnlockObject(Listener, OldIrql);
132
133 return Found;
134 }
135
136 NTSTATUS TCPAccept ( PTDI_REQUEST Request,
137 PCONNECTION_ENDPOINT Listener,
138 PCONNECTION_ENDPOINT Connection,
139 PTCP_COMPLETION_ROUTINE Complete,
140 PVOID Context )
141 {
142 NTSTATUS Status;
143 PTDI_BUCKET Bucket;
144 KIRQL OldIrql;
145
146 LockObject(Listener, &OldIrql);
147
148 Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList);
149
150 if (Bucket)
151 {
152 Bucket->AssociatedEndpoint = Connection;
153 ReferenceObject(Bucket->AssociatedEndpoint);
154
155 Bucket->Request.RequestNotifyObject = Complete;
156 Bucket->Request.RequestContext = Context;
157 InsertTailList( &Listener->ListenRequest, &Bucket->Entry );
158 Status = STATUS_PENDING;
159 }
160 else
161 Status = STATUS_NO_MEMORY;
162
163 UnlockObject(Listener, OldIrql);
164
165 return Status;
166 }