mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 02:15:47 +00:00
Added a (currently unworking) accept implementation. Needs work, but doesn't
break anything. Committed a patch by GvG: - SignalSocket: Removed collected parameter, changed Information to actual number of bytes returned. svn path=/trunk/; revision=12333
This commit is contained in:
parent
bcf559d5f2
commit
af8cd05c99
23 changed files with 691 additions and 177 deletions
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.9 2004/11/30 00:10:40 arty Exp $
|
# $Id: makefile,v 1.10 2004/12/25 21:30:18 arty Exp $
|
||||||
|
|
||||||
PATH_TO_TOP = ../../..
|
PATH_TO_TOP = ../../..
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ TARGET_PCH = $(PATH_TO_TOP)/drivers/lib/ip/include/precomp.h
|
||||||
# -DMEMTRACK
|
# -DMEMTRACK
|
||||||
TARGET_CFLAGS = \
|
TARGET_CFLAGS = \
|
||||||
-D__USE_W32API \
|
-D__USE_W32API \
|
||||||
-DMEMTRACK \
|
|
||||||
-D__NTDRIVER__ \
|
-D__NTDRIVER__ \
|
||||||
-D_SEH_NO_NATIVE_NLG \
|
-D_SEH_NO_NATIVE_NLG \
|
||||||
-Wall -Werror \
|
-Wall -Werror \
|
||||||
|
@ -40,6 +39,7 @@ TARGET_OBJECTS = \
|
||||||
network/routines.o \
|
network/routines.o \
|
||||||
network/transmit.o \
|
network/transmit.o \
|
||||||
transport/rawip/rawip.o \
|
transport/rawip/rawip.o \
|
||||||
|
transport/tcp/accept.o \
|
||||||
transport/tcp/event.o \
|
transport/tcp/event.o \
|
||||||
transport/tcp/if.o \
|
transport/tcp/if.o \
|
||||||
transport/tcp/tcp.o \
|
transport/tcp/tcp.o \
|
||||||
|
|
157
reactos/drivers/lib/ip/transport/tcp/accept.c
Normal file
157
reactos/drivers/lib/ip/transport/tcp/accept.c
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS TCP/IP protocol driver
|
||||||
|
* FILE: transport/tcp/tcp.c
|
||||||
|
* PURPOSE: Transmission Control Protocol Listen/Accept code
|
||||||
|
* PROGRAMMERS: Art Yerkes (arty@users.sf.net)
|
||||||
|
* REVISIONS:
|
||||||
|
* arty 12/21/2004 Created
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
||||||
|
PCONNECTION_ENDPOINT Connection,
|
||||||
|
PTDI_REQUEST_KERNEL Request ) {
|
||||||
|
NTSTATUS Status;
|
||||||
|
SOCKADDR_IN OutAddr;
|
||||||
|
OSK_UINT OutAddrLen;
|
||||||
|
PTA_ADDRESS RequestAddressReturn;
|
||||||
|
SOCKADDR_IN AddressConnecting;
|
||||||
|
PTDI_CONNECTION_INFORMATION WhoIsConnecting;
|
||||||
|
|
||||||
|
/* Unpack TDI info -- We need the return connection information
|
||||||
|
* struct to return the address so it can be filtered if needed
|
||||||
|
* by WSAAccept -- The returned address will be passed on to
|
||||||
|
* userland after we complete this irp */
|
||||||
|
WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)
|
||||||
|
Request->ReturnConnectionInformation;
|
||||||
|
|
||||||
|
Status = TCPTranslateError
|
||||||
|
( OskitTCPAccept( Listener->SocketContext,
|
||||||
|
&Connection->SocketContext,
|
||||||
|
&OutAddr,
|
||||||
|
sizeof(OutAddr),
|
||||||
|
&OutAddrLen,
|
||||||
|
Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) );
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
|
||||||
|
|
||||||
|
if( NT_SUCCESS(Status) && Status != STATUS_PENDING ) {
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Copying address to %x (Who %x)\n",
|
||||||
|
RequestAddressReturn, WhoIsConnecting));
|
||||||
|
|
||||||
|
RequestAddressReturn = (PTA_ADDRESS)WhoIsConnecting->RemoteAddress;
|
||||||
|
RequestAddressReturn->AddressLength = OutAddrLen;
|
||||||
|
RequestAddressReturn->AddressType =
|
||||||
|
AddressConnecting.sin_family;
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Copying address proper: from %x to %x,%x\n",
|
||||||
|
((PCHAR)&AddressConnecting) +
|
||||||
|
sizeof(AddressConnecting.sin_family),
|
||||||
|
RequestAddressReturn->Address,
|
||||||
|
RequestAddressReturn->AddressLength));
|
||||||
|
RtlCopyMemory( RequestAddressReturn->Address,
|
||||||
|
((PCHAR)&AddressConnecting) +
|
||||||
|
sizeof(AddressConnecting.sin_family),
|
||||||
|
RequestAddressReturn->AddressLength );
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Done copying\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This listen is on a socket we keep as internal. That socket has the same
|
||||||
|
* lifetime as the address file */
|
||||||
|
NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
SOCKADDR_IN AddressToBind;
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
|
||||||
|
Connection->SocketContext));
|
||||||
|
|
||||||
|
ASSERT(Connection);
|
||||||
|
ASSERT_KM_POINTER(Connection->SocketContext);
|
||||||
|
ASSERT_KM_POINTER(Connection->AddressFile);
|
||||||
|
|
||||||
|
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
|
||||||
|
|
||||||
|
AddressToBind.sin_family = AF_INET;
|
||||||
|
memcpy( &AddressToBind.sin_addr,
|
||||||
|
&Connection->AddressFile->Address.Address.IPv4Address,
|
||||||
|
sizeof(AddressToBind.sin_addr) );
|
||||||
|
AddressToBind.sin_port = Connection->AddressFile->Port;
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
|
||||||
|
|
||||||
|
OskitTCPBind( Connection->SocketContext,
|
||||||
|
Connection,
|
||||||
|
&AddressToBind,
|
||||||
|
sizeof(AddressToBind) );
|
||||||
|
|
||||||
|
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext,
|
||||||
|
Backlog ) );
|
||||||
|
|
||||||
|
TcpipRecursiveMutexLeave( &TCPLock );
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
|
||||||
|
PCONNECTION_ENDPOINT Connection ) {
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
PTDI_BUCKET Bucket;
|
||||||
|
|
||||||
|
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
|
||||||
|
|
||||||
|
for( ListEntry = Listener->ListenRequest.Flink;
|
||||||
|
ListEntry != &Listener->ListenRequest;
|
||||||
|
ListEntry = ListEntry->Flink ) {
|
||||||
|
Bucket = CONTAINING_RECORD(ListEntry, TDI_BUCKET, Entry);
|
||||||
|
|
||||||
|
if( Bucket->Request.Handle.ConnectionContext == Connection ) {
|
||||||
|
#ifdef MEMTRACK
|
||||||
|
UntrackFL( __FILE__, __LINE__, Bucket->Request.RequestContext );
|
||||||
|
#endif
|
||||||
|
RemoveEntryList( ListEntry );
|
||||||
|
ExFreePool( Bucket );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpipRecursiveMutexLeave( &TCPLock );
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS TCPAccept
|
||||||
|
( PTDI_REQUEST Request,
|
||||||
|
PCONNECTION_ENDPOINT Listener,
|
||||||
|
PCONNECTION_ENDPOINT Connection,
|
||||||
|
PTCP_COMPLETION_ROUTINE Complete,
|
||||||
|
PVOID Context ) {
|
||||||
|
NTSTATUS Status;
|
||||||
|
PTDI_BUCKET Bucket;
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
|
||||||
|
|
||||||
|
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
|
||||||
|
|
||||||
|
Status = TCPServiceListeningSocket( Listener, Connection,
|
||||||
|
(PTDI_REQUEST_KERNEL)Request );
|
||||||
|
|
||||||
|
if( Status == STATUS_PENDING ) {
|
||||||
|
Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) );
|
||||||
|
Bucket->AssociatedEndpoint = Connection;
|
||||||
|
Bucket->Request.RequestNotifyObject = Complete;
|
||||||
|
Bucket->Request.RequestContext = Context;
|
||||||
|
InsertHeadList( &Listener->ListenRequest, &Bucket->Entry );
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpipRecursiveMutexLeave( &TCPLock );
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("TCPAccept finished %x\n", Status));
|
||||||
|
return Status;
|
||||||
|
}
|
|
@ -18,6 +18,12 @@ int TCPSocketState(void *ClientData,
|
||||||
OSK_UINT NewState ) {
|
OSK_UINT NewState ) {
|
||||||
PCONNECTION_ENDPOINT Connection = WhichConnection;
|
PCONNECTION_ENDPOINT Connection = WhichConnection;
|
||||||
|
|
||||||
|
TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n",
|
||||||
|
NewState & SEL_CONNECT ? 'C' : 'c',
|
||||||
|
NewState & SEL_READ ? 'R' : 'r',
|
||||||
|
NewState & SEL_FIN ? 'F' : 'f',
|
||||||
|
NewState & SEL_ACCEPT ? 'A' : 'a'));
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
|
TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
|
||||||
NewState, Connection,
|
NewState, Connection,
|
||||||
Connection ? Connection->State ^ NewState :
|
Connection ? Connection->State ^ NewState :
|
||||||
|
@ -33,6 +39,8 @@ int TCPSocketState(void *ClientData,
|
||||||
TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
|
TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TI_DbgPrint(MID_TRACE,("Connection signalled: %d\n",
|
||||||
|
Connection->Signalled));
|
||||||
if( !Connection->Signalled ) {
|
if( !Connection->Signalled ) {
|
||||||
Connection->Signalled = TRUE;
|
Connection->Signalled = TRUE;
|
||||||
Connection->SignalState = NewState;
|
Connection->SignalState = NewState;
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
* FILE: transport/tcp/tcp.c
|
* FILE: transport/tcp/tcp.c
|
||||||
* PURPOSE: Transmission Control Protocol
|
* PURPOSE: Transmission Control Protocol
|
||||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
|
* Art Yerkes (arty@users.sf.net)
|
||||||
* REVISIONS:
|
* REVISIONS:
|
||||||
* CSH 01/08-2000 Created
|
* CSH 01/08-2000 Created
|
||||||
|
* arty 12/21/2004 Added accept
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
@ -25,11 +27,11 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection,
|
||||||
PTCP_COMPLETION_ROUTINE Complete;
|
PTCP_COMPLETION_ROUTINE Complete;
|
||||||
PTDI_BUCKET Bucket;
|
PTDI_BUCKET Bucket;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
BOOLEAN CompletedOne = FALSE;
|
PIRP Irp;
|
||||||
|
PMDL Mdl;
|
||||||
|
|
||||||
/* Things that can happen when we try the initial connection */
|
/* Things that can happen when we try the initial connection */
|
||||||
if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) &&
|
if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) &&
|
||||||
|
|
||||||
!(Connection->State & (SEL_CONNECT | SEL_FIN)) ) {
|
!(Connection->State & (SEL_CONNECT | SEL_FIN)) ) {
|
||||||
while( !IsListEmpty( &Connection->ConnectRequest ) ) {
|
while( !IsListEmpty( &Connection->ConnectRequest ) ) {
|
||||||
Connection->State |= NewState & (SEL_CONNECT | SEL_FIN);
|
Connection->State |= NewState & (SEL_CONNECT | SEL_FIN);
|
||||||
|
@ -45,27 +47,56 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( (NewState & SEL_ACCEPT) ) {
|
||||||
|
/* Handle readable on a listening socket --
|
||||||
|
* TODO: Implement filtering
|
||||||
|
*/
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
|
||||||
|
Connection,
|
||||||
|
IsListEmpty(&Connection->ListenRequest) ?
|
||||||
|
"empty" : "nonempty"));
|
||||||
|
|
||||||
|
while( !IsListEmpty( &Connection->ListenRequest ) ) {
|
||||||
|
PIO_STACK_LOCATION IrpSp;
|
||||||
|
|
||||||
|
Entry = RemoveHeadList( &Connection->ListenRequest );
|
||||||
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
|
||||||
|
Irp = Bucket->Request.RequestContext;
|
||||||
|
IrpSp = IoGetCurrentIrpStackLocation( Irp );
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
|
||||||
|
Status = TCPServiceListeningSocket
|
||||||
|
( Connection->AddressFile->Listener,
|
||||||
|
Bucket->AssociatedEndpoint,
|
||||||
|
(PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
|
||||||
|
|
||||||
|
if( Status == STATUS_PENDING ) {
|
||||||
|
InsertHeadList( &Connection->ListenRequest, &Bucket->Entry );
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
Complete( Bucket->Request.RequestContext, Status, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Things that happen after we're connected */
|
/* Things that happen after we're connected */
|
||||||
if( (NewState & SEL_READ) ) {
|
if( (NewState & SEL_READ) ) {
|
||||||
TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
|
TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
|
||||||
IsListEmpty(&Connection->ReceiveRequest) ?
|
IsListEmpty(&Connection->ReceiveRequest) ?
|
||||||
"empty" : "nonempty"));
|
"empty" : "nonempty"));
|
||||||
|
|
||||||
while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
|
while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
|
||||||
PIRP Irp;
|
|
||||||
OSK_UINT RecvLen = 0, Received = 0;
|
OSK_UINT RecvLen = 0, Received = 0;
|
||||||
OSK_PCHAR RecvBuffer = 0;
|
OSK_PCHAR RecvBuffer = 0;
|
||||||
PMDL Mdl;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
Entry = RemoveHeadList( &Connection->ReceiveRequest );
|
Entry = RemoveHeadList( &Connection->ReceiveRequest );
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Readable, Completing read request %x\n",
|
|
||||||
Bucket->Request));
|
|
||||||
|
|
||||||
Irp = Bucket->Request.RequestContext;
|
Irp = Bucket->Request.RequestContext;
|
||||||
Mdl = Irp->MdlAddress;
|
Mdl = Irp->MdlAddress;
|
||||||
|
|
||||||
|
@ -97,23 +128,17 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection,
|
||||||
TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
|
TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
|
||||||
Received, Status));
|
Received, Status));
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Completing Receive Request: %x\n",
|
|
||||||
Bucket->Request));
|
|
||||||
|
|
||||||
Complete( Bucket->Request.RequestContext,
|
Complete( Bucket->Request.RequestContext,
|
||||||
STATUS_SUCCESS, Received );
|
STATUS_SUCCESS, Received );
|
||||||
CompletedOne = TRUE;
|
|
||||||
} else if( Status == STATUS_PENDING ) {
|
} else if( Status == STATUS_PENDING ) {
|
||||||
InsertHeadList( &Connection->ReceiveRequest,
|
InsertHeadList
|
||||||
&Bucket->Entry );
|
( &Connection->ReceiveRequest, &Bucket->Entry );
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
TI_DbgPrint(DEBUG_TCP,
|
||||||
("Completing Receive request: %x %x\n",
|
("Completing Receive request: %x %x\n",
|
||||||
Bucket->Request, Status));
|
Bucket->Request, Status));
|
||||||
Complete( Bucket->Request.RequestContext, Status, 0 );
|
Complete( Bucket->Request.RequestContext, Status, 0 );
|
||||||
CompletedOne = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,59 +516,6 @@ NTSTATUS TCPClose
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS TCPListen
|
|
||||||
( PCONNECTION_ENDPOINT Connection,
|
|
||||||
UINT Backlog,
|
|
||||||
PTCP_COMPLETION_ROUTINE Complete,
|
|
||||||
PVOID Context) {
|
|
||||||
NTSTATUS Status;
|
|
||||||
SOCKADDR_IN AddressToBind;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
|
|
||||||
Connection->SocketContext));
|
|
||||||
|
|
||||||
ASSERT(Connection);
|
|
||||||
ASSERT_KM_POINTER(Connection->SocketContext);
|
|
||||||
ASSERT_KM_POINTER(Connection->AddressFile);
|
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
|
|
||||||
|
|
||||||
AddressToBind.sin_family = AF_INET;
|
|
||||||
memcpy( &AddressToBind.sin_addr,
|
|
||||||
&Connection->AddressFile->Address.Address.IPv4Address,
|
|
||||||
sizeof(AddressToBind.sin_addr) );
|
|
||||||
AddressToBind.sin_port = Connection->AddressFile->Port;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
|
|
||||||
|
|
||||||
OskitTCPBind( Connection->SocketContext,
|
|
||||||
Connection,
|
|
||||||
&AddressToBind,
|
|
||||||
sizeof(AddressToBind) );
|
|
||||||
|
|
||||||
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext,
|
|
||||||
Backlog ) );
|
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave( &TCPLock );
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS TCPAccept
|
|
||||||
( PTDI_REQUEST Request,
|
|
||||||
VOID **NewSocketContext ) {
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPAccept finished %x\n", Status));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS TCPReceiveData
|
NTSTATUS TCPReceiveData
|
||||||
( PCONNECTION_ENDPOINT Connection,
|
( PCONNECTION_ENDPOINT Connection,
|
||||||
PNDIS_BUFFER Buffer,
|
PNDIS_BUFFER Buffer,
|
||||||
|
|
|
@ -133,6 +133,12 @@ extern int OskitTCPClose( void *socket );
|
||||||
extern int OskitTCPBind( void *socket, void *connection,
|
extern int OskitTCPBind( void *socket, void *connection,
|
||||||
void *nam, OSK_UINT namelen );
|
void *nam, OSK_UINT namelen );
|
||||||
|
|
||||||
|
extern int OskitTCPAccept( void *socket, void **new_socket,
|
||||||
|
void *addr_out,
|
||||||
|
OSK_UINT addr_len,
|
||||||
|
OSK_UINT *out_addr_len,
|
||||||
|
OSK_UINT finish_accept );
|
||||||
|
|
||||||
extern int OskitTCPListen( void *socket, int backlog );
|
extern int OskitTCPListen( void *socket, int backlog );
|
||||||
|
|
||||||
extern int OskitTCPRecv( void *connection,
|
extern int OskitTCPRecv( void *connection,
|
||||||
|
|
|
@ -22,8 +22,8 @@ struct linker_set domain_set;
|
||||||
|
|
||||||
OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 };
|
OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 };
|
||||||
|
|
||||||
//OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
|
OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
|
||||||
OSK_UINT OskitDebugTraceLevel = 0;
|
//OSK_UINT OskitDebugTraceLevel = 0;
|
||||||
|
|
||||||
/* SPL */
|
/* SPL */
|
||||||
unsigned cpl;
|
unsigned cpl;
|
||||||
|
@ -119,6 +119,7 @@ int OskitTCPSocket( void *context,
|
||||||
if( !error ) {
|
if( !error ) {
|
||||||
so->so_connection = context;
|
so->so_connection = context;
|
||||||
so->so_state = SS_NBIO;
|
so->so_state = SS_NBIO;
|
||||||
|
so->so_error = 0;
|
||||||
*aso = so;
|
*aso = so;
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
|
@ -138,6 +139,8 @@ int OskitTCPRecv( void *connection,
|
||||||
|
|
||||||
*OutLen = 0;
|
*OutLen = 0;
|
||||||
|
|
||||||
|
printf("so->so_state %x\n", ((struct socket *)connection)->so_state);
|
||||||
|
|
||||||
if( Flags & OSK_MSG_OOB ) tcp_flags |= MSG_OOB;
|
if( Flags & OSK_MSG_OOB ) tcp_flags |= MSG_OOB;
|
||||||
if( Flags & OSK_MSG_DONTWAIT ) tcp_flags |= MSG_DONTWAIT;
|
if( Flags & OSK_MSG_DONTWAIT ) tcp_flags |= MSG_DONTWAIT;
|
||||||
if( Flags & OSK_MSG_PEEK ) tcp_flags |= MSG_PEEK;
|
if( Flags & OSK_MSG_PEEK ) tcp_flags |= MSG_PEEK;
|
||||||
|
@ -281,16 +284,117 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
|
||||||
}
|
}
|
||||||
|
|
||||||
int OskitTCPAccept( void *socket,
|
int OskitTCPAccept( void *socket,
|
||||||
|
void **new_socket,
|
||||||
void *AddrOut,
|
void *AddrOut,
|
||||||
OSK_UINT AddrLen,
|
OSK_UINT AddrLen,
|
||||||
OSK_UINT *OutAddrLen ) {
|
OSK_UINT *OutAddrLen,
|
||||||
struct mbuf nam;
|
OSK_UINT FinishAccepting ) {
|
||||||
int error;
|
struct socket *head = (void *)socket;
|
||||||
|
struct sockaddr *name = (struct sockaddr *)AddrOut;
|
||||||
|
struct socket **newso = (struct socket **)new_socket;
|
||||||
|
struct socket *so = socket;
|
||||||
|
struct sockaddr_in sa;
|
||||||
|
struct mbuf mnam;
|
||||||
|
int namelen = 0, error = 0, s;
|
||||||
|
|
||||||
nam.m_data = AddrOut;
|
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Doing accept (Finish %d)\n",
|
||||||
nam.m_len = AddrLen;
|
FinishAccepting));
|
||||||
|
|
||||||
|
*OutAddrLen = AddrLen;
|
||||||
|
|
||||||
return soaccept( socket, &nam );
|
if (name)
|
||||||
|
/* that's a copyin actually */
|
||||||
|
namelen = *OutAddrLen;
|
||||||
|
|
||||||
|
s = splnet();
|
||||||
|
|
||||||
|
OskitDumpBuffer( so, sizeof(*so) );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if ((head->so_options & SO_ACCEPTCONN) == 0) {
|
||||||
|
splx(s);
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
|
||||||
|
head->so_options, SO_ACCEPTCONN));
|
||||||
|
error = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("head->so_q = %x, head->so_state = %x\n",
|
||||||
|
head->so_q, head->so_state));
|
||||||
|
|
||||||
|
if ((head->so_state & SS_NBIO) && head->so_q == NULL) {
|
||||||
|
splx(s);
|
||||||
|
error = EWOULDBLOCK;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
while (head->so_q == NULL && head->so_error == 0) {
|
||||||
|
if (head->so_state & SS_CANTRCVMORE) {
|
||||||
|
head->so_error = ECONNABORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
error = tsleep((caddr_t)&head->so_timeo, PSOCK | PCATCH,
|
||||||
|
"accept", 0);
|
||||||
|
if (error) {
|
||||||
|
splx(s);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
}
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (head->so_error) {
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
error = head->so_error;
|
||||||
|
head->so_error = 0;
|
||||||
|
splx(s);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At this point we know that there is at least one connection
|
||||||
|
* ready to be accepted. Remove it from the queue.
|
||||||
|
*/
|
||||||
|
so = head->so_q;
|
||||||
|
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
if( FinishAccepting ) {
|
||||||
|
head->so_q = so->so_q;
|
||||||
|
head->so_qlen--;
|
||||||
|
|
||||||
|
*newso = so;
|
||||||
|
|
||||||
|
/*so->so_state &= ~SS_COMP;*/
|
||||||
|
so->so_q = NULL;
|
||||||
|
|
||||||
|
mnam.m_data = &sa;
|
||||||
|
mnam.m_len = sizeof(sa);
|
||||||
|
|
||||||
|
(void) soaccept(so, &mnam);
|
||||||
|
|
||||||
|
so->so_state = SS_NBIO | SS_ISCONNECTED;
|
||||||
|
|
||||||
|
OskitDumpBuffer( so, sizeof(*so) );
|
||||||
|
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
if (name) {
|
||||||
|
/* check sa_len before it is destroyed */
|
||||||
|
memcpy( AddrOut, &sa, AddrLen < sizeof(sa) ? AddrLen : sizeof(sa) );
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
*OutAddrLen = namelen; /* copyout actually */
|
||||||
|
}
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
|
splx(s);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error));
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The story so far
|
/* The story so far
|
||||||
|
|
|
@ -20,12 +20,17 @@ void wakeup( struct socket *so, void *token ) {
|
||||||
OSK_UINT flags = 0;
|
OSK_UINT flags = 0;
|
||||||
|
|
||||||
OS_DbgPrint
|
OS_DbgPrint
|
||||||
(OSK_MID_TRACE,("XXX Bytes to receive: %d\n", so->so_rcv.sb_cc));
|
(OSK_MID_TRACE,("XXX Bytes to receive: %d state %x\n",
|
||||||
|
so->so_rcv.sb_cc, so->so_state));
|
||||||
|
|
||||||
if( so->so_state & SS_ISCONNECTED ) {
|
if( so->so_state & SS_ISCONNECTED ) {
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Socket connected!\n"));
|
OS_DbgPrint(OSK_MID_TRACE,("Socket connected!\n"));
|
||||||
flags |= SEL_CONNECT;
|
flags |= SEL_CONNECT;
|
||||||
}
|
}
|
||||||
|
if( so->so_q ) {
|
||||||
|
OS_DbgPrint(OSK_MID_TRACE,("Socket accepting q\n"));
|
||||||
|
flags |= SEL_ACCEPT;
|
||||||
|
}
|
||||||
if( so->so_rcv.sb_cc > 0 ) {
|
if( so->so_rcv.sb_cc > 0 ) {
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Socket readable\n"));
|
OS_DbgPrint(OSK_MID_TRACE,("Socket readable\n"));
|
||||||
flags |= SEL_READ;
|
flags |= SEL_READ;
|
||||||
|
|
|
@ -330,7 +330,7 @@ m_copym(m, off0, len, wait)
|
||||||
copyhdr = 1;
|
copyhdr = 1;
|
||||||
while (off > 0) {
|
while (off > 0) {
|
||||||
if (m == 0)
|
if (m == 0)
|
||||||
panic("m_copym");
|
panic("m_copym: %d", off);
|
||||||
if (off < m->m_len)
|
if (off < m->m_len)
|
||||||
break;
|
break;
|
||||||
off -= m->m_len;
|
off -= m->m_len;
|
||||||
|
|
|
@ -608,6 +608,8 @@ restart:
|
||||||
}
|
}
|
||||||
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
|
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
|
||||||
(so->so_proto->pr_flags & PR_CONNREQUIRED)) {
|
(so->so_proto->pr_flags & PR_CONNREQUIRED)) {
|
||||||
|
printf("so: %x\n", so);
|
||||||
|
__asm__("int3");
|
||||||
error = ENOTCONN;
|
error = ENOTCONN;
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
|
@ -774,7 +776,7 @@ dontblock:
|
||||||
* Keep sockbuf locked against other readers.
|
* Keep sockbuf locked against other readers.
|
||||||
*/
|
*/
|
||||||
while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 &&
|
while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 &&
|
||||||
!sosendallatonce(so) && !nextrecord) {
|
!sosendallatonce(so) && !nextrecord) {
|
||||||
if (so->so_error || so->so_state & SS_CANTRCVMORE)
|
if (so->so_error || so->so_state & SS_CANTRCVMORE)
|
||||||
break;
|
break;
|
||||||
error = sbwait(&so->so_rcv);
|
error = sbwait(&so->so_rcv);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: connect.c,v 1.9 2004/12/13 21:20:37 arty Exp $
|
/* $Id: connect.c,v 1.10 2004/12/25 21:30:17 arty Exp $
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/connect.c
|
* FILE: drivers/net/afd/afd/connect.c
|
||||||
|
@ -40,12 +40,36 @@ NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB ) {
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Allocate the receive area and start receiving */
|
||||||
|
FCB->Recv.Window =
|
||||||
|
ExAllocatePool( NonPagedPool, FCB->Recv.Size );
|
||||||
|
FCB->Send.Window =
|
||||||
|
ExAllocatePool( NonPagedPool, FCB->Send.Size );
|
||||||
|
|
||||||
|
FCB->State = SOCKET_STATE_CONNECTED;
|
||||||
|
|
||||||
|
if( FCB->Recv.Window ) {
|
||||||
|
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
|
||||||
|
FCB->Connection.Object,
|
||||||
|
TDI_RECEIVE_NORMAL,
|
||||||
|
FCB->Recv.Window,
|
||||||
|
FCB->Recv.Size,
|
||||||
|
&FCB->ReceiveIrp.Iosb,
|
||||||
|
ReceiveComplete,
|
||||||
|
FCB );
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS DDKAPI StreamSocketConnectComplete
|
NTSTATUS DDKAPI StreamSocketConnectComplete
|
||||||
( PDEVICE_OBJECT DeviceObject,
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
PVOID Context ) {
|
PVOID Context ) {
|
||||||
NTSTATUS Status = Irp->IoStatus.Status;
|
NTSTATUS Status = Irp->IoStatus.Status;
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||||
PLIST_ENTRY NextIrpEntry;
|
PLIST_ENTRY NextIrpEntry;
|
||||||
PIRP NextIrp;
|
PIRP NextIrp;
|
||||||
|
@ -83,22 +107,7 @@ NTSTATUS DDKAPI StreamSocketConnectComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) ) {
|
if( NT_SUCCESS(Status) ) {
|
||||||
/* Allocate the receive area and start receiving */
|
Status = MakeSocketIntoConnection( FCB );
|
||||||
FCB->Recv.Window =
|
|
||||||
ExAllocatePool( NonPagedPool, FCB->Recv.Size );
|
|
||||||
FCB->Send.Window =
|
|
||||||
ExAllocatePool( NonPagedPool, FCB->Send.Size );
|
|
||||||
|
|
||||||
if( FCB->Recv.Window ) {
|
|
||||||
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
|
|
||||||
IrpSp->FileObject,
|
|
||||||
TDI_RECEIVE_NORMAL,
|
|
||||||
FCB->Recv.Window,
|
|
||||||
FCB->Recv.Size,
|
|
||||||
&FCB->ReceiveIrp.Iosb,
|
|
||||||
ReceiveComplete,
|
|
||||||
FCB );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( FCB->Send.Window &&
|
if( FCB->Send.Window &&
|
||||||
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: listen.c,v 1.4 2004/09/05 04:26:29 arty Exp $
|
/* $Id: listen.c,v 1.5 2004/12/25 21:30:17 arty Exp $
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/listen.c
|
* FILE: drivers/net/afd/afd/listen.c
|
||||||
|
@ -12,12 +12,54 @@
|
||||||
#include "tdiconn.h"
|
#include "tdiconn.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
VOID SatisfyAccept( PIRP Irp, PFILE_OBJECT NewFileObject,
|
||||||
|
PAFD_TDI_OBJECT_QELT Qelt ) {
|
||||||
|
PAFD_FCB FCB = NewFileObject->FsContext;
|
||||||
|
|
||||||
|
if( !SocketAcquireStateLock( FCB ) ) return;
|
||||||
|
|
||||||
|
/* Transfer the connection to the new socket, launch the opening read */
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Completing a real accept (FCB %x)\n", FCB));
|
||||||
|
|
||||||
|
FCB->State = SOCKET_STATE_CONNECTED;
|
||||||
|
FCB->Connection = Qelt->Object;
|
||||||
|
#if 0
|
||||||
|
FCB->RemoteAddress =
|
||||||
|
TaCopyTransportAddress( Qelt->ConnInfo->RemoteAddress );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||||
|
|
||||||
|
MakeSocketIntoConnection( FCB );
|
||||||
|
|
||||||
|
SocketStateUnlock( FCB );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) {
|
||||||
|
PAFD_RECEIVED_ACCEPT_DATA ListenReceive =
|
||||||
|
(PAFD_RECEIVED_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
|
ListenReceive->SequenceNumber = Qelt->Seq;
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Giving SEQ %d to userland\n", Qelt->Seq));
|
||||||
|
#if 0
|
||||||
|
TaCopyTransportAddressInPlace( &ListenReceive->Address,
|
||||||
|
Qelt->ConnInfo->RemoteAddress );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = sizeof(*ListenReceive);
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS DDKAPI ListenComplete
|
NTSTATUS DDKAPI ListenComplete
|
||||||
( PDEVICE_OBJECT DeviceObject,
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
PVOID Context ) {
|
PVOID Context ) {
|
||||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||||
|
PAFD_TDI_OBJECT_QELT Qelt;
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return Status;
|
if( !SocketAcquireStateLock( FCB ) ) return Status;
|
||||||
|
|
||||||
|
@ -31,7 +73,39 @@ NTSTATUS DDKAPI ListenComplete
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
|
AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
|
||||||
AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", FCB->ListenIrp.Iosb.Status));
|
AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", FCB->ListenIrp.Iosb.Status));
|
||||||
AFD_DbgPrint(MID_TRACE,("Doing nothing as yet.\n"));
|
|
||||||
|
Qelt = ExAllocatePool( NonPagedPool, sizeof(*Qelt) );
|
||||||
|
if( !Qelt ) {
|
||||||
|
TdiCloseDevice( FCB->Connection.Handle,
|
||||||
|
FCB->Connection.Object );
|
||||||
|
} else {
|
||||||
|
Qelt->Object = FCB->Connection;
|
||||||
|
Qelt->Seq = FCB->ConnSeq++;
|
||||||
|
InsertTailList( &FCB->PendingConnections, &Qelt->ListEntry );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Satisfy a pre-accept request if one is available */
|
||||||
|
if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) &&
|
||||||
|
!IsListEmpty( &FCB->PendingConnections ) ) {
|
||||||
|
PLIST_ENTRY PendingIrp =
|
||||||
|
RemoveHeadList( &FCB->PendingIrpList[FUNCTION_PREACCEPT] );
|
||||||
|
PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
|
||||||
|
SatisfyPreAccept
|
||||||
|
( CONTAINING_RECORD( PendingIrp, IRP,
|
||||||
|
Tail.Overlay.ListEntry ),
|
||||||
|
CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT,
|
||||||
|
ListEntry ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
FCB->NeedsNewListen = TRUE;
|
||||||
|
|
||||||
|
/* Trigger a select return if appropriate */
|
||||||
|
if( !IsListEmpty( &FCB->PendingConnections ) ) {
|
||||||
|
FCB->PollState |= AFD_EVENT_ACCEPT;
|
||||||
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
|
} else {
|
||||||
|
FCB->PollState &= ~AFD_EVENT_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock( FCB );
|
||||||
|
|
||||||
|
@ -61,17 +135,140 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
FCB->DelayedAccept = ListenReq->UseDelayedAcceptance;
|
FCB->DelayedAccept = ListenReq->UseDelayedAcceptance;
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle));
|
||||||
|
|
||||||
Status = WarmSocketForConnection( FCB );
|
Status = WarmSocketForConnection( FCB );
|
||||||
|
|
||||||
FCB->State = SOCKET_STATE_LISTENING;
|
FCB->State = SOCKET_STATE_LISTENING;
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Status from warmsocket %x\n", Status));
|
||||||
|
|
||||||
|
TdiBuildNullConnectionInfo
|
||||||
|
( &FCB->ListenIrp.ConnectionCallInfo,
|
||||||
|
FCB->LocalAddress->Address[0].AddressType );
|
||||||
|
TdiBuildNullConnectionInfo
|
||||||
|
( &FCB->ListenIrp.ConnectionReturnInfo,
|
||||||
|
FCB->LocalAddress->Address[0].AddressType );
|
||||||
|
|
||||||
Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
|
Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
|
||||||
FCB->Connection.Object,
|
FCB->Connection.Object,
|
||||||
&FCB->ListenIrp.ConnectionInfo,
|
&FCB->ListenIrp.ConnectionCallInfo,
|
||||||
|
&FCB->ListenIrp.ConnectionReturnInfo,
|
||||||
&FCB->ListenIrp.Iosb,
|
&FCB->ListenIrp.Iosb,
|
||||||
ListenComplete,
|
ListenComplete,
|
||||||
FCB );
|
FCB );
|
||||||
|
|
||||||
|
if( NT_SUCCESS(Status) || Status == STATUS_PENDING )
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp ) {
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
|
|
||||||
|
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, TRUE );
|
||||||
|
|
||||||
|
if( !IsListEmpty( &FCB->PendingConnections ) ) {
|
||||||
|
PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
|
||||||
|
|
||||||
|
/* We have a pending connection ... complete this irp right away */
|
||||||
|
SatisfyPreAccept
|
||||||
|
( Irp,
|
||||||
|
CONTAINING_RECORD
|
||||||
|
( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry ) );
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
|
||||||
|
|
||||||
|
SocketStateUnlock( FCB );
|
||||||
|
return Status;
|
||||||
|
} else {
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Holding\n"));
|
||||||
|
|
||||||
|
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_PREACCEPT );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp ) {
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
|
PAFD_ACCEPT_DATA AcceptData = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
PLIST_ENTRY PendingConn;
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
|
|
||||||
|
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, TRUE );
|
||||||
|
|
||||||
|
if( FCB->NeedsNewListen ) {
|
||||||
|
AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle));
|
||||||
|
|
||||||
|
/* Launch new accept socket */
|
||||||
|
Status = WarmSocketForConnection( FCB );
|
||||||
|
|
||||||
|
if( Status == STATUS_SUCCESS ) {
|
||||||
|
TdiBuildNullConnectionInfo
|
||||||
|
( &FCB->ListenIrp.ConnectionReturnInfo,
|
||||||
|
FCB->LocalAddress->Address[0].AddressType );
|
||||||
|
|
||||||
|
Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
|
||||||
|
FCB->Connection.Object,
|
||||||
|
&FCB->ListenIrp.ConnectionCallInfo,
|
||||||
|
&FCB->ListenIrp.ConnectionReturnInfo,
|
||||||
|
&FCB->ListenIrp.Iosb,
|
||||||
|
ListenComplete,
|
||||||
|
FCB );
|
||||||
|
}
|
||||||
|
FCB->NeedsNewListen = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( PendingConn = FCB->PendingConnections.Flink;
|
||||||
|
PendingConn != &FCB->PendingConnections;
|
||||||
|
PendingConn = PendingConn->Flink ) {
|
||||||
|
PAFD_TDI_OBJECT_QELT PendingConnObj =
|
||||||
|
CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry );
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Comparing Seq %d to Q %d\n",
|
||||||
|
AcceptData->SequenceNumber,
|
||||||
|
PendingConnObj->Seq));
|
||||||
|
|
||||||
|
if( PendingConnObj->Seq == AcceptData->SequenceNumber ) {
|
||||||
|
PFILE_OBJECT NewFileObject;
|
||||||
|
|
||||||
|
RemoveEntryList( PendingConn );
|
||||||
|
|
||||||
|
Status = ObReferenceObjectByHandle
|
||||||
|
( (HANDLE)AcceptData->ListenHandle,
|
||||||
|
FILE_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
KernelMode,
|
||||||
|
(PVOID *)&NewFileObject,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
/* We have a pending connection ... complete this irp right away */
|
||||||
|
SatisfyAccept( Irp, NewFileObject, PendingConnObj );
|
||||||
|
|
||||||
|
ObDereferenceObject( NewFileObject );
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
|
||||||
|
|
||||||
|
ExFreePool( PendingConnObj );
|
||||||
|
|
||||||
|
if( IsListEmpty( &FCB->PendingConnections ) )
|
||||||
|
FCB->PollState &= ~AFD_EVENT_ACCEPT;
|
||||||
|
|
||||||
|
SocketStateUnlock( FCB );
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketStateUnlock( FCB );
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: lock.c,v 1.7 2004/11/17 05:17:22 arty Exp $
|
/* $Id: lock.c,v 1.8 2004/12/25 21:30:17 arty Exp $
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/lock.c
|
* FILE: drivers/net/afd/afd/lock.c
|
||||||
|
@ -142,7 +142,8 @@ VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
for( i = 0; i < HandleCount; i++ ) {
|
for( i = 0; i < HandleCount; i++ ) {
|
||||||
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
if( HandleArray[i].Handle )
|
||||||
|
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
||||||
}
|
}
|
||||||
|
|
||||||
ExFreePool( HandleArray );
|
ExFreePool( HandleArray );
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: main.c,v 1.16 2004/12/11 14:59:31 navaraf Exp $
|
/* $Id: main.c,v 1.17 2004/12/25 21:30:17 arty Exp $
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/main.c
|
* FILE: drivers/net/afd/afd/main.c
|
||||||
|
@ -104,7 +104,8 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeListHead( &FCB->DatagramList );
|
InitializeListHead( &FCB->DatagramList );
|
||||||
|
InitializeListHead( &FCB->PendingConnections );
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB));
|
||||||
|
|
||||||
if( ConnectInfo ) {
|
if( ConnectInfo ) {
|
||||||
|
@ -252,7 +253,8 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
|
if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
|
||||||
Flags |= TDI_DISCONNECT_RELEASE;
|
Flags |= TDI_DISCONNECT_RELEASE;
|
||||||
if( DisReq->DisconnectType & AFD_DISCONNECT_RECV )
|
if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
|
||||||
|
DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
|
||||||
Flags |= TDI_DISCONNECT_ABORT;
|
Flags |= TDI_DISCONNECT_ABORT;
|
||||||
|
|
||||||
Status = TdiDisconnect( FCB->Connection.Object,
|
Status = TdiDisconnect( FCB->Connection.Object,
|
||||||
|
@ -349,12 +351,10 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
return AfdSetContext( DeviceObject, Irp, IrpSp );
|
return AfdSetContext( DeviceObject, Irp, IrpSp );
|
||||||
|
|
||||||
case IOCTL_AFD_WAIT_FOR_LISTEN:
|
case IOCTL_AFD_WAIT_FOR_LISTEN:
|
||||||
AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_WAIT_FOR_LISTEN\n"));
|
return AfdWaitForListen( DeviceObject, Irp, IrpSp );
|
||||||
break;
|
|
||||||
|
|
||||||
case IOCTL_AFD_ACCEPT:
|
case IOCTL_AFD_ACCEPT:
|
||||||
AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_ACCEPT\n"));
|
return AfdAccept( DeviceObject, Irp, IrpSp );
|
||||||
break;
|
|
||||||
|
|
||||||
case IOCTL_AFD_DISCONNECT:
|
case IOCTL_AFD_DISCONNECT:
|
||||||
return AfdDisconnect( DeviceObject, Irp, IrpSp );
|
return AfdDisconnect( DeviceObject, Irp, IrpSp );
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: select.c,v 1.8 2004/11/25 23:36:36 arty Exp $
|
/* $Id: select.c,v 1.9 2004/12/25 21:30:17 arty Exp $
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/select.c
|
* FILE: drivers/net/afd/afd/select.c
|
||||||
|
@ -42,12 +42,12 @@ VOID RemoveSelect( PAFD_ACTIVE_POLL Poll ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq,
|
VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq,
|
||||||
NTSTATUS Status, UINT Collected ) {
|
NTSTATUS Status ) {
|
||||||
PIRP Irp = Poll->Irp;
|
PIRP Irp = Poll->Irp;
|
||||||
AFD_DbgPrint(MID_TRACE,("Called (Status %x Events %d)\n",
|
AFD_DbgPrint(MID_TRACE,("Called (Status %x)\n", Status));
|
||||||
Status, Collected));
|
|
||||||
Poll->Irp->IoStatus.Status = Status;
|
Poll->Irp->IoStatus.Status = Status;
|
||||||
Poll->Irp->IoStatus.Information = Collected;
|
Poll->Irp->IoStatus.Information =
|
||||||
|
FIELD_OFFSET(AFD_POLL_INFO, Handles) + sizeof(AFD_HANDLE) * PollReq->HandleCount;
|
||||||
CopyBackStatus( PollReq->Handles,
|
CopyBackStatus( PollReq->Handles,
|
||||||
PollReq->HandleCount );
|
PollReq->HandleCount );
|
||||||
UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount );
|
UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount );
|
||||||
|
@ -77,7 +77,7 @@ VOID SelectTimeout( PKDPC Dpc,
|
||||||
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
||||||
|
|
||||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||||
SignalSocket( Poll, PollReq, STATUS_TIMEOUT, 0 );
|
SignalSocket( Poll, PollReq, STATUS_TIMEOUT );
|
||||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Timeout\n"));
|
AFD_DbgPrint(MID_TRACE,("Timeout\n"));
|
||||||
|
@ -100,7 +100,7 @@ VOID KillExclusiveSelects( PAFD_DEVICE_EXTENSION DeviceExt ) {
|
||||||
Irp = Poll->Irp;
|
Irp = Poll->Irp;
|
||||||
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
||||||
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
||||||
SignalSocket( Poll, PollReq, STATUS_CANCELLED, 0 );
|
SignalSocket( Poll, PollReq, STATUS_CANCELLED );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
if( !AFD_HANDLES(PollReq) ) {
|
if( !AFD_HANDLES(PollReq) ) {
|
||||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||||
Irp->IoStatus.Information = -1;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||||
return Irp->IoStatus.Status;
|
return Irp->IoStatus.Status;
|
||||||
}
|
}
|
||||||
|
@ -186,8 +186,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
if( Signalled ) {
|
if( Signalled ) {
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = Signalled;
|
SignalSocket( Poll, PollReq, Status );
|
||||||
SignalSocket( Poll, PollReq, Status, Signalled );
|
|
||||||
} else {
|
} else {
|
||||||
Status = STATUS_PENDING;
|
Status = STATUS_PENDING;
|
||||||
IoMarkIrpPending( Irp );
|
IoMarkIrpPending( Irp );
|
||||||
|
@ -344,7 +343,7 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
|
||||||
if( UpdatePollWithFCB( Poll, FileObject ) ) {
|
if( UpdatePollWithFCB( Poll, FileObject ) ) {
|
||||||
ThePollEnt = ThePollEnt->Flink;
|
ThePollEnt = ThePollEnt->Flink;
|
||||||
AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
|
AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
|
||||||
SignalSocket( Poll, PollReq, STATUS_SUCCESS, 1 );
|
SignalSocket( Poll, PollReq, STATUS_SUCCESS );
|
||||||
} else
|
} else
|
||||||
ThePollEnt = ThePollEnt->Flink;
|
ThePollEnt = ThePollEnt->Flink;
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,6 +369,7 @@ NTSTATUS TdiListen
|
||||||
( PIRP *Irp,
|
( PIRP *Irp,
|
||||||
PFILE_OBJECT ConnectionObject,
|
PFILE_OBJECT ConnectionObject,
|
||||||
PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
|
PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
|
||||||
|
PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo,
|
||||||
PIO_STATUS_BLOCK Iosb,
|
PIO_STATUS_BLOCK Iosb,
|
||||||
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||||
PVOID CompletionContext)
|
PVOID CompletionContext)
|
||||||
|
@ -412,7 +413,7 @@ NTSTATUS TdiListen
|
||||||
CompletionContext, /* Completion routine context */
|
CompletionContext, /* Completion routine context */
|
||||||
0, /* Flags */
|
0, /* Flags */
|
||||||
*RequestConnectionInfo, /* Request connection information */
|
*RequestConnectionInfo, /* Request connection information */
|
||||||
NULL /* ReturnConnectionInfo */); /* Return connection information */
|
*ReturnConnectionInfo); /* Return connection information */
|
||||||
|
|
||||||
Status = TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb);
|
Status = TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: afd.h,v 1.28 2004/12/13 21:20:38 arty Exp $
|
/* $Id: afd.h,v 1.29 2004/12/25 21:30:18 arty Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -51,8 +51,10 @@
|
||||||
#define FUNCTION_CONNECT 0
|
#define FUNCTION_CONNECT 0
|
||||||
#define FUNCTION_RECV 1
|
#define FUNCTION_RECV 1
|
||||||
#define FUNCTION_SEND 2
|
#define FUNCTION_SEND 2
|
||||||
#define FUNCTION_CLOSE 3
|
#define FUNCTION_PREACCEPT 3
|
||||||
#define MAX_FUNCTIONS 4
|
#define FUNCTION_ACCEPT 4
|
||||||
|
#define FUNCTION_CLOSE 5
|
||||||
|
#define MAX_FUNCTIONS 6
|
||||||
|
|
||||||
#define IN_FLIGHT_REQUESTS 3
|
#define IN_FLIGHT_REQUESTS 3
|
||||||
|
|
||||||
|
@ -102,10 +104,18 @@ typedef struct _AFD_TDI_OBJECT {
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
} AFD_TDI_OBJECT, *PAFD_TDI_OBJECT;
|
} AFD_TDI_OBJECT, *PAFD_TDI_OBJECT;
|
||||||
|
|
||||||
|
typedef struct _AFD_TDI_OBJECT_QELT {
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
UINT Seq;
|
||||||
|
PTDI_CONNECTION_INFORMATION ConnInfo;
|
||||||
|
AFD_TDI_OBJECT Object;
|
||||||
|
} AFD_TDI_OBJECT_QELT, *PAFD_TDI_OBJECT_QELT;
|
||||||
|
|
||||||
typedef struct _AFD_IN_FLIGHT_REQUEST {
|
typedef struct _AFD_IN_FLIGHT_REQUEST {
|
||||||
PIRP InFlightRequest;
|
PIRP InFlightRequest;
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
PTDI_CONNECTION_INFORMATION ConnectionInfo;
|
PTDI_CONNECTION_INFORMATION ConnectionCallInfo;
|
||||||
|
PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
|
||||||
} AFD_IN_FLIGHT_REQUEST, *PAFD_IN_FLIGHT_REQUEST;
|
} AFD_IN_FLIGHT_REQUEST, *PAFD_IN_FLIGHT_REQUEST;
|
||||||
|
|
||||||
typedef struct _AFD_DATA_WINDOW {
|
typedef struct _AFD_DATA_WINDOW {
|
||||||
|
@ -129,7 +139,8 @@ typedef struct _AFD_FCB {
|
||||||
KSPIN_LOCK SpinLock;
|
KSPIN_LOCK SpinLock;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PAFD_DEVICE_EXTENSION DeviceExt;
|
PAFD_DEVICE_EXTENSION DeviceExt;
|
||||||
BOOLEAN DelayedAccept;
|
BOOLEAN DelayedAccept, NeedsNewListen;
|
||||||
|
UINT ConnSeq;
|
||||||
PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
|
PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
|
||||||
PTDI_CONNECTION_INFORMATION AddressFrom;
|
PTDI_CONNECTION_INFORMATION AddressFrom;
|
||||||
AFD_TDI_OBJECT AddressFile, Connection;
|
AFD_TDI_OBJECT AddressFile, Connection;
|
||||||
|
@ -146,6 +157,7 @@ typedef struct _AFD_FCB {
|
||||||
UINT ContextSize;
|
UINT ContextSize;
|
||||||
LIST_ENTRY PendingIrpList[MAX_FUNCTIONS];
|
LIST_ENTRY PendingIrpList[MAX_FUNCTIONS];
|
||||||
LIST_ENTRY DatagramList;
|
LIST_ENTRY DatagramList;
|
||||||
|
LIST_ENTRY PendingConnections;
|
||||||
} AFD_FCB, *PAFD_FCB;
|
} AFD_FCB, *PAFD_FCB;
|
||||||
|
|
||||||
/* bind.c */
|
/* bind.c */
|
||||||
|
@ -157,6 +169,7 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
/* connect.c */
|
/* connect.c */
|
||||||
|
|
||||||
|
NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB );
|
||||||
NTSTATUS WarmSocketForConnection( PAFD_FCB FCB );
|
NTSTATUS WarmSocketForConnection( PAFD_FCB FCB );
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
@ -182,10 +195,15 @@ AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp );
|
PIO_STACK_LOCATION IrpSp );
|
||||||
|
|
||||||
/* listen.c */
|
/* listen.c */
|
||||||
|
NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp );
|
||||||
|
|
||||||
NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp);
|
PIO_STACK_LOCATION IrpSp);
|
||||||
|
|
||||||
|
NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp );
|
||||||
|
|
||||||
/* lock.c */
|
/* lock.c */
|
||||||
|
|
||||||
PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
|
PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
|
||||||
|
@ -261,6 +279,7 @@ NTSTATUS TdiListen
|
||||||
( PIRP *Irp,
|
( PIRP *Irp,
|
||||||
PFILE_OBJECT ConnectionObject,
|
PFILE_OBJECT ConnectionObject,
|
||||||
PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
|
PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
|
||||||
|
PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo,
|
||||||
PIO_STATUS_BLOCK Iosb,
|
PIO_STATUS_BLOCK Iosb,
|
||||||
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||||
PVOID CompletionContext);
|
PVOID CompletionContext);
|
||||||
|
|
|
@ -92,8 +92,8 @@ BOOLEAN LanShouldComplete( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) {
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
|
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("NDIS completed the same send packet twice "
|
DbgPrint("NDIS completed the same send packet twice "
|
||||||
"(Adapter %x Packet %x)!!\n", Adapter, NdisPacket));
|
"(Adapter %x Packet %x)!!\n", Adapter, NdisPacket);
|
||||||
#ifdef BREAK_ON_DOUBLE_COMPLETE
|
#ifdef BREAK_ON_DOUBLE_COMPLETE
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -356,7 +356,8 @@ VOID LanSubmitReceiveWork(
|
||||||
if( !LanReceiveWorkerBusy ) {
|
if( !LanReceiveWorkerBusy ) {
|
||||||
LanReceiveWorkerBusy = TRUE;
|
LanReceiveWorkerBusy = TRUE;
|
||||||
ExQueueWorkItem( &LanWorkItem, CriticalWorkQueue );
|
ExQueueWorkItem( &LanWorkItem, CriticalWorkQueue );
|
||||||
DbgPrint("Work item inserted %x %x\n", &LanWorkItem, WQItem);
|
TI_DbgPrint(DEBUG_DATALINK,
|
||||||
|
("Work item inserted %x %x\n", &LanWorkItem, WQItem));
|
||||||
} else {
|
} else {
|
||||||
DbgPrint("LAN WORKER BUSY %x %x\n", &LanWorkItem, WQItem);
|
DbgPrint("LAN WORKER BUSY %x %x\n", &LanWorkItem, WQItem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,21 @@ extern LIST_ENTRY SleepingThreadsList;
|
||||||
extern FAST_MUTEX SleepingThreadsLock;
|
extern FAST_MUTEX SleepingThreadsLock;
|
||||||
extern RECURSIVE_MUTEX TCPLock;
|
extern RECURSIVE_MUTEX TCPLock;
|
||||||
|
|
||||||
|
/* accept.c */
|
||||||
|
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
||||||
|
PCONNECTION_ENDPOINT Connection,
|
||||||
|
PTDI_REQUEST_KERNEL Request );
|
||||||
|
NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog );
|
||||||
|
VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
|
||||||
|
PCONNECTION_ENDPOINT Connection );
|
||||||
|
NTSTATUS TCPAccept
|
||||||
|
( PTDI_REQUEST Request,
|
||||||
|
PCONNECTION_ENDPOINT Listener,
|
||||||
|
PCONNECTION_ENDPOINT Connection,
|
||||||
|
PTCP_COMPLETION_ROUTINE Complete,
|
||||||
|
PVOID Context );
|
||||||
|
|
||||||
|
/* tcp.c */
|
||||||
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext );
|
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext );
|
||||||
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
|
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
|
||||||
|
|
||||||
|
@ -121,12 +136,6 @@ NTSTATUS TCPDisconnect(
|
||||||
PTCP_COMPLETION_ROUTINE Complete,
|
PTCP_COMPLETION_ROUTINE Complete,
|
||||||
PVOID Context);
|
PVOID Context);
|
||||||
|
|
||||||
NTSTATUS TCPListen(
|
|
||||||
PCONNECTION_ENDPOINT Connection,
|
|
||||||
UINT Backlog,
|
|
||||||
PTCP_COMPLETION_ROUTINE Complete,
|
|
||||||
PVOID Context);
|
|
||||||
|
|
||||||
NTSTATUS TCPReceiveData(
|
NTSTATUS TCPReceiveData(
|
||||||
PCONNECTION_ENDPOINT Connection,
|
PCONNECTION_ENDPOINT Connection,
|
||||||
PNDIS_BUFFER Buffer,
|
PNDIS_BUFFER Buffer,
|
||||||
|
|
|
@ -144,28 +144,6 @@ typedef struct _DATAGRAM_SEND_REQUEST {
|
||||||
ULONG Flags; /* Protocol specific flags */
|
ULONG Flags; /* Protocol specific flags */
|
||||||
} DATAGRAM_SEND_REQUEST, *PDATAGRAM_SEND_REQUEST;
|
} DATAGRAM_SEND_REQUEST, *PDATAGRAM_SEND_REQUEST;
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define InitializeDatagramSendRequest( \
|
|
||||||
_SendRequest, \
|
|
||||||
_RemoteAddress, \
|
|
||||||
_RemotePort, \
|
|
||||||
_Buffer, \
|
|
||||||
_BufferSize, \
|
|
||||||
_Complete, \
|
|
||||||
_Context, \
|
|
||||||
_Build, \
|
|
||||||
_Flags) { \
|
|
||||||
(_SendRequest)->RemoteAddress = (_RemoteAddress); \
|
|
||||||
(_SendRequest)->RemotePort = (_RemotePort); \
|
|
||||||
(_SendRequest)->Buffer = (_Buffer); \
|
|
||||||
(_SendRequest)->BufferSize = (_BufferSize); \
|
|
||||||
(_SendRequest)->Complete = (_Complete); \
|
|
||||||
(_SendRequest)->Context = (_Context); \
|
|
||||||
(_SendRequest)->Build = (_Build); \
|
|
||||||
(_SendRequest)->Flags = (_Flags); \
|
|
||||||
}
|
|
||||||
#endif /* These things bug me... They hide the member names. */
|
|
||||||
|
|
||||||
/* Transport address file context structure. The FileObject->FsContext2
|
/* Transport address file context structure. The FileObject->FsContext2
|
||||||
field holds a pointer to this structure */
|
field holds a pointer to this structure */
|
||||||
typedef struct _ADDRESS_FILE {
|
typedef struct _ADDRESS_FILE {
|
||||||
|
@ -175,6 +153,7 @@ typedef struct _ADDRESS_FILE {
|
||||||
OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */
|
OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */
|
||||||
USHORT Flags; /* Flags for address file (see below) */
|
USHORT Flags; /* Flags for address file (see below) */
|
||||||
IP_ADDRESS Address; /* Address of this address file */
|
IP_ADDRESS Address; /* Address of this address file */
|
||||||
|
USHORT Family; /* Address family */
|
||||||
USHORT Protocol; /* Protocol number */
|
USHORT Protocol; /* Protocol number */
|
||||||
USHORT Port; /* Network port (network byte order) */
|
USHORT Port; /* Network port (network byte order) */
|
||||||
WORK_QUEUE_ITEM WorkItem; /* Work queue item handle */
|
WORK_QUEUE_ITEM WorkItem; /* Work queue item handle */
|
||||||
|
@ -184,8 +163,9 @@ typedef struct _ADDRESS_FILE {
|
||||||
LIST_ENTRY ReceiveQueue; /* List of outstanding receive requests */
|
LIST_ENTRY ReceiveQueue; /* List of outstanding receive requests */
|
||||||
LIST_ENTRY TransmitQueue; /* List of outstanding transmit requests */
|
LIST_ENTRY TransmitQueue; /* List of outstanding transmit requests */
|
||||||
struct _CONNECTION_ENDPOINT *Connection;
|
struct _CONNECTION_ENDPOINT *Connection;
|
||||||
/* Associated connection or NULL if no
|
/* Associated connection or NULL if no associated connection exist */
|
||||||
associated connection exist */
|
struct _CONNECTION_ENDPOINT *Listener;
|
||||||
|
/* Associated listener (see transport/tcp/accept.c) */
|
||||||
IP_ADDRESS AddrCache; /* One entry address cache (destination
|
IP_ADDRESS AddrCache; /* One entry address cache (destination
|
||||||
address of last packet transmitted) */
|
address of last packet transmitted) */
|
||||||
|
|
||||||
|
@ -302,6 +282,7 @@ typedef struct _TCP_SEGMENT {
|
||||||
|
|
||||||
typedef struct _TDI_BUCKET {
|
typedef struct _TDI_BUCKET {
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
|
struct _CONNECTION_ENDPOINT *AssociatedEndpoint;
|
||||||
TDI_REQUEST Request;
|
TDI_REQUEST Request;
|
||||||
} TDI_BUCKET, *PTDI_BUCKET;
|
} TDI_BUCKET, *PTDI_BUCKET;
|
||||||
|
|
||||||
|
@ -316,7 +297,7 @@ typedef struct _CONNECTION_ENDPOINT {
|
||||||
PVOID SocketContext; /* Context for lower layer */
|
PVOID SocketContext; /* Context for lower layer */
|
||||||
|
|
||||||
UINT State; /* Socket state W.R.T. oskit */
|
UINT State; /* Socket state W.R.T. oskit */
|
||||||
|
|
||||||
/* Requests */
|
/* Requests */
|
||||||
LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */
|
LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */
|
||||||
LIST_ENTRY ListenRequest; /* Queued listen requests */
|
LIST_ENTRY ListenRequest; /* Queued listen requests */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.33 2004/12/03 23:37:40 blight Exp $
|
# $Id: makefile,v 1.34 2004/12/25 21:30:19 arty Exp $
|
||||||
|
|
||||||
PATH_TO_TOP = ../../..
|
PATH_TO_TOP = ../../..
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ TARGET_PCH = include/precomp.h
|
||||||
TARGET_CFLAGS = \
|
TARGET_CFLAGS = \
|
||||||
-D__USE_W32API \
|
-D__USE_W32API \
|
||||||
-D_SEH_NO_NATIVE_NLG \
|
-D_SEH_NO_NATIVE_NLG \
|
||||||
-DMEMTRACK \
|
|
||||||
-DNDIS40 \
|
-DNDIS40 \
|
||||||
-Wall -Werror \
|
-Wall -Werror \
|
||||||
-I./include \
|
-I./include \
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS TCP/IP protocol driver
|
* PROJECT: ReactOS TCP/IP protocol driver
|
||||||
|
@ -272,8 +271,8 @@ NTSTATUS DispTdiAssociateAddress(
|
||||||
(PVOID*)&FileObject,
|
(PVOID*)&FileObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status)) {
|
if (!NT_SUCCESS(Status)) {
|
||||||
TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X).\n",
|
TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X): %x.\n",
|
||||||
Parameters->AddressHandle));
|
Parameters->AddressHandle, Status));
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +464,7 @@ NTSTATUS DispTdiListen(
|
||||||
PTDI_REQUEST_KERNEL Parameters;
|
PTDI_REQUEST_KERNEL Parameters;
|
||||||
PTRANSPORT_CONTEXT TranContext;
|
PTRANSPORT_CONTEXT TranContext;
|
||||||
PIO_STACK_LOCATION IrpSp;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
|
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
|
||||||
|
|
||||||
|
@ -489,9 +488,50 @@ NTSTATUS DispTdiListen(
|
||||||
|
|
||||||
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
|
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
|
||||||
|
|
||||||
Status = TCPListen( Connection, 1024 /* BACKLOG */,
|
TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
|
||||||
DispDataRequestComplete,
|
Connection->AddressFile ));
|
||||||
Irp );
|
if( Connection->AddressFile ) {
|
||||||
|
TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile->Listener: %x\n",
|
||||||
|
Connection->AddressFile->Listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Listening will require us to create a listening socket and store it in
|
||||||
|
* the address file. It will be signalled, and attempt to complete an irp
|
||||||
|
* when a new connection arrives. */
|
||||||
|
/* The important thing to note here is that the irp we'll complete belongs
|
||||||
|
* to the socket to be accepted onto, not the listener */
|
||||||
|
if( !Connection->AddressFile->Listener ) {
|
||||||
|
Connection->AddressFile->Listener =
|
||||||
|
TCPAllocateConnectionEndpoint( NULL );
|
||||||
|
|
||||||
|
if( !Connection->AddressFile->Listener )
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
if( NT_SUCCESS(Status) ) {
|
||||||
|
Connection->AddressFile->Listener->AddressFile =
|
||||||
|
Connection->AddressFile;
|
||||||
|
|
||||||
|
Status = TCPSocket( Connection->AddressFile->Listener,
|
||||||
|
Connection->AddressFile->Family,
|
||||||
|
SOCK_STREAM,
|
||||||
|
Connection->AddressFile->Protocol );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( NT_SUCCESS(Status) )
|
||||||
|
Status = TCPListen( Connection->AddressFile->Listener, 1024 );
|
||||||
|
/* BACKLOG */
|
||||||
|
}
|
||||||
|
|
||||||
|
if( NT_SUCCESS(Status) ) {
|
||||||
|
Status = TCPAccept
|
||||||
|
( (PTDI_REQUEST)Parameters,
|
||||||
|
Connection->AddressFile->Listener,
|
||||||
|
Connection,
|
||||||
|
DispDataRequestComplete,
|
||||||
|
Irp );
|
||||||
|
}
|
||||||
|
|
||||||
|
TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status));
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,6 +249,7 @@ NTSTATUS FileOpenAddress(
|
||||||
/* Locate address entry. If specified address is 0, a random address is chosen */
|
/* Locate address entry. If specified address is 0, a random address is chosen */
|
||||||
|
|
||||||
/* FIXME: IPv4 only */
|
/* FIXME: IPv4 only */
|
||||||
|
AddrFile->Family = Address->Address[0].AddressType;
|
||||||
IPv4Address = Address->Address[0].Address[0].in_addr;
|
IPv4Address = Address->Address[0].Address[0].in_addr;
|
||||||
if (IPv4Address == 0)
|
if (IPv4Address == 0)
|
||||||
Matched = IPGetDefaultAddress(&AddrFile->Address);
|
Matched = IPGetDefaultAddress(&AddrFile->Address);
|
||||||
|
@ -351,6 +352,8 @@ NTSTATUS FileCloseAddress(
|
||||||
switch (AddrFile->Protocol) {
|
switch (AddrFile->Protocol) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
TCPFreePort( AddrFile->Port );
|
TCPFreePort( AddrFile->Port );
|
||||||
|
if( AddrFile->Listener )
|
||||||
|
TCPClose( AddrFile->Listener );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
*/
|
*/
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
#define NDEBUG
|
//#define NDEBUG
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DWORD DebugTraceLevel = DEBUG_ULTRA;
|
DWORD DebugTraceLevel = MAX_TRACE | DEBUG_TCP;
|
||||||
#else
|
#else
|
||||||
DWORD DebugTraceLevel = 0;
|
DWORD DebugTraceLevel = 0;
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
|
@ -480,6 +480,7 @@ TiDispatchInternal(
|
||||||
|
|
||||||
case TDI_LISTEN:
|
case TDI_LISTEN:
|
||||||
Status = DispTdiListen(Irp);
|
Status = DispTdiListen(Irp);
|
||||||
|
Complete = FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TDI_CONNECT:
|
case TDI_CONNECT:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue