mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +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 = ../../..
|
||||
|
||||
|
@ -11,7 +11,6 @@ TARGET_PCH = $(PATH_TO_TOP)/drivers/lib/ip/include/precomp.h
|
|||
# -DMEMTRACK
|
||||
TARGET_CFLAGS = \
|
||||
-D__USE_W32API \
|
||||
-DMEMTRACK \
|
||||
-D__NTDRIVER__ \
|
||||
-D_SEH_NO_NATIVE_NLG \
|
||||
-Wall -Werror \
|
||||
|
@ -40,6 +39,7 @@ TARGET_OBJECTS = \
|
|||
network/routines.o \
|
||||
network/transmit.o \
|
||||
transport/rawip/rawip.o \
|
||||
transport/tcp/accept.o \
|
||||
transport/tcp/event.o \
|
||||
transport/tcp/if.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 ) {
|
||||
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",
|
||||
NewState, Connection,
|
||||
Connection ? Connection->State ^ NewState :
|
||||
|
@ -33,6 +39,8 @@ int TCPSocketState(void *ClientData,
|
|||
TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
|
||||
}
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Connection signalled: %d\n",
|
||||
Connection->Signalled));
|
||||
if( !Connection->Signalled ) {
|
||||
Connection->Signalled = TRUE;
|
||||
Connection->SignalState = NewState;
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
* FILE: transport/tcp/tcp.c
|
||||
* PURPOSE: Transmission Control Protocol
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Art Yerkes (arty@users.sf.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/08-2000 Created
|
||||
* CSH 01/08-2000 Created
|
||||
* arty 12/21/2004 Added accept
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
@ -25,11 +27,11 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection,
|
|||
PTCP_COMPLETION_ROUTINE Complete;
|
||||
PTDI_BUCKET Bucket;
|
||||
PLIST_ENTRY Entry;
|
||||
BOOLEAN CompletedOne = FALSE;
|
||||
PIRP Irp;
|
||||
PMDL Mdl;
|
||||
|
||||
/* Things that can happen when we try the initial connection */
|
||||
if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) &&
|
||||
|
||||
!(Connection->State & (SEL_CONNECT | SEL_FIN)) ) {
|
||||
while( !IsListEmpty( &Connection->ConnectRequest ) ) {
|
||||
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 */
|
||||
if( (NewState & SEL_READ) ) {
|
||||
TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
|
||||
IsListEmpty(&Connection->ReceiveRequest) ?
|
||||
"empty" : "nonempty"));
|
||||
|
||||
|
||||
while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
|
||||
PIRP Irp;
|
||||
OSK_UINT RecvLen = 0, Received = 0;
|
||||
OSK_PCHAR RecvBuffer = 0;
|
||||
PMDL Mdl;
|
||||
NTSTATUS Status;
|
||||
|
||||
Entry = RemoveHeadList( &Connection->ReceiveRequest );
|
||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||
Complete = Bucket->Request.RequestNotifyObject;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,
|
||||
("Readable, Completing read request %x\n",
|
||||
Bucket->Request));
|
||||
|
||||
Irp = Bucket->Request.RequestContext;
|
||||
Mdl = Irp->MdlAddress;
|
||||
|
||||
|
@ -97,23 +128,17 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection,
|
|||
TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
|
||||
Received, Status));
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,
|
||||
("Completing Receive Request: %x\n",
|
||||
Bucket->Request));
|
||||
|
||||
Complete( Bucket->Request.RequestContext,
|
||||
STATUS_SUCCESS, Received );
|
||||
CompletedOne = TRUE;
|
||||
} else if( Status == STATUS_PENDING ) {
|
||||
InsertHeadList( &Connection->ReceiveRequest,
|
||||
&Bucket->Entry );
|
||||
InsertHeadList
|
||||
( &Connection->ReceiveRequest, &Bucket->Entry );
|
||||
break;
|
||||
} else {
|
||||
TI_DbgPrint(DEBUG_TCP,
|
||||
("Completing Receive request: %x %x\n",
|
||||
Bucket->Request, Status));
|
||||
Complete( Bucket->Request.RequestContext, Status, 0 );
|
||||
CompletedOne = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -491,59 +516,6 @@ NTSTATUS TCPClose
|
|||
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
|
||||
( PCONNECTION_ENDPOINT Connection,
|
||||
PNDIS_BUFFER Buffer,
|
||||
|
|
|
@ -133,6 +133,12 @@ extern int OskitTCPClose( void *socket );
|
|||
extern int OskitTCPBind( void *socket, void *connection,
|
||||
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 OskitTCPRecv( void *connection,
|
||||
|
|
|
@ -22,8 +22,8 @@ struct linker_set domain_set;
|
|||
|
||||
OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 };
|
||||
|
||||
//OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
|
||||
OSK_UINT OskitDebugTraceLevel = 0;
|
||||
OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
|
||||
//OSK_UINT OskitDebugTraceLevel = 0;
|
||||
|
||||
/* SPL */
|
||||
unsigned cpl;
|
||||
|
@ -119,6 +119,7 @@ int OskitTCPSocket( void *context,
|
|||
if( !error ) {
|
||||
so->so_connection = context;
|
||||
so->so_state = SS_NBIO;
|
||||
so->so_error = 0;
|
||||
*aso = so;
|
||||
}
|
||||
return error;
|
||||
|
@ -138,6 +139,8 @@ int OskitTCPRecv( void *connection,
|
|||
|
||||
*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_DONTWAIT ) tcp_flags |= MSG_DONTWAIT;
|
||||
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,
|
||||
void **new_socket,
|
||||
void *AddrOut,
|
||||
OSK_UINT AddrLen,
|
||||
OSK_UINT *OutAddrLen ) {
|
||||
struct mbuf nam;
|
||||
int error;
|
||||
OSK_UINT *OutAddrLen,
|
||||
OSK_UINT FinishAccepting ) {
|
||||
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;
|
||||
nam.m_len = AddrLen;
|
||||
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Doing accept (Finish %d)\n",
|
||||
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
|
||||
|
|
|
@ -20,12 +20,17 @@ void wakeup( struct socket *so, void *token ) {
|
|||
OSK_UINT flags = 0;
|
||||
|
||||
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 ) {
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Socket connected!\n"));
|
||||
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 ) {
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Socket readable\n"));
|
||||
flags |= SEL_READ;
|
||||
|
|
|
@ -330,7 +330,7 @@ m_copym(m, off0, len, wait)
|
|||
copyhdr = 1;
|
||||
while (off > 0) {
|
||||
if (m == 0)
|
||||
panic("m_copym");
|
||||
panic("m_copym: %d", off);
|
||||
if (off < m->m_len)
|
||||
break;
|
||||
off -= m->m_len;
|
||||
|
|
|
@ -608,6 +608,8 @@ restart:
|
|||
}
|
||||
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
|
||||
(so->so_proto->pr_flags & PR_CONNREQUIRED)) {
|
||||
printf("so: %x\n", so);
|
||||
__asm__("int3");
|
||||
error = ENOTCONN;
|
||||
goto release;
|
||||
}
|
||||
|
@ -774,7 +776,7 @@ dontblock:
|
|||
* Keep sockbuf locked against other readers.
|
||||
*/
|
||||
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)
|
||||
break;
|
||||
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
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/connect.c
|
||||
|
@ -40,12 +40,36 @@ NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
|
|||
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
|
||||
( PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp,
|
||||
PVOID Context ) {
|
||||
NTSTATUS Status = Irp->IoStatus.Status;
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||
PLIST_ENTRY NextIrpEntry;
|
||||
PIRP NextIrp;
|
||||
|
@ -83,22 +107,7 @@ NTSTATUS DDKAPI StreamSocketConnectComplete
|
|||
}
|
||||
|
||||
if( NT_SUCCESS(Status) ) {
|
||||
/* Allocate the receive area and start receiving */
|
||||
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 );
|
||||
}
|
||||
Status = MakeSocketIntoConnection( FCB );
|
||||
|
||||
if( FCB->Send.Window &&
|
||||
!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
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/listen.c
|
||||
|
@ -12,12 +12,54 @@
|
|||
#include "tdiconn.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
|
||||
( PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp,
|
||||
PVOID Context ) {
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||
PAFD_TDI_OBJECT_QELT Qelt;
|
||||
|
||||
if( !SocketAcquireStateLock( FCB ) ) return Status;
|
||||
|
||||
|
@ -31,7 +73,39 @@ NTSTATUS DDKAPI ListenComplete
|
|||
|
||||
AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
|
||||
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 );
|
||||
|
||||
|
@ -61,17 +135,140 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
|
||||
FCB->DelayedAccept = ListenReq->UseDelayedAcceptance;
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle));
|
||||
|
||||
Status = WarmSocketForConnection( FCB );
|
||||
|
||||
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,
|
||||
FCB->Connection.Object,
|
||||
&FCB->ListenIrp.ConnectionInfo,
|
||||
&FCB->ListenIrp.ConnectionCallInfo,
|
||||
&FCB->ListenIrp.ConnectionReturnInfo,
|
||||
&FCB->ListenIrp.Iosb,
|
||||
ListenComplete,
|
||||
FCB );
|
||||
|
||||
if( NT_SUCCESS(Status) || Status == STATUS_PENDING )
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
||||
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
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/lock.c
|
||||
|
@ -142,7 +142,8 @@ VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
|
|||
UINT i;
|
||||
|
||||
for( i = 0; i < HandleCount; i++ ) {
|
||||
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
||||
if( HandleArray[i].Handle )
|
||||
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
||||
}
|
||||
|
||||
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
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/main.c
|
||||
|
@ -104,7 +104,8 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
}
|
||||
|
||||
InitializeListHead( &FCB->DatagramList );
|
||||
|
||||
InitializeListHead( &FCB->PendingConnections );
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB));
|
||||
|
||||
if( ConnectInfo ) {
|
||||
|
@ -252,7 +253,8 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
|
||||
if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
|
||||
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;
|
||||
|
||||
Status = TdiDisconnect( FCB->Connection.Object,
|
||||
|
@ -349,12 +351,10 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
return AfdSetContext( DeviceObject, Irp, IrpSp );
|
||||
|
||||
case IOCTL_AFD_WAIT_FOR_LISTEN:
|
||||
AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_WAIT_FOR_LISTEN\n"));
|
||||
break;
|
||||
return AfdWaitForListen( DeviceObject, Irp, IrpSp );
|
||||
|
||||
case IOCTL_AFD_ACCEPT:
|
||||
AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_ACCEPT\n"));
|
||||
break;
|
||||
return AfdAccept( DeviceObject, Irp, IrpSp );
|
||||
|
||||
case IOCTL_AFD_DISCONNECT:
|
||||
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
|
||||
* PROJECT: ReactOS kernel
|
||||
* 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,
|
||||
NTSTATUS Status, UINT Collected ) {
|
||||
NTSTATUS Status ) {
|
||||
PIRP Irp = Poll->Irp;
|
||||
AFD_DbgPrint(MID_TRACE,("Called (Status %x Events %d)\n",
|
||||
Status, Collected));
|
||||
AFD_DbgPrint(MID_TRACE,("Called (Status %x)\n", 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,
|
||||
PollReq->HandleCount );
|
||||
UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount );
|
||||
|
@ -77,7 +77,7 @@ VOID SelectTimeout( PKDPC Dpc,
|
|||
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
||||
|
||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||
SignalSocket( Poll, PollReq, STATUS_TIMEOUT, 0 );
|
||||
SignalSocket( Poll, PollReq, STATUS_TIMEOUT );
|
||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Timeout\n"));
|
||||
|
@ -100,7 +100,7 @@ VOID KillExclusiveSelects( PAFD_DEVICE_EXTENSION DeviceExt ) {
|
|||
Irp = Poll->Irp;
|
||||
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
||||
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) ) {
|
||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||
Irp->IoStatus.Information = -1;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||
return Irp->IoStatus.Status;
|
||||
}
|
||||
|
@ -186,8 +186,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
if( Signalled ) {
|
||||
Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Signalled;
|
||||
SignalSocket( Poll, PollReq, Status, Signalled );
|
||||
SignalSocket( Poll, PollReq, Status );
|
||||
} else {
|
||||
Status = STATUS_PENDING;
|
||||
IoMarkIrpPending( Irp );
|
||||
|
@ -344,7 +343,7 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
|
|||
if( UpdatePollWithFCB( Poll, FileObject ) ) {
|
||||
ThePollEnt = ThePollEnt->Flink;
|
||||
AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
|
||||
SignalSocket( Poll, PollReq, STATUS_SUCCESS, 1 );
|
||||
SignalSocket( Poll, PollReq, STATUS_SUCCESS );
|
||||
} else
|
||||
ThePollEnt = ThePollEnt->Flink;
|
||||
}
|
||||
|
|
|
@ -369,6 +369,7 @@ NTSTATUS TdiListen
|
|||
( PIRP *Irp,
|
||||
PFILE_OBJECT ConnectionObject,
|
||||
PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
|
||||
PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo,
|
||||
PIO_STATUS_BLOCK Iosb,
|
||||
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||
PVOID CompletionContext)
|
||||
|
@ -412,7 +413,7 @@ NTSTATUS TdiListen
|
|||
CompletionContext, /* Completion routine context */
|
||||
0, /* Flags */
|
||||
*RequestConnectionInfo, /* Request connection information */
|
||||
NULL /* ReturnConnectionInfo */); /* Return connection information */
|
||||
*ReturnConnectionInfo); /* Return connection information */
|
||||
|
||||
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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -51,8 +51,10 @@
|
|||
#define FUNCTION_CONNECT 0
|
||||
#define FUNCTION_RECV 1
|
||||
#define FUNCTION_SEND 2
|
||||
#define FUNCTION_CLOSE 3
|
||||
#define MAX_FUNCTIONS 4
|
||||
#define FUNCTION_PREACCEPT 3
|
||||
#define FUNCTION_ACCEPT 4
|
||||
#define FUNCTION_CLOSE 5
|
||||
#define MAX_FUNCTIONS 6
|
||||
|
||||
#define IN_FLIGHT_REQUESTS 3
|
||||
|
||||
|
@ -102,10 +104,18 @@ typedef struct _AFD_TDI_OBJECT {
|
|||
HANDLE Handle;
|
||||
} 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 {
|
||||
PIRP InFlightRequest;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
PTDI_CONNECTION_INFORMATION ConnectionInfo;
|
||||
PTDI_CONNECTION_INFORMATION ConnectionCallInfo;
|
||||
PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
|
||||
} AFD_IN_FLIGHT_REQUEST, *PAFD_IN_FLIGHT_REQUEST;
|
||||
|
||||
typedef struct _AFD_DATA_WINDOW {
|
||||
|
@ -129,7 +139,8 @@ typedef struct _AFD_FCB {
|
|||
KSPIN_LOCK SpinLock;
|
||||
PFILE_OBJECT FileObject;
|
||||
PAFD_DEVICE_EXTENSION DeviceExt;
|
||||
BOOLEAN DelayedAccept;
|
||||
BOOLEAN DelayedAccept, NeedsNewListen;
|
||||
UINT ConnSeq;
|
||||
PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
|
||||
PTDI_CONNECTION_INFORMATION AddressFrom;
|
||||
AFD_TDI_OBJECT AddressFile, Connection;
|
||||
|
@ -146,6 +157,7 @@ typedef struct _AFD_FCB {
|
|||
UINT ContextSize;
|
||||
LIST_ENTRY PendingIrpList[MAX_FUNCTIONS];
|
||||
LIST_ENTRY DatagramList;
|
||||
LIST_ENTRY PendingConnections;
|
||||
} AFD_FCB, *PAFD_FCB;
|
||||
|
||||
/* bind.c */
|
||||
|
@ -157,6 +169,7 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
|
||||
/* connect.c */
|
||||
|
||||
NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB );
|
||||
NTSTATUS WarmSocketForConnection( PAFD_FCB FCB );
|
||||
NTSTATUS STDCALL
|
||||
AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||
|
@ -182,10 +195,15 @@ AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
PIO_STACK_LOCATION IrpSp );
|
||||
|
||||
/* listen.c */
|
||||
NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp );
|
||||
|
||||
NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp);
|
||||
|
||||
NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp );
|
||||
|
||||
/* lock.c */
|
||||
|
||||
PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
|
||||
|
@ -261,6 +279,7 @@ NTSTATUS TdiListen
|
|||
( PIRP *Irp,
|
||||
PFILE_OBJECT ConnectionObject,
|
||||
PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
|
||||
PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo,
|
||||
PIO_STATUS_BLOCK Iosb,
|
||||
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||
PVOID CompletionContext);
|
||||
|
|
|
@ -92,8 +92,8 @@ BOOLEAN LanShouldComplete( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) {
|
|||
}
|
||||
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("NDIS completed the same send packet twice "
|
||||
"(Adapter %x Packet %x)!!\n", Adapter, NdisPacket));
|
||||
DbgPrint("NDIS completed the same send packet twice "
|
||||
"(Adapter %x Packet %x)!!\n", Adapter, NdisPacket);
|
||||
#ifdef BREAK_ON_DOUBLE_COMPLETE
|
||||
KeBugCheck(0);
|
||||
#endif
|
||||
|
@ -356,7 +356,8 @@ VOID LanSubmitReceiveWork(
|
|||
if( !LanReceiveWorkerBusy ) {
|
||||
LanReceiveWorkerBusy = TRUE;
|
||||
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 {
|
||||
DbgPrint("LAN WORKER BUSY %x %x\n", &LanWorkItem, WQItem);
|
||||
}
|
||||
|
|
|
@ -87,6 +87,21 @@ extern LIST_ENTRY SleepingThreadsList;
|
|||
extern FAST_MUTEX SleepingThreadsLock;
|
||||
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 );
|
||||
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
|
||||
|
||||
|
@ -121,12 +136,6 @@ NTSTATUS TCPDisconnect(
|
|||
PTCP_COMPLETION_ROUTINE Complete,
|
||||
PVOID Context);
|
||||
|
||||
NTSTATUS TCPListen(
|
||||
PCONNECTION_ENDPOINT Connection,
|
||||
UINT Backlog,
|
||||
PTCP_COMPLETION_ROUTINE Complete,
|
||||
PVOID Context);
|
||||
|
||||
NTSTATUS TCPReceiveData(
|
||||
PCONNECTION_ENDPOINT Connection,
|
||||
PNDIS_BUFFER Buffer,
|
||||
|
|
|
@ -144,28 +144,6 @@ typedef struct _DATAGRAM_SEND_REQUEST {
|
|||
ULONG Flags; /* Protocol specific flags */
|
||||
} 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
|
||||
field holds a pointer to this structure */
|
||||
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 */
|
||||
USHORT Flags; /* Flags for address file (see below) */
|
||||
IP_ADDRESS Address; /* Address of this address file */
|
||||
USHORT Family; /* Address family */
|
||||
USHORT Protocol; /* Protocol number */
|
||||
USHORT Port; /* Network port (network byte order) */
|
||||
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 TransmitQueue; /* List of outstanding transmit requests */
|
||||
struct _CONNECTION_ENDPOINT *Connection;
|
||||
/* Associated connection or NULL if no
|
||||
associated connection exist */
|
||||
/* Associated connection or NULL if no associated connection exist */
|
||||
struct _CONNECTION_ENDPOINT *Listener;
|
||||
/* Associated listener (see transport/tcp/accept.c) */
|
||||
IP_ADDRESS AddrCache; /* One entry address cache (destination
|
||||
address of last packet transmitted) */
|
||||
|
||||
|
@ -302,6 +282,7 @@ typedef struct _TCP_SEGMENT {
|
|||
|
||||
typedef struct _TDI_BUCKET {
|
||||
LIST_ENTRY Entry;
|
||||
struct _CONNECTION_ENDPOINT *AssociatedEndpoint;
|
||||
TDI_REQUEST Request;
|
||||
} TDI_BUCKET, *PTDI_BUCKET;
|
||||
|
||||
|
@ -316,7 +297,7 @@ typedef struct _CONNECTION_ENDPOINT {
|
|||
PVOID SocketContext; /* Context for lower layer */
|
||||
|
||||
UINT State; /* Socket state W.R.T. oskit */
|
||||
|
||||
|
||||
/* Requests */
|
||||
LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */
|
||||
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 = ../../..
|
||||
|
||||
|
@ -14,7 +14,6 @@ TARGET_PCH = include/precomp.h
|
|||
TARGET_CFLAGS = \
|
||||
-D__USE_W32API \
|
||||
-D_SEH_NO_NATIVE_NLG \
|
||||
-DMEMTRACK \
|
||||
-DNDIS40 \
|
||||
-Wall -Werror \
|
||||
-I./include \
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS TCP/IP protocol driver
|
||||
|
@ -272,8 +271,8 @@ NTSTATUS DispTdiAssociateAddress(
|
|||
(PVOID*)&FileObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X).\n",
|
||||
Parameters->AddressHandle));
|
||||
TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X): %x.\n",
|
||||
Parameters->AddressHandle, Status));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -465,7 +464,7 @@ NTSTATUS DispTdiListen(
|
|||
PTDI_REQUEST_KERNEL Parameters;
|
||||
PTRANSPORT_CONTEXT TranContext;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
|
||||
|
||||
|
@ -489,9 +488,50 @@ NTSTATUS DispTdiListen(
|
|||
|
||||
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
|
||||
|
||||
Status = TCPListen( Connection, 1024 /* BACKLOG */,
|
||||
DispDataRequestComplete,
|
||||
Irp );
|
||||
TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
|
||||
Connection->AddressFile ));
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -249,6 +249,7 @@ NTSTATUS FileOpenAddress(
|
|||
/* Locate address entry. If specified address is 0, a random address is chosen */
|
||||
|
||||
/* FIXME: IPv4 only */
|
||||
AddrFile->Family = Address->Address[0].AddressType;
|
||||
IPv4Address = Address->Address[0].Address[0].in_addr;
|
||||
if (IPv4Address == 0)
|
||||
Matched = IPGetDefaultAddress(&AddrFile->Address);
|
||||
|
@ -351,6 +352,8 @@ NTSTATUS FileCloseAddress(
|
|||
switch (AddrFile->Protocol) {
|
||||
case IPPROTO_TCP:
|
||||
TCPFreePort( AddrFile->Port );
|
||||
if( AddrFile->Listener )
|
||||
TCPClose( AddrFile->Listener );
|
||||
break;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
*/
|
||||
#include "precomp.h"
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
|
||||
#ifndef NDEBUG
|
||||
DWORD DebugTraceLevel = DEBUG_ULTRA;
|
||||
DWORD DebugTraceLevel = MAX_TRACE | DEBUG_TCP;
|
||||
#else
|
||||
DWORD DebugTraceLevel = 0;
|
||||
#endif /* NDEBUG */
|
||||
|
@ -480,6 +480,7 @@ TiDispatchInternal(
|
|||
|
||||
case TDI_LISTEN:
|
||||
Status = DispTdiListen(Irp);
|
||||
Complete = FALSE;
|
||||
break;
|
||||
|
||||
case TDI_CONNECT:
|
||||
|
|
Loading…
Reference in a new issue