ae98ad34cd70e6cf2929d95d6189036fc100e44b
[reactos.git] / 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 NTSTATUS TCPCheckPeerForAccept(PVOID Context,
16 PTDI_REQUEST_KERNEL Request) {
17 struct tcp_pcb *newpcb = Context;
18 NTSTATUS Status;
19 PTDI_CONNECTION_INFORMATION WhoIsConnecting;
20 PTA_IP_ADDRESS RemoteAddress;
21 struct ip_addr ipaddr;
22
23 if (Request->RequestFlags & TDI_QUERY_ACCEPT)
24 DbgPrint("TDI_QUERY_ACCEPT NOT SUPPORTED!!!\n");
25
26 WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)Request->ReturnConnectionInformation;
27 RemoteAddress = (PTA_IP_ADDRESS)WhoIsConnecting->RemoteAddress;
28
29 RemoteAddress->TAAddressCount = 1;
30 RemoteAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
31 RemoteAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
32
33 Status = TCPTranslateError(LibTCPGetPeerName(newpcb,
34 &ipaddr,
35 &RemoteAddress->Address[0].Address[0].sin_port));
36
37 RemoteAddress->Address[0].Address[0].in_addr = ipaddr.addr;
38
39 TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
40
41 return Status;
42 }
43
44 /* This listen is on a socket we keep as internal. That socket has the same
45 * lifetime as the address file */
46 NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
47 NTSTATUS Status = STATUS_SUCCESS;
48 struct ip_addr AddressToBind;
49 KIRQL OldIrql;
50
51 ASSERT(Connection);
52 ASSERT_KM_POINTER(Connection->AddressFile);
53
54 LockObject(Connection, &OldIrql);
55
56 TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
57
58 TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
59 Connection->SocketContext));
60
61 AddressToBind.addr = Connection->AddressFile->Address.Address.IPv4Address;
62
63 Status = TCPTranslateError(LibTCPBind(Connection->SocketContext,
64 &AddressToBind,
65 Connection->AddressFile->Port));
66
67 if (NT_SUCCESS(Status))
68 {
69 Connection->SocketContext = LibTCPListen(Connection->SocketContext, Backlog);
70 if (!Connection->SocketContext)
71 Status = STATUS_UNSUCCESSFUL;
72 }
73
74 UnlockObject(Connection, OldIrql);
75
76 TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
77
78 return Status;
79 }
80
81 BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
82 PCONNECTION_ENDPOINT Connection ) {
83 PLIST_ENTRY ListEntry;
84 PTDI_BUCKET Bucket;
85 KIRQL OldIrql;
86 BOOLEAN Found = FALSE;
87
88 LockObject(Listener, &OldIrql);
89
90 ListEntry = Listener->ListenRequest.Flink;
91 while ( ListEntry != &Listener->ListenRequest ) {
92 Bucket = CONTAINING_RECORD(ListEntry, TDI_BUCKET, Entry);
93
94 if( Bucket->AssociatedEndpoint == Connection ) {
95 RemoveEntryList( &Bucket->Entry );
96 ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG );
97 Found = TRUE;
98 break;
99 }
100
101 ListEntry = ListEntry->Flink;
102 }
103
104 UnlockObject(Listener, OldIrql);
105
106 return Found;
107 }
108
109 NTSTATUS TCPAccept ( PTDI_REQUEST Request,
110 PCONNECTION_ENDPOINT Listener,
111 PCONNECTION_ENDPOINT Connection,
112 PTCP_COMPLETION_ROUTINE Complete,
113 PVOID Context )
114 {
115 NTSTATUS Status;
116 PTDI_BUCKET Bucket;
117 KIRQL OldIrql;
118
119 TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
120
121 LockObject(Listener, &OldIrql);
122
123 Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket),
124 TDI_BUCKET_TAG );
125
126 if( Bucket ) {
127 Bucket->AssociatedEndpoint = Connection;
128 Bucket->Request.RequestNotifyObject = Complete;
129 Bucket->Request.RequestContext = Context;
130 InsertTailList( &Listener->ListenRequest, &Bucket->Entry );
131 Status = STATUS_PENDING;
132 } else
133 Status = STATUS_NO_MEMORY;
134
135 UnlockObject(Listener, OldIrql);
136
137 TI_DbgPrint(DEBUG_TCP,("TCPAccept finished %x\n", Status));
138 return Status;
139 }