mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:56:31 +00:00
- Use a spin lock to protect OSKit instead of a recursive mutex
- Remove the now unused recursive mutex code - Don't clear the SS_ISCONNECTING flag when soconnect returns EINPROGRESS because it causes a crash during soreceive - Lock CONNECTION_ENDPOINT and ADDRESS_FILE structs better - Remove incorrect IoMarkIrpPending calls - Remove useless ASSERT_LOCKED - Don't destroy so_connection when we close a connection - Remove useless FileFindConnectionByContext - Remove SignalledConnectionsList and SignalledConnectionsLock and simply loop through ConnectionEndpointList for signalled connections - Add connections to ConnectionEndpointList in TCPAllocateConnectionEndpoint instead of FileOpenConnection so we don't miss listeners - Remove connections from ConnectionEndpointList in TCPFreeConnectionEndpoint instead of FileCloseConnection so we don't miss listeners - Use ExInterlockedRemoveHeadList to remove entries in the address file's request lists - Remove useless members, flags, and variables in titypes.h and tcp.h - Fixes bug 4955 and 4434 svn path=/trunk/; revision=44163
This commit is contained in:
parent
283fdbd510
commit
f3d4211e56
18 changed files with 566 additions and 709 deletions
|
@ -13,7 +13,6 @@ extern KSPIN_LOCK AddressFileListLock;
|
||||||
extern LIST_ENTRY ConnectionEndpointListHead;
|
extern LIST_ENTRY ConnectionEndpointListHead;
|
||||||
extern KSPIN_LOCK ConnectionEndpointListLock;
|
extern KSPIN_LOCK ConnectionEndpointListLock;
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS FileOpenAddress(
|
NTSTATUS FileOpenAddress(
|
||||||
PTDI_REQUEST Request,
|
PTDI_REQUEST Request,
|
||||||
PTA_IP_ADDRESS AddrList,
|
PTA_IP_ADDRESS AddrList,
|
||||||
|
@ -27,8 +26,6 @@ NTSTATUS FileOpenConnection(
|
||||||
PTDI_REQUEST Request,
|
PTDI_REQUEST Request,
|
||||||
PVOID ClientContext);
|
PVOID ClientContext);
|
||||||
|
|
||||||
PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context );
|
|
||||||
|
|
||||||
NTSTATUS FileCloseConnection(
|
NTSTATUS FileCloseConnection(
|
||||||
PTDI_REQUEST Request);
|
PTDI_REQUEST Request);
|
||||||
|
|
||||||
|
|
|
@ -84,11 +84,6 @@ typedef struct _SLEEPING_THREAD {
|
||||||
#define SRF_FIN TCP_FIN
|
#define SRF_FIN TCP_FIN
|
||||||
|
|
||||||
extern LONG TCP_IPIdentification;
|
extern LONG TCP_IPIdentification;
|
||||||
extern LIST_ENTRY SignalledConnectionsList;
|
|
||||||
extern KSPIN_LOCK SignalledConnectionsLock;
|
|
||||||
extern LIST_ENTRY SleepingThreadsList;
|
|
||||||
extern FAST_MUTEX SleepingThreadsLock;
|
|
||||||
extern RECURSIVE_MUTEX TCPLock;
|
|
||||||
|
|
||||||
/* accept.c */
|
/* accept.c */
|
||||||
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
||||||
|
@ -105,7 +100,6 @@ NTSTATUS TCPAccept
|
||||||
PVOID Context );
|
PVOID Context );
|
||||||
|
|
||||||
/* tcp.c */
|
/* tcp.c */
|
||||||
ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection );
|
|
||||||
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext );
|
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext );
|
||||||
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
|
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,6 @@ typedef struct _ADDRESS_FILE {
|
||||||
LIST_ENTRY ListEntry; /* Entry on list */
|
LIST_ENTRY ListEntry; /* Entry on list */
|
||||||
KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */
|
KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */
|
||||||
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) */
|
|
||||||
IP_ADDRESS Address; /* Address of this address file */
|
IP_ADDRESS Address; /* Address of this address file */
|
||||||
USHORT Family; /* Address family */
|
USHORT Family; /* Address family */
|
||||||
USHORT Protocol; /* Protocol number */
|
USHORT Protocol; /* Protocol number */
|
||||||
|
@ -213,29 +212,6 @@ typedef struct _ADDRESS_FILE {
|
||||||
BOOLEAN RegisteredChainedReceiveExpeditedHandler;
|
BOOLEAN RegisteredChainedReceiveExpeditedHandler;
|
||||||
} ADDRESS_FILE, *PADDRESS_FILE;
|
} ADDRESS_FILE, *PADDRESS_FILE;
|
||||||
|
|
||||||
/* Address File Flag constants */
|
|
||||||
#define AFF_VALID 0x0001 /* Address file object is valid for use */
|
|
||||||
#define AFF_BUSY 0x0002 /* Address file object is exclusive to someone */
|
|
||||||
#define AFF_DELETE 0x0004 /* Address file object is sheduled to be deleted */
|
|
||||||
#define AFF_SEND 0x0008 /* A send request is pending */
|
|
||||||
#define AFF_RECEIVE 0x0010 /* A receive request is pending */
|
|
||||||
#define AFF_PENDING 0x001C /* A request is pending */
|
|
||||||
|
|
||||||
/* Macros for manipulating address file object flags */
|
|
||||||
|
|
||||||
#define AF_IS_VALID(ADF) ((ADF)->Flags & AFF_VALID)
|
|
||||||
#define AF_SET_VALID(ADF) ((ADF)->Flags |= AFF_VALID)
|
|
||||||
#define AF_CLR_VALID(ADF) ((ADF)->Flags &= ~AFF_VALID)
|
|
||||||
|
|
||||||
#define AF_IS_BUSY(ADF) ((ADF)->Flags & AFF_BUSY)
|
|
||||||
#define AF_SET_BUSY(ADF) ((ADF)->Flags |= AFF_BUSY)
|
|
||||||
#define AF_CLR_BUSY(ADF) ((ADF)->Flags &= ~AFF_BUSY)
|
|
||||||
|
|
||||||
#define AF_IS_PENDING(ADF, X) (ADF->Flags & X)
|
|
||||||
#define AF_SET_PENDING(ADF, X) (ADF->Flags |= X)
|
|
||||||
#define AF_CLR_PENDING(ADF, X) (ADF->Flags &= ~X)
|
|
||||||
|
|
||||||
|
|
||||||
/* Structure used to search through Address Files */
|
/* Structure used to search through Address Files */
|
||||||
typedef struct _AF_SEARCH {
|
typedef struct _AF_SEARCH {
|
||||||
PLIST_ENTRY Next; /* Next address file to check */
|
PLIST_ENTRY Next; /* Next address file to check */
|
||||||
|
@ -306,8 +282,6 @@ typedef struct _CONNECTION_ENDPOINT {
|
||||||
LIST_ENTRY SendRequest; /* Queued send requests */
|
LIST_ENTRY SendRequest; /* Queued send requests */
|
||||||
|
|
||||||
/* Signals */
|
/* Signals */
|
||||||
LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for
|
|
||||||
* notification service to the client */
|
|
||||||
UINT SignalState; /* Active signals from oskit */
|
UINT SignalState; /* Active signals from oskit */
|
||||||
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
|
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
|
||||||
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
#include <ntddk.h>
|
|
||||||
#include "recmutex.h"
|
|
||||||
|
|
||||||
VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
RtlZeroMemory( RecMutex, sizeof(*RecMutex) );
|
|
||||||
ExInitializeFastMutex( &RecMutex->Mutex );
|
|
||||||
KeInitializeEvent( &RecMutex->StateLockedEvent,
|
|
||||||
NotificationEvent, FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE: When we leave, the FAST_MUTEX must have been released. The result
|
|
||||||
* is that we always exit in the same irql as entering */
|
|
||||||
VOID RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
PVOID CurrentThread = KeGetCurrentThread();
|
|
||||||
|
|
||||||
ASSERT(RecMutex);
|
|
||||||
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
|
|
||||||
|
|
||||||
/* Wait for the previous user to unlock the RecMutex state. There might be
|
|
||||||
* multiple waiters waiting to change the state. We need to check each
|
|
||||||
* time we get the event whether somebody still has the state locked */
|
|
||||||
|
|
||||||
ExAcquireFastMutex( &RecMutex->Mutex );
|
|
||||||
|
|
||||||
if( CurrentThread == RecMutex->CurrentThread ) {
|
|
||||||
RecMutex->LockCount++;
|
|
||||||
ExReleaseFastMutex( &RecMutex->Mutex );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while( RecMutex->LockCount != 0 ) {
|
|
||||||
ExReleaseFastMutex( &RecMutex->Mutex );
|
|
||||||
Status = KeWaitForSingleObject( &RecMutex->StateLockedEvent,
|
|
||||||
UserRequest,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL );
|
|
||||||
ExAcquireFastMutex( &RecMutex->Mutex );
|
|
||||||
}
|
|
||||||
RecMutex->CurrentThread = CurrentThread;
|
|
||||||
RecMutex->LockCount++;
|
|
||||||
ExReleaseFastMutex( &RecMutex->Mutex );
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
ASSERT(RecMutex);
|
|
||||||
|
|
||||||
ExAcquireFastMutex( &RecMutex->Mutex );
|
|
||||||
|
|
||||||
ASSERT(RecMutex->LockCount > 0);
|
|
||||||
RecMutex->LockCount--;
|
|
||||||
|
|
||||||
if( !RecMutex->LockCount ) {
|
|
||||||
KePulseEvent( &RecMutex->StateLockedEvent, IO_NETWORK_INCREMENT,
|
|
||||||
FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
ExReleaseFastMutex( &RecMutex->Mutex );
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#ifndef _ROSRTL_RECMUTEX_H
|
|
||||||
#define _ROSRTL_RECMUTEX_H
|
|
||||||
|
|
||||||
typedef struct _RECURSIVE_MUTEX {
|
|
||||||
/* Lock. */
|
|
||||||
FAST_MUTEX Mutex;
|
|
||||||
/* Number of times this object was locked */
|
|
||||||
SIZE_T LockCount;
|
|
||||||
/* CurrentThread */
|
|
||||||
PVOID CurrentThread;
|
|
||||||
/* Notification event which signals that another thread can take over */
|
|
||||||
KEVENT StateLockedEvent;
|
|
||||||
} RECURSIVE_MUTEX, *PRECURSIVE_MUTEX;
|
|
||||||
|
|
||||||
extern VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex );
|
|
||||||
extern VOID RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex );
|
|
||||||
extern VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex );
|
|
||||||
|
|
||||||
#define ASSERT_LOCKED(x)
|
|
||||||
|
|
||||||
#endif/*_ROSRTL_RECMUTEX_H*/
|
|
|
@ -21,9 +21,6 @@
|
||||||
<directory name="datalink">
|
<directory name="datalink">
|
||||||
<file>lan.c</file>
|
<file>lan.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
<directory name="recmutex">
|
|
||||||
<file>recmutex.c</file>
|
|
||||||
</directory>
|
|
||||||
<directory name="tcpip">
|
<directory name="tcpip">
|
||||||
<file>ainfo.c</file>
|
<file>ainfo.c</file>
|
||||||
<file>buffer.c</file>
|
<file>buffer.c</file>
|
||||||
|
|
|
@ -210,9 +210,8 @@ VOID NTAPI DispCancelListenRequest(
|
||||||
|
|
||||||
TCPRemoveIRP(Connection, Irp);
|
TCPRemoveIRP(Connection, Irp);
|
||||||
|
|
||||||
TCPAbortListenForSocket(
|
TCPAbortListenForSocket(Connection->AddressFile->Listener,
|
||||||
Connection->AddressFile->Listener,
|
Connection);
|
||||||
Connection );
|
|
||||||
|
|
||||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||||
|
|
||||||
|
@ -1044,7 +1043,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
|
||||||
Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
|
Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||||
|
|
||||||
/* Set the event handler. if an event handler is associated with
|
/* Set the event handler. if an event handler is associated with
|
||||||
a specific event, it's flag (RegisteredXxxHandler) is TRUE.
|
a specific event, it's flag (RegisteredXxxHandler) is TRUE.
|
||||||
|
@ -1165,7 +1164,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,9 +295,6 @@ NTSTATUS FileOpenAddress(
|
||||||
/* Initialize spin lock that protects the address file object */
|
/* Initialize spin lock that protects the address file object */
|
||||||
KeInitializeSpinLock(&AddrFile->Lock);
|
KeInitializeSpinLock(&AddrFile->Lock);
|
||||||
|
|
||||||
/* Set valid flag so the address can be used */
|
|
||||||
AF_SET_VALID(AddrFile);
|
|
||||||
|
|
||||||
/* Return address file object */
|
/* Return address file object */
|
||||||
Request->Handle.AddressHandle = AddrFile;
|
Request->Handle.AddressHandle = AddrFile;
|
||||||
|
|
||||||
|
@ -328,7 +325,7 @@ NTSTATUS FileCloseAddress(
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
|
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
|
||||||
PDATAGRAM_SEND_REQUEST SendRequest;
|
PDATAGRAM_SEND_REQUEST SendRequest;
|
||||||
PLIST_ENTRY CurrentEntry, NextEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
|
||||||
AddrFile = Request->Handle.AddressHandle;
|
AddrFile = Request->Handle.AddressHandle;
|
||||||
|
|
||||||
|
@ -339,8 +336,6 @@ NTSTATUS FileCloseAddress(
|
||||||
RemoveEntryList(&AddrFile->ListEntry);
|
RemoveEntryList(&AddrFile->ListEntry);
|
||||||
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
|
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
|
||||||
|
|
||||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
|
||||||
|
|
||||||
/* FIXME: Kill TCP connections on this address file object */
|
/* FIXME: Kill TCP connections on this address file object */
|
||||||
|
|
||||||
/* Return pending requests with error */
|
/* Return pending requests with error */
|
||||||
|
@ -348,43 +343,27 @@ NTSTATUS FileCloseAddress(
|
||||||
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
|
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
|
||||||
|
|
||||||
/* Go through pending receive request list and cancel them all */
|
/* Go through pending receive request list and cancel them all */
|
||||||
CurrentEntry = AddrFile->ReceiveQueue.Flink;
|
while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
|
||||||
while (CurrentEntry != &AddrFile->ReceiveQueue) {
|
|
||||||
NextEntry = CurrentEntry->Flink;
|
|
||||||
ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
|
ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
|
||||||
/* Abort the request and free its resources */
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
|
||||||
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0);
|
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0);
|
||||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
/* exFreePool(ReceiveRequest); FIXME: WTF? */
|
||||||
CurrentEntry = NextEntry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
|
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
|
||||||
|
|
||||||
/* Go through pending send request list and cancel them all */
|
/* Go through pending send request list and cancel them all */
|
||||||
CurrentEntry = AddrFile->TransmitQueue.Flink;
|
while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
|
||||||
while (CurrentEntry != &AddrFile->TransmitQueue) {
|
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
|
||||||
NextEntry = CurrentEntry->Flink;
|
|
||||||
SendRequest = CONTAINING_RECORD(CurrentEntry,
|
|
||||||
DATAGRAM_SEND_REQUEST, ListEntry);
|
|
||||||
/* Abort the request and free its resources */
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
|
||||||
(*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0);
|
(*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0);
|
||||||
exFreePool(SendRequest);
|
exFreePool(SendRequest);
|
||||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
|
||||||
CurrentEntry = NextEntry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
|
||||||
|
|
||||||
/* Protocol specific handling */
|
/* Protocol specific handling */
|
||||||
switch (AddrFile->Protocol) {
|
switch (AddrFile->Protocol) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
TCPFreePort( AddrFile->Port );
|
TCPFreePort( AddrFile->Port );
|
||||||
if( AddrFile->Listener ) {
|
if( AddrFile->Listener )
|
||||||
TCPClose( AddrFile->Listener );
|
TCPClose( AddrFile->Listener );
|
||||||
exFreePool( AddrFile->Listener );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
|
@ -433,48 +412,11 @@ NTSTATUS FileOpenConnection(
|
||||||
/* Return connection endpoint file object */
|
/* Return connection endpoint file object */
|
||||||
Request->Handle.ConnectionContext = Connection;
|
Request->Handle.ConnectionContext = Connection;
|
||||||
|
|
||||||
/* Add connection endpoint to global list */
|
|
||||||
ExInterlockedInsertTailList(
|
|
||||||
&ConnectionEndpointListHead,
|
|
||||||
&Connection->ListEntry,
|
|
||||||
&ConnectionEndpointListLock);
|
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FUNCTION: Find a connection by examining the context field. This
|
|
||||||
* is needed in some situations where a FIN reply is needed after a
|
|
||||||
* socket is formally broken.
|
|
||||||
* ARGUMENTS:
|
|
||||||
* Request = Pointer to TDI request structure for this request
|
|
||||||
* RETURNS:
|
|
||||||
* Status of operation
|
|
||||||
*/
|
|
||||||
PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) {
|
|
||||||
PLIST_ENTRY Entry;
|
|
||||||
KIRQL OldIrql;
|
|
||||||
PCONNECTION_ENDPOINT Connection = NULL;
|
|
||||||
|
|
||||||
TcpipAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql );
|
|
||||||
|
|
||||||
for( Entry = ConnectionEndpointListHead.Flink;
|
|
||||||
Entry != &ConnectionEndpointListHead;
|
|
||||||
Entry = Entry->Flink ) {
|
|
||||||
Connection =
|
|
||||||
CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry );
|
|
||||||
if( Connection->SocketContext == Context ) break;
|
|
||||||
else Connection = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpipReleaseSpinLock( &ConnectionEndpointListLock, OldIrql );
|
|
||||||
|
|
||||||
return Connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Closes an connection file object
|
* FUNCTION: Closes an connection file object
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
@ -486,20 +428,13 @@ NTSTATUS FileCloseConnection(
|
||||||
PTDI_REQUEST Request)
|
PTDI_REQUEST Request)
|
||||||
{
|
{
|
||||||
PCONNECTION_ENDPOINT Connection;
|
PCONNECTION_ENDPOINT Connection;
|
||||||
KIRQL OldIrql;
|
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE, ("Called.\n"));
|
TI_DbgPrint(MID_TRACE, ("Called.\n"));
|
||||||
|
|
||||||
Connection = Request->Handle.ConnectionContext;
|
Connection = Request->Handle.ConnectionContext;
|
||||||
|
|
||||||
TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
|
|
||||||
RemoveEntryList(&Connection->ListEntry);
|
|
||||||
TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
|
|
||||||
|
|
||||||
TCPClose( Connection );
|
TCPClose( Connection );
|
||||||
|
|
||||||
TCPFreeConnectionEndpoint(Connection);
|
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -44,16 +44,3 @@ VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) {
|
||||||
ExReleaseFastMutex( Mutex );
|
ExReleaseFastMutex( Mutex );
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
RecursiveMutexInit( RecMutex );
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
//TI_DbgPrint(DEBUG_LOCK,("Locking\n"));
|
|
||||||
RecursiveMutexEnter( RecMutex );
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
//TI_DbgPrint(DEBUG_LOCK,("Unlocking\n"));
|
|
||||||
RecursiveMutexLeave( RecMutex );
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,11 +45,3 @@ VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ) {
|
||||||
VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) {
|
VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
|
|
||||||
}
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ VOID DGDeliverData(
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
|
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||||
|
|
||||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||||
|
|
||||||
if (AddrFile->Protocol == IPPROTO_UDP)
|
if (AddrFile->Protocol == IPPROTO_UDP)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +136,7 @@ VOID DGDeliverData(
|
||||||
&SrcAddress->Address.IPv4Address,
|
&SrcAddress->Address.IPv4Address,
|
||||||
sizeof(SrcAddress->Address.IPv4Address) );
|
sizeof(SrcAddress->Address.IPv4Address) );
|
||||||
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
|
|
||||||
/* Complete the receive request */
|
/* Complete the receive request */
|
||||||
if (Current->BufferSize < DataSize)
|
if (Current->BufferSize < DataSize)
|
||||||
|
@ -144,11 +144,11 @@ VOID DGDeliverData(
|
||||||
else
|
else
|
||||||
Current->Complete(Current->Context, STATUS_SUCCESS, DataSize);
|
Current->Complete(Current->Context, STATUS_SUCCESS, DataSize);
|
||||||
|
|
||||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
}
|
}
|
||||||
else if (AddrFile->RegisteredReceiveDatagramHandler)
|
else if (AddrFile->RegisteredReceiveDatagramHandler)
|
||||||
{
|
{
|
||||||
|
@ -157,8 +157,6 @@ VOID DGDeliverData(
|
||||||
ReceiveHandler = AddrFile->ReceiveDatagramHandler;
|
ReceiveHandler = AddrFile->ReceiveDatagramHandler;
|
||||||
HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
|
HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
|
||||||
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
|
||||||
|
|
||||||
if (SrcAddress->Type == IP_ADDRESS_V4)
|
if (SrcAddress->Type == IP_ADDRESS_V4)
|
||||||
{
|
{
|
||||||
AddressLength = sizeof(IPv4_RAW_ADDRESS);
|
AddressLength = sizeof(IPv4_RAW_ADDRESS);
|
||||||
|
@ -170,6 +168,8 @@ VOID DGDeliverData(
|
||||||
SourceAddress = SrcAddress->Address.IPv6Address;
|
SourceAddress = SrcAddress->Address.IPv6Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
|
|
||||||
Status = (*ReceiveHandler)(HandlerContext,
|
Status = (*ReceiveHandler)(HandlerContext,
|
||||||
AddressLength,
|
AddressLength,
|
||||||
SourceAddress,
|
SourceAddress,
|
||||||
|
@ -184,7 +184,7 @@ VOID DGDeliverData(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
|
TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,76 +228,67 @@ NTSTATUS DGReceiveDatagram(
|
||||||
* This is the high level interface for receiving DG datagrams
|
* This is the high level interface for receiving DG datagrams
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
|
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
|
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||||
|
|
||||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||||
|
|
||||||
if (AF_IS_VALID(AddrFile))
|
ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
|
||||||
|
if (ReceiveRequest)
|
||||||
{
|
{
|
||||||
ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
|
/* Initialize a receive request */
|
||||||
if (ReceiveRequest)
|
|
||||||
|
/* Extract the remote address filter from the request (if any) */
|
||||||
|
if ((ConnInfo->RemoteAddressLength != 0) &&
|
||||||
|
(ConnInfo->RemoteAddress))
|
||||||
{
|
{
|
||||||
/* Initialize a receive request */
|
Status = AddrGetAddress(ConnInfo->RemoteAddress,
|
||||||
|
&ReceiveRequest->RemoteAddress,
|
||||||
/* Extract the remote address filter from the request (if any) */
|
&ReceiveRequest->RemotePort);
|
||||||
if ((ConnInfo->RemoteAddressLength != 0) &&
|
if (!NT_SUCCESS(Status))
|
||||||
(ConnInfo->RemoteAddress))
|
|
||||||
{
|
{
|
||||||
Status = AddrGetAddress(ConnInfo->RemoteAddress,
|
exFreePool(ReceiveRequest);
|
||||||
&ReceiveRequest->RemoteAddress,
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
&ReceiveRequest->RemotePort);
|
return Status;
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
|
||||||
exFreePool(ReceiveRequest);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
ReceiveRequest->RemotePort = 0;
|
|
||||||
AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
IoMarkIrpPending(Irp);
|
|
||||||
|
|
||||||
ReceiveRequest->ReturnInfo = ReturnInfo;
|
|
||||||
ReceiveRequest->Buffer = BufferData;
|
|
||||||
ReceiveRequest->BufferSize = ReceiveLength;
|
|
||||||
ReceiveRequest->UserComplete = Complete;
|
|
||||||
ReceiveRequest->UserContext = Context;
|
|
||||||
ReceiveRequest->Complete =
|
|
||||||
(PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete;
|
|
||||||
ReceiveRequest->Context = ReceiveRequest;
|
|
||||||
ReceiveRequest->AddressFile = AddrFile;
|
|
||||||
ReceiveRequest->Irp = Irp;
|
|
||||||
|
|
||||||
/* Queue receive request */
|
|
||||||
InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
|
|
||||||
AF_SET_PENDING(AddrFile, AFF_RECEIVE);
|
|
||||||
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
|
|
||||||
|
|
||||||
return STATUS_PENDING;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
ReceiveRequest->RemotePort = 0;
|
||||||
|
AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
|
||||||
|
ReceiveRequest->ReturnInfo = ReturnInfo;
|
||||||
|
ReceiveRequest->Buffer = BufferData;
|
||||||
|
ReceiveRequest->BufferSize = ReceiveLength;
|
||||||
|
ReceiveRequest->UserComplete = Complete;
|
||||||
|
ReceiveRequest->UserContext = Context;
|
||||||
|
ReceiveRequest->Complete =
|
||||||
|
(PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete;
|
||||||
|
ReceiveRequest->Context = ReceiveRequest;
|
||||||
|
ReceiveRequest->AddressFile = AddrFile;
|
||||||
|
ReceiveRequest->Irp = Irp;
|
||||||
|
|
||||||
|
/* Queue receive request */
|
||||||
|
InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
|
||||||
|
|
||||||
|
TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
|
|
||||||
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = STATUS_INVALID_ADDRESS;
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
|
TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -195,6 +195,9 @@ NTSTATUS RawIPSendDatagram(
|
||||||
USHORT RemotePort;
|
USHORT RemotePort;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
|
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
|
||||||
AddrFile, ConnInfo, BufferData, DataSize));
|
AddrFile, ConnInfo, BufferData, DataSize));
|
||||||
|
@ -209,13 +212,17 @@ NTSTATUS RawIPSendDatagram(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
|
TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
|
||||||
|
|
||||||
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress )))
|
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress )))
|
||||||
|
{
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
return STATUS_NETWORK_UNREACHABLE;
|
return STATUS_NETWORK_UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
LocalAddress = AddrFile->Address;
|
LocalAddress = AddrFile->Address;
|
||||||
if (AddrIsUnspecified(&LocalAddress))
|
if (AddrIsUnspecified(&LocalAddress))
|
||||||
|
@ -237,18 +244,24 @@ NTSTATUS RawIPSendDatagram(
|
||||||
DataSize );
|
DataSize );
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) )
|
if( !NT_SUCCESS(Status) )
|
||||||
|
{
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
return Status;
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
|
TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL )))
|
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL )))
|
||||||
{
|
{
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
FreeNdisPacket(Packet.NdisPacket);
|
FreeNdisPacket(Packet.NdisPacket);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("Leaving\n"));
|
TI_DbgPrint(MID_TRACE,("Leaving\n"));
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
|
/* Listener->Lock MUST be acquired */
|
||||||
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
||||||
PCONNECTION_ENDPOINT Connection,
|
PCONNECTION_ENDPOINT Connection,
|
||||||
PTDI_REQUEST_KERNEL Request ) {
|
PTDI_REQUEST_KERNEL Request ) {
|
||||||
|
@ -26,18 +27,15 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
||||||
WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)
|
WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)
|
||||||
Request->ReturnConnectionInformation;
|
Request->ReturnConnectionInformation;
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
|
||||||
|
|
||||||
Status = TCPTranslateError
|
Status = TCPTranslateError
|
||||||
( OskitTCPAccept( Listener->SocketContext,
|
( OskitTCPAccept( Listener->SocketContext,
|
||||||
&Connection->SocketContext,
|
&Connection->SocketContext,
|
||||||
|
Connection,
|
||||||
&OutAddr,
|
&OutAddr,
|
||||||
sizeof(OutAddr),
|
sizeof(OutAddr),
|
||||||
&OutAddrLen,
|
&OutAddrLen,
|
||||||
Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) );
|
Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) );
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
|
TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) && Status != STATUS_PENDING ) {
|
if( NT_SUCCESS(Status) && Status != STATUS_PENDING ) {
|
||||||
|
@ -71,11 +69,14 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
||||||
NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
SOCKADDR_IN AddressToBind;
|
SOCKADDR_IN AddressToBind;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
ASSERT(Connection);
|
ASSERT(Connection);
|
||||||
ASSERT_KM_POINTER(Connection->SocketContext);
|
ASSERT_KM_POINTER(Connection->SocketContext);
|
||||||
ASSERT_KM_POINTER(Connection->AddressFile);
|
ASSERT_KM_POINTER(Connection->AddressFile);
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
|
TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
|
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
|
||||||
|
@ -89,8 +90,6 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
|
TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter( &TCPLock );
|
|
||||||
|
|
||||||
Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext,
|
Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext,
|
||||||
&AddressToBind,
|
&AddressToBind,
|
||||||
sizeof(AddressToBind) ) );
|
sizeof(AddressToBind) ) );
|
||||||
|
@ -98,7 +97,7 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
|
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave( &TCPLock );
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
|
TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
|
||||||
|
|
||||||
|
@ -137,12 +136,17 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PTDI_BUCKET Bucket;
|
PTDI_BUCKET Bucket;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
|
TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Listener->Lock, &OldIrql);
|
||||||
|
|
||||||
Status = TCPServiceListeningSocket( Listener, Connection,
|
Status = TCPServiceListeningSocket( Listener, Connection,
|
||||||
(PTDI_REQUEST_KERNEL)Request );
|
(PTDI_REQUEST_KERNEL)Request );
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Listener->Lock, OldIrql);
|
||||||
|
|
||||||
if( Status == STATUS_PENDING ) {
|
if( Status == STATUS_PENDING ) {
|
||||||
Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
|
Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
|
||||||
|
|
||||||
|
@ -150,8 +154,8 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
|
||||||
Bucket->AssociatedEndpoint = Connection;
|
Bucket->AssociatedEndpoint = Connection;
|
||||||
Bucket->Request.RequestNotifyObject = Complete;
|
Bucket->Request.RequestNotifyObject = Complete;
|
||||||
Bucket->Request.RequestContext = Context;
|
Bucket->Request.RequestContext = Context;
|
||||||
IoMarkIrpPending((PIRP)Context);
|
ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry,
|
||||||
ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, &Listener->Lock );
|
&Listener->Lock );
|
||||||
} else
|
} else
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,56 +15,30 @@ int TCPSocketState(void *ClientData,
|
||||||
void *WhichConnection,
|
void *WhichConnection,
|
||||||
OSK_UINT NewState ) {
|
OSK_UINT NewState ) {
|
||||||
PCONNECTION_ENDPOINT Connection = WhichConnection;
|
PCONNECTION_ENDPOINT Connection = WhichConnection;
|
||||||
ULONG OldState;
|
|
||||||
KIRQL OldIrql;
|
|
||||||
|
|
||||||
ASSERT_LOCKED(&TCPLock);
|
TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n",
|
||||||
|
Connection,
|
||||||
TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n",
|
|
||||||
NewState & SEL_CONNECT ? 'C' : 'c',
|
NewState & SEL_CONNECT ? 'C' : 'c',
|
||||||
NewState & SEL_READ ? 'R' : 'r',
|
NewState & SEL_READ ? 'R' : 'r',
|
||||||
NewState & SEL_FIN ? 'F' : 'f',
|
NewState & SEL_FIN ? 'F' : 'f',
|
||||||
NewState & SEL_ACCEPT ? 'A' : 'a'));
|
NewState & SEL_ACCEPT ? 'A' : 'a',
|
||||||
|
NewState & SEL_WRITE ? 'W' : 'w'));
|
||||||
|
|
||||||
|
if (!Connection)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeAcquireSpinLockAtDpcLevel(&Connection->Lock);
|
||||||
|
|
||||||
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->SignalState ^ NewState :
|
Connection->SignalState ^ NewState,
|
||||||
NewState));
|
NewState));
|
||||||
|
|
||||||
if( !Connection ) {
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Socket closing.\n"));
|
|
||||||
Connection = FileFindConnectionByContext( WhichSocket );
|
|
||||||
if( !Connection )
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
|
|
||||||
}
|
|
||||||
|
|
||||||
OldState = Connection->SignalState;
|
|
||||||
|
|
||||||
Connection->SignalState |= NewState;
|
Connection->SignalState |= NewState;
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
KeReleaseSpinLockFromDpcLevel(&Connection->Lock);
|
||||||
|
|
||||||
/* We must not be locked when handling signalled connections
|
|
||||||
* because a completion could trigger another IOCTL which
|
|
||||||
* would cause a deadlock
|
|
||||||
*/
|
|
||||||
NewState = HandleSignalledConnection(Connection);
|
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
|
|
||||||
if ((NewState == 0 || NewState == SEL_FIN) &&
|
|
||||||
(OldState != 0 && OldState != SEL_FIN))
|
|
||||||
{
|
|
||||||
RemoveEntryList(&Connection->SignalList);
|
|
||||||
}
|
|
||||||
else if (NewState != 0 && NewState != SEL_FIN)
|
|
||||||
{
|
|
||||||
InsertTailList(&SignalledConnectionsList, &Connection->SignalList);
|
|
||||||
}
|
|
||||||
KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -86,8 +60,6 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
|
||||||
IP_ADDRESS RemoteAddress, LocalAddress;
|
IP_ADDRESS RemoteAddress, LocalAddress;
|
||||||
PIPv4_HEADER Header;
|
PIPv4_HEADER Header;
|
||||||
|
|
||||||
ASSERT_LOCKED(&TCPLock);
|
|
||||||
|
|
||||||
if( *data == 0x45 ) { /* IPv4 */
|
if( *data == 0x45 ) { /* IPv4 */
|
||||||
Header = (PIPv4_HEADER)data;
|
Header = (PIPv4_HEADER)data;
|
||||||
LocalAddress.Type = IP_ADDRESS_V4;
|
LocalAddress.Type = IP_ADDRESS_V4;
|
||||||
|
@ -181,8 +153,6 @@ void *TCPMalloc( void *ClientData,
|
||||||
void *v;
|
void *v;
|
||||||
ULONG Signature;
|
ULONG Signature;
|
||||||
|
|
||||||
ASSERT_LOCKED(&TCPLock);
|
|
||||||
|
|
||||||
#if 0 != MEM_PROFILE
|
#if 0 != MEM_PROFILE
|
||||||
static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0;
|
static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0;
|
||||||
static OSK_UINT ArrayUsed = 0, AllocationCount = 0;
|
static OSK_UINT ArrayUsed = 0, AllocationCount = 0;
|
||||||
|
@ -258,8 +228,6 @@ void TCPFree( void *ClientData,
|
||||||
void *data, OSK_PCHAR File, OSK_UINT Line ) {
|
void *data, OSK_PCHAR File, OSK_UINT Line ) {
|
||||||
ULONG Signature;
|
ULONG Signature;
|
||||||
|
|
||||||
ASSERT_LOCKED(&TCPLock);
|
|
||||||
|
|
||||||
UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') );
|
UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') );
|
||||||
data = (void *)((char *) data - sizeof(ULONG));
|
data = (void *)((char *) data - sizeof(ULONG));
|
||||||
Signature = *((ULONG *) data);
|
Signature = *((ULONG *) data);
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
LONG TCP_IPIdentification = 0;
|
LONG TCP_IPIdentification = 0;
|
||||||
static BOOLEAN TCPInitialized = FALSE;
|
static BOOLEAN TCPInitialized = FALSE;
|
||||||
static NPAGED_LOOKASIDE_LIST TCPSegmentList;
|
static NPAGED_LOOKASIDE_LIST TCPSegmentList;
|
||||||
LIST_ENTRY SignalledConnectionsList;
|
|
||||||
KSPIN_LOCK SignalledConnectionsLock;
|
|
||||||
RECURSIVE_MUTEX TCPLock;
|
|
||||||
PORT_SET TCPPorts;
|
PORT_SET TCPPorts;
|
||||||
|
|
||||||
ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
|
static VOID DrainSignals() {
|
||||||
|
PCONNECTION_ENDPOINT Connection;
|
||||||
|
PLIST_ENTRY CurrentEntry, NextEntry;
|
||||||
|
KIRQL OldIrql;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PTCP_COMPLETION_ROUTINE Complete;
|
PTCP_COMPLETION_ROUTINE Complete;
|
||||||
PTDI_BUCKET Bucket;
|
PTDI_BUCKET Bucket;
|
||||||
|
@ -28,279 +28,290 @@ ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
|
KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
|
||||||
Connection, Connection->SocketContext));
|
CurrentEntry = ConnectionEndpointListHead.Flink;
|
||||||
|
while (CurrentEntry != &ConnectionEndpointListHead)
|
||||||
if( Connection->SignalState & SEL_FIN ) {
|
|
||||||
TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
|
|
||||||
|
|
||||||
Connection->SignalState &= ~SEL_READ;
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
|
|
||||||
&Connection->Lock )) != NULL)
|
|
||||||
{
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
|
||||||
|
|
||||||
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
|
||||||
|
|
||||||
exFreePool(Bucket);
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection->SignalState &= ~SEL_WRITE;
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
|
|
||||||
&Connection->Lock )) != NULL)
|
|
||||||
{
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
|
||||||
|
|
||||||
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
|
||||||
|
|
||||||
exFreePool(Bucket);
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection->SignalState &= ~SEL_ACCEPT;
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
|
|
||||||
&Connection->Lock )) != NULL)
|
|
||||||
{
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
|
||||||
|
|
||||||
/* We have to notify oskittcp of the abortion */
|
|
||||||
TCPAbortListenForSocket(Connection->AddressFile->Listener,
|
|
||||||
Connection);
|
|
||||||
|
|
||||||
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
|
||||||
|
|
||||||
exFreePool(Bucket);
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection->SignalState &= ~SEL_CONNECT;
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
|
|
||||||
&Connection->Lock )) != NULL)
|
|
||||||
{
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
|
||||||
|
|
||||||
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
|
||||||
|
|
||||||
exFreePool(Bucket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Things that can happen when we try the initial connection */
|
|
||||||
if( Connection->SignalState & SEL_CONNECT ) {
|
|
||||||
Connection->SignalState &= ~SEL_CONNECT;
|
|
||||||
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
|
|
||||||
&Connection->Lock )) != NULL ) {
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP, ("Connect Event\n"));
|
|
||||||
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Completing Request %x\n", Bucket->Request.RequestContext));
|
|
||||||
|
|
||||||
Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
|
|
||||||
|
|
||||||
/* Frees the bucket allocated in TCPConnect */
|
|
||||||
exFreePool( Bucket );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Connection->SignalState & 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"));
|
|
||||||
|
|
||||||
Connection->SignalState &= ~SEL_ACCEPT;
|
|
||||||
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
|
|
||||||
&Connection->Lock )) != NULL ) {
|
|
||||||
PIO_STACK_LOCATION IrpSp;
|
|
||||||
|
|
||||||
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 ) {
|
|
||||||
Connection->SignalState |= SEL_ACCEPT;
|
|
||||||
ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock );
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
Complete( Bucket->Request.RequestContext, Status, 0 );
|
|
||||||
exFreePool( Bucket );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Things that happen after we're connected */
|
|
||||||
if( Connection->SignalState & SEL_READ ) {
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
|
|
||||||
IsListEmpty(&Connection->ReceiveRequest) ?
|
|
||||||
"empty" : "nonempty"));
|
|
||||||
|
|
||||||
Connection->SignalState &= ~SEL_READ;
|
|
||||||
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
|
|
||||||
&Connection->Lock )) != NULL ) {
|
|
||||||
OSK_UINT RecvLen = 0, Received = 0;
|
|
||||||
PVOID RecvBuffer = 0;
|
|
||||||
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
|
||||||
|
|
||||||
Irp = Bucket->Request.RequestContext;
|
|
||||||
Mdl = Irp->MdlAddress;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Getting the user buffer from %x\n", Mdl));
|
|
||||||
|
|
||||||
NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
|
|
||||||
TI_DbgPrint
|
|
||||||
(DEBUG_TCP,
|
|
||||||
("Connection->SocketContext: %x\n",
|
|
||||||
Connection->SocketContext));
|
|
||||||
TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
|
|
||||||
|
|
||||||
Status = TCPTranslateError
|
|
||||||
( OskitTCPRecv( Connection->SocketContext,
|
|
||||||
RecvBuffer,
|
|
||||||
RecvLen,
|
|
||||||
&Received,
|
|
||||||
0 ) );
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
|
|
||||||
|
|
||||||
if( Status == STATUS_SUCCESS ) {
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
|
|
||||||
Received, Status));
|
|
||||||
|
|
||||||
Complete( Bucket->Request.RequestContext,
|
|
||||||
STATUS_SUCCESS, Received );
|
|
||||||
exFreePool( Bucket );
|
|
||||||
} else if( Status == STATUS_PENDING ) {
|
|
||||||
ExInterlockedInsertHeadList
|
|
||||||
( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
|
|
||||||
Connection->SignalState |= SEL_READ;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Completing Receive request: %x %x\n",
|
|
||||||
Bucket->Request, Status));
|
|
||||||
Complete( Bucket->Request.RequestContext, Status, 0 );
|
|
||||||
exFreePool( Bucket );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( Connection->SignalState & SEL_WRITE ) {
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
|
|
||||||
IsListEmpty(&Connection->SendRequest) ?
|
|
||||||
"empty" : "nonempty"));
|
|
||||||
|
|
||||||
Connection->SignalState &= ~SEL_WRITE;
|
|
||||||
while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
|
|
||||||
&Connection->Lock )) != NULL ) {
|
|
||||||
OSK_UINT SendLen = 0, Sent = 0;
|
|
||||||
PVOID SendBuffer = 0;
|
|
||||||
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
|
||||||
|
|
||||||
Irp = Bucket->Request.RequestContext;
|
|
||||||
Mdl = Irp->MdlAddress;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Getting the user buffer from %x\n", Mdl));
|
|
||||||
|
|
||||||
NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Writing %d bytes to %x\n", SendLen, SendBuffer));
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
|
|
||||||
TI_DbgPrint
|
|
||||||
(DEBUG_TCP,
|
|
||||||
("Connection->SocketContext: %x\n",
|
|
||||||
Connection->SocketContext));
|
|
||||||
|
|
||||||
Status = TCPTranslateError
|
|
||||||
( OskitTCPSend( Connection->SocketContext,
|
|
||||||
SendBuffer,
|
|
||||||
SendLen,
|
|
||||||
&Sent,
|
|
||||||
0 ) );
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
|
|
||||||
|
|
||||||
if( Status == STATUS_SUCCESS ) {
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n",
|
|
||||||
Sent, Status));
|
|
||||||
|
|
||||||
Complete( Bucket->Request.RequestContext,
|
|
||||||
STATUS_SUCCESS, Sent );
|
|
||||||
exFreePool( Bucket );
|
|
||||||
} else if( Status == STATUS_PENDING ) {
|
|
||||||
ExInterlockedInsertHeadList
|
|
||||||
( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
|
|
||||||
Connection->SignalState |= SEL_WRITE;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
TI_DbgPrint(DEBUG_TCP,
|
|
||||||
("Completing Send request: %x %x\n",
|
|
||||||
Bucket->Request, Status));
|
|
||||||
Complete( Bucket->Request.RequestContext, Status, 0 );
|
|
||||||
exFreePool( Bucket );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Connection->SignalState;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID DrainSignals() {
|
|
||||||
PCONNECTION_ENDPOINT Connection;
|
|
||||||
PLIST_ENTRY CurrentEntry, NextEntry;
|
|
||||||
ULONG NewState;
|
|
||||||
KIRQL OldIrql;
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
|
|
||||||
CurrentEntry = SignalledConnectionsList.Flink;
|
|
||||||
while (CurrentEntry != &SignalledConnectionsList)
|
|
||||||
{
|
{
|
||||||
NextEntry = CurrentEntry->Flink;
|
NextEntry = CurrentEntry->Flink;
|
||||||
|
KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
|
||||||
|
|
||||||
Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT,
|
Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT,
|
||||||
SignalList );
|
ListEntry );
|
||||||
|
|
||||||
KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
NewState = HandleSignalledConnection(Connection);
|
|
||||||
KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
|
|
||||||
|
|
||||||
if (NewState == SEL_FIN || NewState == 0)
|
TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
|
||||||
{
|
Connection, Connection->SocketContext));
|
||||||
RemoveEntryList(CurrentEntry);
|
|
||||||
|
if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) {
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
|
||||||
|
|
||||||
|
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
|
||||||
|
&Connection->Lock )) != NULL)
|
||||||
|
{
|
||||||
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
|
||||||
|
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
||||||
|
|
||||||
|
exFreePool(Bucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
|
||||||
|
&Connection->Lock )) != NULL)
|
||||||
|
{
|
||||||
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
|
||||||
|
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
||||||
|
|
||||||
|
exFreePool(Bucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
|
||||||
|
&Connection->Lock )) != NULL)
|
||||||
|
{
|
||||||
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
|
||||||
|
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
||||||
|
|
||||||
|
exFreePool(Bucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
|
||||||
|
&Connection->Lock )) != NULL)
|
||||||
|
{
|
||||||
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
|
||||||
|
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
||||||
|
|
||||||
|
exFreePool(Bucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentEntry = NextEntry;
|
/* Things that can happen when we try the initial connection */
|
||||||
|
if( Connection->SignalState & SEL_CONNECT ) {
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
|
||||||
|
&Connection->Lock )) != NULL ) {
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP, ("Connect Event\n"));
|
||||||
|
|
||||||
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
TI_DbgPrint(DEBUG_TCP,
|
||||||
|
("Completing Request %x\n", Bucket->Request.RequestContext));
|
||||||
|
|
||||||
|
Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
|
||||||
|
|
||||||
|
/* Frees the bucket allocated in TCPConnect */
|
||||||
|
exFreePool( Bucket );
|
||||||
|
}
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Connection->SignalState & SEL_ACCEPT ) {
|
||||||
|
/* Handle readable on a listening socket --
|
||||||
|
* TODO: Implement filtering
|
||||||
|
*/
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
|
||||||
|
Connection,
|
||||||
|
IsListEmpty(&Connection->ListenRequest) ?
|
||||||
|
"empty" : "nonempty"));
|
||||||
|
|
||||||
|
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
|
||||||
|
&Connection->Lock )) != NULL ) {
|
||||||
|
PIO_STACK_LOCATION IrpSp;
|
||||||
|
|
||||||
|
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"));
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
|
Status = TCPServiceListeningSocket
|
||||||
|
( Connection->AddressFile->Listener,
|
||||||
|
Bucket->AssociatedEndpoint,
|
||||||
|
(PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
|
||||||
|
|
||||||
|
if( Status == STATUS_PENDING ) {
|
||||||
|
ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry,
|
||||||
|
&Connection->Lock );
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
Complete( Bucket->Request.RequestContext, Status, 0 );
|
||||||
|
exFreePool( Bucket );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Things that happen after we're connected */
|
||||||
|
if( Connection->SignalState & SEL_READ &&
|
||||||
|
Connection->SignalState & SEL_CONNECT ) {
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
|
||||||
|
IsListEmpty(&Connection->ReceiveRequest) ?
|
||||||
|
"empty" : "nonempty"));
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
|
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
|
||||||
|
&Connection->Lock )) != NULL ) {
|
||||||
|
OSK_UINT RecvLen = 0, Received = 0;
|
||||||
|
PVOID RecvBuffer = 0;
|
||||||
|
|
||||||
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
|
||||||
|
Irp = Bucket->Request.RequestContext;
|
||||||
|
Mdl = Irp->MdlAddress;
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,
|
||||||
|
("Getting the user buffer from %x\n", Mdl));
|
||||||
|
|
||||||
|
NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,
|
||||||
|
("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
|
||||||
|
TI_DbgPrint
|
||||||
|
(DEBUG_TCP,
|
||||||
|
("Connection->SocketContext: %x\n",
|
||||||
|
Connection->SocketContext));
|
||||||
|
TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
|
Status = TCPTranslateError
|
||||||
|
( OskitTCPRecv( Connection->SocketContext,
|
||||||
|
RecvBuffer,
|
||||||
|
RecvLen,
|
||||||
|
&Received,
|
||||||
|
0 ) );
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
|
||||||
|
|
||||||
|
if( Status == STATUS_SUCCESS ) {
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
|
||||||
|
Received, Status));
|
||||||
|
Complete( Bucket->Request.RequestContext,
|
||||||
|
STATUS_SUCCESS, Received );
|
||||||
|
exFreePool( Bucket );
|
||||||
|
} else if( Status == STATUS_PENDING ) {
|
||||||
|
ExInterlockedInsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry,
|
||||||
|
&Connection->Lock );
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
TI_DbgPrint(DEBUG_TCP,
|
||||||
|
("Completing Receive request: %x %x\n",
|
||||||
|
Bucket->Request, Status));
|
||||||
|
Complete( Bucket->Request.RequestContext, Status, 0 );
|
||||||
|
exFreePool( Bucket );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
}
|
||||||
|
if( Connection->SignalState & SEL_WRITE &&
|
||||||
|
Connection->SignalState & SEL_CONNECT ) {
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
|
||||||
|
IsListEmpty(&Connection->SendRequest) ?
|
||||||
|
"empty" : "nonempty"));
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
|
while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
|
||||||
|
&Connection->Lock )) != NULL ) {
|
||||||
|
OSK_UINT SendLen = 0, Sent = 0;
|
||||||
|
PVOID SendBuffer = 0;
|
||||||
|
|
||||||
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
|
|
||||||
|
Irp = Bucket->Request.RequestContext;
|
||||||
|
Mdl = Irp->MdlAddress;
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,
|
||||||
|
("Getting the user buffer from %x\n", Mdl));
|
||||||
|
|
||||||
|
NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,
|
||||||
|
("Writing %d bytes to %x\n", SendLen, SendBuffer));
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
|
||||||
|
TI_DbgPrint
|
||||||
|
(DEBUG_TCP,
|
||||||
|
("Connection->SocketContext: %x\n",
|
||||||
|
Connection->SocketContext));
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
|
Status = TCPTranslateError
|
||||||
|
( OskitTCPSend( Connection->SocketContext,
|
||||||
|
SendBuffer,
|
||||||
|
SendLen,
|
||||||
|
&Sent,
|
||||||
|
0 ) );
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
|
||||||
|
|
||||||
|
if( Status == STATUS_SUCCESS ) {
|
||||||
|
TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n",
|
||||||
|
Sent, Status));
|
||||||
|
Complete( Bucket->Request.RequestContext,
|
||||||
|
STATUS_SUCCESS, Sent );
|
||||||
|
exFreePool( Bucket );
|
||||||
|
} else if( Status == STATUS_PENDING ) {
|
||||||
|
ExInterlockedInsertHeadList( &Connection->SendRequest, &Bucket->Entry,
|
||||||
|
&Connection->Lock );
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
TI_DbgPrint(DEBUG_TCP,
|
||||||
|
("Completing Send request: %x %x\n",
|
||||||
|
Bucket->Request, Status));
|
||||||
|
Complete( Bucket->Request.RequestContext, Status, 0 );
|
||||||
|
exFreePool( Bucket );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
|
if (!Connection->SocketContext)
|
||||||
|
{
|
||||||
|
TCPFreeConnectionEndpoint(Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
|
|
||||||
|
KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
|
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
|
||||||
|
@ -314,7 +325,7 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
|
||||||
RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
|
RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
|
||||||
|
|
||||||
/* Initialize spin lock that protects the connection endpoint file object */
|
/* Initialize spin lock that protects the connection endpoint file object */
|
||||||
TcpipInitializeSpinLock(&Connection->Lock);
|
KeInitializeSpinLock(&Connection->Lock);
|
||||||
InitializeListHead(&Connection->ConnectRequest);
|
InitializeListHead(&Connection->ConnectRequest);
|
||||||
InitializeListHead(&Connection->ListenRequest);
|
InitializeListHead(&Connection->ListenRequest);
|
||||||
InitializeListHead(&Connection->ReceiveRequest);
|
InitializeListHead(&Connection->ReceiveRequest);
|
||||||
|
@ -323,19 +334,32 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
|
||||||
/* Save client context pointer */
|
/* Save client context pointer */
|
||||||
Connection->ClientContext = ClientContext;
|
Connection->ClientContext = ClientContext;
|
||||||
|
|
||||||
|
/* Add connection endpoint to global list */
|
||||||
|
ExInterlockedInsertTailList(&ConnectionEndpointListHead,
|
||||||
|
&Connection->ListEntry,
|
||||||
|
&ConnectionEndpointListLock);
|
||||||
|
|
||||||
return Connection;
|
return Connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) {
|
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) {
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
|
TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
|
||||||
|
|
||||||
|
TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
|
||||||
|
RemoveEntryList(&Connection->ListEntry);
|
||||||
|
TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
|
||||||
|
|
||||||
exFreePool( Connection );
|
exFreePool( Connection );
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
|
NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
|
||||||
UINT Family, UINT Type, UINT Proto ) {
|
UINT Family, UINT Type, UINT Proto ) {
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, "
|
TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, "
|
||||||
"Proto %d\n",
|
"Proto %d\n",
|
||||||
|
@ -352,7 +376,7 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
|
||||||
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
|
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
|
||||||
Connection->SocketContext));
|
Connection->SocketContext));
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -370,13 +394,9 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
|
||||||
IPPacket->TotalSize,
|
IPPacket->TotalSize,
|
||||||
IPPacket->HeaderSize));
|
IPPacket->HeaderSize));
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter( &TCPLock );
|
|
||||||
|
|
||||||
OskitTCPReceiveDatagram( IPPacket->Header,
|
OskitTCPReceiveDatagram( IPPacket->Header,
|
||||||
IPPacket->TotalSize,
|
IPPacket->TotalSize,
|
||||||
IPPacket->HeaderSize );
|
IPPacket->HeaderSize );
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave( &TCPLock );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* event.c */
|
/* event.c */
|
||||||
|
@ -447,10 +467,7 @@ TimerThread(PVOID Context)
|
||||||
PsTerminateSystemThread(Status);
|
PsTerminateSystemThread(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter( &TCPLock );
|
|
||||||
TimerOskitTCP( Next == NextFast, Next == NextSlow );
|
TimerOskitTCP( Next == NextFast, Next == NextSlow );
|
||||||
TcpipRecursiveMutexLeave( &TCPLock );
|
|
||||||
|
|
||||||
if (Next == NextSlow) {
|
if (Next == NextSlow) {
|
||||||
DrainSignals();
|
DrainSignals();
|
||||||
}
|
}
|
||||||
|
@ -483,9 +500,6 @@ NTSTATUS TCPStartup(VOID)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
TcpipRecursiveMutexInit( &TCPLock );
|
|
||||||
KeInitializeSpinLock( &SignalledConnectionsLock );
|
|
||||||
InitializeListHead( &SignalledConnectionsList );
|
|
||||||
Status = TCPMemStartup();
|
Status = TCPMemStartup();
|
||||||
if ( ! NT_SUCCESS(Status) ) {
|
if ( ! NT_SUCCESS(Status) ) {
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -497,10 +511,8 @@ NTSTATUS TCPStartup(VOID)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
|
||||||
RegisterOskitTCPEventHandlers( &EventHandlers );
|
RegisterOskitTCPEventHandlers( &EventHandlers );
|
||||||
InitOskitTCP();
|
InitOskitTCP();
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
|
||||||
|
|
||||||
/* Register this protocol with IP layer */
|
/* Register this protocol with IP layer */
|
||||||
IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
|
IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
|
||||||
|
@ -545,9 +557,7 @@ NTSTATUS TCPShutdown(VOID)
|
||||||
|
|
||||||
TCPInitialized = FALSE;
|
TCPInitialized = FALSE;
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
|
||||||
DeinitOskitTCP();
|
DeinitOskitTCP();
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
|
||||||
|
|
||||||
PortsShutdown( &TCPPorts );
|
PortsShutdown( &TCPPorts );
|
||||||
|
|
||||||
|
@ -597,6 +607,7 @@ NTSTATUS TCPConnect
|
||||||
USHORT RemotePort;
|
USHORT RemotePort;
|
||||||
PTDI_BUCKET Bucket;
|
PTDI_BUCKET Bucket;
|
||||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
|
TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
|
||||||
|
|
||||||
|
@ -625,7 +636,7 @@ NTSTATUS TCPConnect
|
||||||
AddressToBind = AddressToConnect;
|
AddressToBind = AddressToConnect;
|
||||||
AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
|
AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
Status = TCPTranslateError
|
Status = TCPTranslateError
|
||||||
( OskitTCPBind( Connection->SocketContext,
|
( OskitTCPBind( Connection->SocketContext,
|
||||||
|
@ -640,26 +651,29 @@ NTSTATUS TCPConnect
|
||||||
|
|
||||||
Status = TCPTranslateError
|
Status = TCPTranslateError
|
||||||
( OskitTCPConnect( Connection->SocketContext,
|
( OskitTCPConnect( Connection->SocketContext,
|
||||||
Connection,
|
|
||||||
&AddressToConnect,
|
&AddressToConnect,
|
||||||
sizeof(AddressToConnect) ) );
|
sizeof(AddressToConnect) ) );
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
|
Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
|
||||||
if( !Bucket ) return STATUS_NO_MEMORY;
|
if( !Bucket )
|
||||||
|
{
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
Bucket->Request.RequestNotifyObject = (PVOID)Complete;
|
Bucket->Request.RequestNotifyObject = (PVOID)Complete;
|
||||||
Bucket->Request.RequestContext = Context;
|
Bucket->Request.RequestContext = Context;
|
||||||
|
|
||||||
IoMarkIrpPending((PIRP)Context);
|
|
||||||
|
|
||||||
ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock );
|
ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry,
|
||||||
|
&Connection->Lock );
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,12 +685,11 @@ NTSTATUS TCPDisconnect
|
||||||
PTCP_COMPLETION_ROUTINE Complete,
|
PTCP_COMPLETION_ROUTINE Complete,
|
||||||
PVOID Context ) {
|
PVOID Context ) {
|
||||||
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
||||||
|
KIRQL OldIrql;
|
||||||
ASSERT_LOCKED(&TCPLock);
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("started\n"));
|
TI_DbgPrint(DEBUG_TCP,("started\n"));
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
if (Flags & TDI_DISCONNECT_RELEASE)
|
if (Flags & TDI_DISCONNECT_RELEASE)
|
||||||
Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext));
|
Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext));
|
||||||
|
@ -684,7 +697,7 @@ NTSTATUS TCPDisconnect
|
||||||
if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
|
if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
|
||||||
Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
|
Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status));
|
TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status));
|
||||||
|
|
||||||
|
@ -694,20 +707,20 @@ NTSTATUS TCPDisconnect
|
||||||
NTSTATUS TCPClose
|
NTSTATUS TCPClose
|
||||||
( PCONNECTION_ENDPOINT Connection ) {
|
( PCONNECTION_ENDPOINT Connection ) {
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PVOID Socket;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPClose started\n"));
|
TI_DbgPrint(DEBUG_TCP,("TCPClose started\n"));
|
||||||
|
|
||||||
/* Make our code remove all pending IRPs */
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
Connection->SignalState |= SEL_FIN;
|
Socket = Connection->SocketContext;
|
||||||
HandleSignalledConnection(Connection);
|
Connection->SocketContext = NULL;
|
||||||
|
Status = TCPTranslateError( OskitTCPClose( Socket ) );
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) );
|
Connection->SocketContext = Socket;
|
||||||
if (Status == STATUS_SUCCESS)
|
}
|
||||||
Connection->SocketContext = NULL;
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status));
|
TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status));
|
||||||
|
|
||||||
|
@ -726,17 +739,18 @@ NTSTATUS TCPReceiveData
|
||||||
UINT DataLen, Received = 0;
|
UINT DataLen, Received = 0;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PTDI_BUCKET Bucket;
|
PTDI_BUCKET Bucket;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
|
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
|
||||||
ReceiveLength, Connection->SocketContext));
|
ReceiveLength, Connection->SocketContext));
|
||||||
|
|
||||||
ASSERT_KM_POINTER(Connection->SocketContext);
|
|
||||||
|
|
||||||
NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
|
NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
|
TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
|
ASSERT_KM_POINTER(Connection->SocketContext);
|
||||||
|
|
||||||
Status = TCPTranslateError
|
Status = TCPTranslateError
|
||||||
( OskitTCPRecv
|
( OskitTCPRecv
|
||||||
|
@ -746,7 +760,7 @@ NTSTATUS TCPReceiveData
|
||||||
&Received,
|
&Received,
|
||||||
ReceiveFlags ) );
|
ReceiveFlags ) );
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received));
|
TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received));
|
||||||
|
|
||||||
|
@ -763,9 +777,8 @@ NTSTATUS TCPReceiveData
|
||||||
Bucket->Request.RequestContext = Context;
|
Bucket->Request.RequestContext = Context;
|
||||||
*BytesReceived = 0;
|
*BytesReceived = 0;
|
||||||
|
|
||||||
IoMarkIrpPending((PIRP)Context);
|
ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry,
|
||||||
|
&Connection->Lock );
|
||||||
ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Queued read irp\n"));
|
TI_DbgPrint(DEBUG_TCP,("Queued read irp\n"));
|
||||||
} else {
|
} else {
|
||||||
TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received));
|
TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received));
|
||||||
|
@ -788,8 +801,9 @@ NTSTATUS TCPSendData
|
||||||
UINT Sent = 0;
|
UINT Sent = 0;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PTDI_BUCKET Bucket;
|
PTDI_BUCKET Bucket;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
ASSERT_LOCKED(&TCPLock);
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
|
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
|
||||||
SendLength, Connection->SocketContext));
|
SendLength, Connection->SocketContext));
|
||||||
|
@ -800,14 +814,12 @@ NTSTATUS TCPSendData
|
||||||
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
|
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
|
||||||
Connection->SocketContext));
|
Connection->SocketContext));
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
|
||||||
|
|
||||||
Status = TCPTranslateError
|
Status = TCPTranslateError
|
||||||
( OskitTCPSend( Connection->SocketContext,
|
( OskitTCPSend( Connection->SocketContext,
|
||||||
(OSK_PCHAR)BufferData, SendLength,
|
(OSK_PCHAR)BufferData, SendLength,
|
||||||
&Sent, 0 ) );
|
&Sent, 0 ) );
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent));
|
TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent));
|
||||||
|
|
||||||
|
@ -823,10 +835,9 @@ NTSTATUS TCPSendData
|
||||||
Bucket->Request.RequestNotifyObject = Complete;
|
Bucket->Request.RequestNotifyObject = Complete;
|
||||||
Bucket->Request.RequestContext = Context;
|
Bucket->Request.RequestContext = Context;
|
||||||
*BytesSent = 0;
|
*BytesSent = 0;
|
||||||
|
|
||||||
IoMarkIrpPending((PIRP)Context);
|
|
||||||
|
|
||||||
ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
|
ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry,
|
||||||
|
&Connection->Lock );
|
||||||
TI_DbgPrint(DEBUG_TCP,("Queued write irp\n"));
|
TI_DbgPrint(DEBUG_TCP,("Queued write irp\n"));
|
||||||
} else {
|
} else {
|
||||||
TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
|
TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
|
||||||
|
@ -865,14 +876,15 @@ NTSTATUS TCPGetSockAddress
|
||||||
OSK_UI16 LocalPort, RemotePort;
|
OSK_UI16 LocalPort, RemotePort;
|
||||||
PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
|
PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
TcpipRecursiveMutexEnter(&TCPLock);
|
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||||
|
|
||||||
Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext,
|
Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext,
|
||||||
&LocalAddress, &LocalPort,
|
&LocalAddress, &LocalPort,
|
||||||
&RemoteAddress, &RemotePort));
|
&RemoteAddress, &RemotePort));
|
||||||
|
|
||||||
TcpipRecursiveMutexLeave(&TCPLock);
|
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -172,6 +172,9 @@ NTSTATUS UDPSendDatagram(
|
||||||
USHORT RemotePort;
|
USHORT RemotePort;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
|
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
|
||||||
AddrFile, ConnInfo, BufferData, DataSize));
|
AddrFile, ConnInfo, BufferData, DataSize));
|
||||||
|
@ -186,10 +189,12 @@ NTSTATUS UDPSendDatagram(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
|
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
return STATUS_NETWORK_UNREACHABLE;
|
return STATUS_NETWORK_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,14 +218,20 @@ NTSTATUS UDPSendDatagram(
|
||||||
DataSize );
|
DataSize );
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) )
|
if( !NT_SUCCESS(Status) )
|
||||||
|
{
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
return Status;
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
|
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
|
||||||
{
|
{
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
FreeNdisPacket(Packet.NdisPacket);
|
FreeNdisPacket(Packet.NdisPacket);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ extern int OskitTCPSend( void *socket,
|
||||||
OSK_UINT *OutLen,
|
OSK_UINT *OutLen,
|
||||||
OSK_UINT Flags );
|
OSK_UINT Flags );
|
||||||
|
|
||||||
extern int OskitTCPConnect( void *socket, void *connection,
|
extern int OskitTCPConnect( void *socket,
|
||||||
void *nam, OSK_UINT namelen );
|
void *nam, OSK_UINT namelen );
|
||||||
extern int OskitTCPClose( void *socket );
|
extern int OskitTCPClose( void *socket );
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ extern int OskitTCPBind( void *socket,
|
||||||
void *nam, OSK_UINT namelen );
|
void *nam, OSK_UINT namelen );
|
||||||
|
|
||||||
extern int OskitTCPAccept( void *socket, void **new_socket,
|
extern int OskitTCPAccept( void *socket, void **new_socket,
|
||||||
void *addr_out,
|
void *context, void *addr_out,
|
||||||
OSK_UINT addr_len,
|
OSK_UINT addr_len,
|
||||||
OSK_UINT *out_addr_len,
|
OSK_UINT *out_addr_len,
|
||||||
OSK_UINT finish_accept );
|
OSK_UINT finish_accept );
|
||||||
|
@ -187,4 +187,27 @@ void fbsd_free( void *data, char *file, unsigned line, ... );
|
||||||
#define FREAD 0x0001
|
#define FREAD 0x0001
|
||||||
#define FWRITE 0x0002
|
#define FWRITE 0x0002
|
||||||
|
|
||||||
|
/* Don't define this unless your are insane or aicom */
|
||||||
|
//#define LOCK_SPAM
|
||||||
|
|
||||||
|
#ifdef LOCK_SPAM
|
||||||
|
#define OSKLock() if (!KeTryToAcquireSpinLockAtDpcLevel(&OSKLock)) \
|
||||||
|
{ \
|
||||||
|
DbgPrint("OSKLock WAIT (%s)\n", __FUNCTION__); \
|
||||||
|
KeAcquireSpinLockAtDpcLevel(&OSKLock); \
|
||||||
|
} \
|
||||||
|
DbgPrint("OSKLock >>>> (%s)\n", __FUNCTION__)
|
||||||
|
|
||||||
|
#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock); \
|
||||||
|
DbgPrint("OSKLock <<<< (%s)\n", __FUNCTION__)
|
||||||
|
#else
|
||||||
|
#define OSKLock() KeAcquireSpinLockAtDpcLevel(&OSKLock)
|
||||||
|
#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define OSKLockAndRaise(x) KeRaiseIrql(DISPATCH_LEVEL, x); \
|
||||||
|
OSKLock()
|
||||||
|
#define OSKUnlockAndLower(x) OSKUnlock(); \
|
||||||
|
KeLowerIrql(x)
|
||||||
|
|
||||||
#endif/*OSKITTCP_H*/
|
#endif/*OSKITTCP_H*/
|
||||||
|
|
|
@ -23,6 +23,8 @@ 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;
|
||||||
|
|
||||||
|
KSPIN_LOCK OSKLock;
|
||||||
|
|
||||||
/* SPL */
|
/* SPL */
|
||||||
unsigned cpl;
|
unsigned cpl;
|
||||||
unsigned net_imask;
|
unsigned net_imask;
|
||||||
|
@ -45,6 +47,7 @@ void fbsd_free( void *data, char *file, unsigned line, ... ) {
|
||||||
|
|
||||||
void InitOskitTCP() {
|
void InitOskitTCP() {
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Init Called\n"));
|
OS_DbgPrint(OSK_MID_TRACE,("Init Called\n"));
|
||||||
|
KeInitializeSpinLock(&OSKLock);
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("MB Init\n"));
|
OS_DbgPrint(OSK_MID_TRACE,("MB Init\n"));
|
||||||
mbinit();
|
mbinit();
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n"));
|
OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n"));
|
||||||
|
@ -66,12 +69,19 @@ void DeinitOskitTCP() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerOskitTCP( int FastTimer, int SlowTimer ) {
|
void TimerOskitTCP( int FastTimer, int SlowTimer ) {
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* This function is a special case in which we cannot use OSKLock/OSKUnlock
|
||||||
|
* because we don't enter with the connection lock held */
|
||||||
|
|
||||||
|
OSKLockAndRaise(&OldIrql);
|
||||||
if ( SlowTimer ) {
|
if ( SlowTimer ) {
|
||||||
tcp_slowtimo();
|
tcp_slowtimo();
|
||||||
}
|
}
|
||||||
if ( FastTimer ) {
|
if ( FastTimer ) {
|
||||||
tcp_fasttimo();
|
tcp_fasttimo();
|
||||||
}
|
}
|
||||||
|
OSKUnlockAndLower(OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) {
|
void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) {
|
||||||
|
@ -115,12 +125,16 @@ int OskitTCPSocket( void *context,
|
||||||
int proto )
|
int proto )
|
||||||
{
|
{
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
int error = socreate(domain, &so, type, proto);
|
int error = socreate(domain, &so, type, proto);
|
||||||
if( !error ) {
|
if( !error ) {
|
||||||
so->so_connection = context;
|
so->so_connection = context;
|
||||||
so->so_state |= SS_NBIO;
|
so->so_state |= SS_NBIO;
|
||||||
*aso = so;
|
*aso = so;
|
||||||
}
|
}
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,8 +167,11 @@ int OskitTCPRecv( void *connection,
|
||||||
|
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
|
OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */,
|
error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */,
|
||||||
&tcp_flags );
|
&tcp_flags );
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
*OutLen = Len - uio.uio_resid;
|
*OutLen = Len - uio.uio_resid;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -182,14 +199,15 @@ int OskitTCPBind( void *socket,
|
||||||
addr.sa_family = addr.sa_len;
|
addr.sa_family = addr.sa_len;
|
||||||
addr.sa_len = sizeof(struct sockaddr);
|
addr.sa_len = sizeof(struct sockaddr);
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
error = sobind(so, &sabuf);
|
error = sobind(so, &sabuf);
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int OskitTCPConnect( void *socket, void *connection,
|
int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) {
|
||||||
void *nam, OSK_UINT namelen ) {
|
|
||||||
struct socket *so = socket;
|
struct socket *so = socket;
|
||||||
int error = EFAULT;
|
int error = EFAULT;
|
||||||
struct mbuf sabuf;
|
struct mbuf sabuf;
|
||||||
|
@ -197,8 +215,7 @@ int OskitTCPConnect( void *socket, void *connection,
|
||||||
|
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
|
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
|
||||||
|
|
||||||
so->so_connection = connection;
|
OSKLock();
|
||||||
|
|
||||||
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
|
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
|
||||||
error = EALREADY;
|
error = EALREADY;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -217,7 +234,9 @@ int OskitTCPConnect( void *socket, void *connection,
|
||||||
|
|
||||||
error = soconnect(so, &sabuf);
|
error = soconnect(so, &sabuf);
|
||||||
|
|
||||||
if (error)
|
if (error == EINPROGRESS)
|
||||||
|
goto done;
|
||||||
|
else if (error)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
|
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
|
||||||
|
@ -232,34 +251,49 @@ bad:
|
||||||
error = EINTR;
|
error = EINTR;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
OSKUnlock();
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int OskitTCPDisconnect(void *socket)
|
int OskitTCPDisconnect(void *socket)
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return OSK_ESHUTDOWN;
|
return OSK_ESHUTDOWN;
|
||||||
|
|
||||||
return sodisconnect(socket);
|
OSKLock();
|
||||||
|
error = sodisconnect(socket);
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OskitTCPShutdown( void *socket, int disconn_type ) {
|
int OskitTCPShutdown( void *socket, int disconn_type ) {
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return OSK_ESHUTDOWN;
|
return OSK_ESHUTDOWN;
|
||||||
|
|
||||||
return soshutdown( socket, disconn_type );
|
OSKLock();
|
||||||
|
error = soshutdown( socket, disconn_type );
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OskitTCPClose( void *socket ) {
|
int OskitTCPClose( void *socket ) {
|
||||||
struct socket *so = socket;
|
int error;
|
||||||
|
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return OSK_ESHUTDOWN;
|
return OSK_ESHUTDOWN;
|
||||||
|
|
||||||
so->so_connection = 0;
|
OSKLock();
|
||||||
soclose( so );
|
error = soclose( socket );
|
||||||
return 0;
|
OSKUnlock();
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
|
int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
|
||||||
|
@ -281,7 +315,10 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
|
||||||
uio.uio_rw = UIO_WRITE;
|
uio.uio_rw = UIO_WRITE;
|
||||||
uio.uio_procp = NULL;
|
uio.uio_procp = NULL;
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
error = sosend( socket, NULL, &uio, NULL, NULL, 0 );
|
error = sosend( socket, NULL, &uio, NULL, NULL, 0 );
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
*OutLen = Len - uio.uio_resid;
|
*OutLen = Len - uio.uio_resid;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -289,6 +326,7 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
|
||||||
|
|
||||||
int OskitTCPAccept( void *socket,
|
int OskitTCPAccept( void *socket,
|
||||||
void **new_socket,
|
void **new_socket,
|
||||||
|
void *context,
|
||||||
void *AddrOut,
|
void *AddrOut,
|
||||||
OSK_UINT AddrLen,
|
OSK_UINT AddrLen,
|
||||||
OSK_UINT *OutAddrLen,
|
OSK_UINT *OutAddrLen,
|
||||||
|
@ -317,11 +355,12 @@ int OskitTCPAccept( void *socket,
|
||||||
/* that's a copyin actually */
|
/* that's a copyin actually */
|
||||||
namelen = *OutAddrLen;
|
namelen = *OutAddrLen;
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
|
|
||||||
s = splnet();
|
s = splnet();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ((head->so_options & SO_ACCEPTCONN) == 0) {
|
if ((head->so_options & SO_ACCEPTCONN) == 0) {
|
||||||
splx(s);
|
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
|
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
|
||||||
head->so_options, SO_ACCEPTCONN));
|
head->so_options, SO_ACCEPTCONN));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
|
@ -333,39 +372,10 @@ int OskitTCPAccept( void *socket,
|
||||||
head->so_q, head->so_state));
|
head->so_q, head->so_state));
|
||||||
|
|
||||||
if ((head->so_state & SS_NBIO) && head->so_q == NULL) {
|
if ((head->so_state & SS_NBIO) && head->so_q == NULL) {
|
||||||
splx(s);
|
|
||||||
error = EWOULDBLOCK;
|
error = EWOULDBLOCK;
|
||||||
goto out;
|
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
|
* At this point we know that there is at least one connection
|
||||||
* ready to be accepted. Remove it from the queue.
|
* ready to be accepted. Remove it from the queue.
|
||||||
|
@ -384,19 +394,20 @@ int OskitTCPAccept( void *socket,
|
||||||
head->so_q = so->so_q;
|
head->so_q = so->so_q;
|
||||||
head->so_qlen--;
|
head->so_qlen--;
|
||||||
|
|
||||||
*newso = so;
|
|
||||||
|
|
||||||
/*so->so_state &= ~SS_COMP;*/
|
|
||||||
|
|
||||||
mnam.m_data = (char *)&sa;
|
mnam.m_data = (char *)&sa;
|
||||||
mnam.m_len = sizeof(sa);
|
mnam.m_len = sizeof(sa);
|
||||||
|
|
||||||
(void) soaccept(so, &mnam);
|
error = soaccept(so, &mnam);
|
||||||
|
if (error)
|
||||||
|
goto out;
|
||||||
|
|
||||||
so->so_state = SS_NBIO | SS_ISCONNECTED;
|
so->so_state |= SS_NBIO | SS_ISCONNECTED;
|
||||||
so->so_q = so->so_q0 = NULL;
|
so->so_q = so->so_q0 = NULL;
|
||||||
so->so_qlen = 0;
|
so->so_qlen = 0;
|
||||||
so->so_head = 0;
|
so->so_head = 0;
|
||||||
|
so->so_connection = context;
|
||||||
|
|
||||||
|
*newso = so;
|
||||||
|
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
if (name) {
|
if (name) {
|
||||||
|
@ -406,9 +417,10 @@ int OskitTCPAccept( void *socket,
|
||||||
*OutAddrLen = namelen; /* copyout actually */
|
*OutAddrLen = namelen; /* copyout actually */
|
||||||
}
|
}
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||||
splx(s);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
splx(s);
|
||||||
|
OSKUnlock();
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error));
|
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error));
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
@ -421,10 +433,20 @@ out:
|
||||||
|
|
||||||
void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
|
void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
|
||||||
OSK_UINT IpHeaderLen ) {
|
OSK_UINT IpHeaderLen ) {
|
||||||
struct mbuf *Ip = m_devget( (char *)Data, Len, 0, NULL, NULL );
|
struct mbuf *Ip;
|
||||||
struct ip *iph;
|
struct ip *iph;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
if( !Ip ) return; /* drop the segment */
|
/* This function is a special case in which we cannot use OSKLock/OSKUnlock
|
||||||
|
* because we don't enter with the connection lock held */
|
||||||
|
|
||||||
|
OSKLockAndRaise(&OldIrql);
|
||||||
|
Ip = m_devget( (char *)Data, Len, 0, NULL, NULL );
|
||||||
|
if( !Ip )
|
||||||
|
{
|
||||||
|
OSKUnlockAndLower(OldIrql);
|
||||||
|
return; /* drop the segment */
|
||||||
|
}
|
||||||
|
|
||||||
//memcpy( Ip->m_data, Data, Len );
|
//memcpy( Ip->m_data, Data, Len );
|
||||||
Ip->m_pkthdr.len = IpHeaderLen;
|
Ip->m_pkthdr.len = IpHeaderLen;
|
||||||
|
@ -439,6 +461,7 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
|
||||||
IpHeaderLen));
|
IpHeaderLen));
|
||||||
|
|
||||||
tcp_input(Ip, IpHeaderLen);
|
tcp_input(Ip, IpHeaderLen);
|
||||||
|
OSKUnlockAndLower(OldIrql);
|
||||||
|
|
||||||
/* The buffer Ip is freed by tcp_input */
|
/* The buffer Ip is freed by tcp_input */
|
||||||
}
|
}
|
||||||
|
@ -450,6 +473,7 @@ int OskitTCPSetSockOpt(void *socket,
|
||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return OSK_ESHUTDOWN;
|
return OSK_ESHUTDOWN;
|
||||||
|
@ -457,16 +481,23 @@ int OskitTCPSetSockOpt(void *socket,
|
||||||
if (size >= MLEN)
|
if (size >= MLEN)
|
||||||
return OSK_EINVAL;
|
return OSK_EINVAL;
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
m = m_get(M_WAIT, MT_SOOPTS);
|
m = m_get(M_WAIT, MT_SOOPTS);
|
||||||
if (!m)
|
if (!m)
|
||||||
|
{
|
||||||
|
OSKUnlock();
|
||||||
return OSK_ENOMEM;
|
return OSK_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
m->m_len = size;
|
m->m_len = size;
|
||||||
|
|
||||||
memcpy(m->m_data, buffer, size);
|
memcpy(m->m_data, buffer, size);
|
||||||
|
|
||||||
/* m is freed by sosetopt */
|
/* m is freed by sosetopt */
|
||||||
return sosetopt(socket, level, optname, m);
|
error = sosetopt(socket, level, optname, m);
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OskitTCPGetSockOpt(void *socket,
|
int OskitTCPGetSockOpt(void *socket,
|
||||||
|
@ -481,6 +512,7 @@ int OskitTCPGetSockOpt(void *socket,
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return OSK_ESHUTDOWN;
|
return OSK_ESHUTDOWN;
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
error = sogetopt(socket, level, optname, &m);
|
error = sogetopt(socket, level, optname, &m);
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
|
@ -489,6 +521,7 @@ int OskitTCPGetSockOpt(void *socket,
|
||||||
if (!buffer || oldsize < m->m_len)
|
if (!buffer || oldsize < m->m_len)
|
||||||
{
|
{
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
|
OSKUnlock();
|
||||||
return OSK_EINVAL;
|
return OSK_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,6 +529,7 @@ int OskitTCPGetSockOpt(void *socket,
|
||||||
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
}
|
}
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -507,7 +541,11 @@ int OskitTCPListen( void *socket, int backlog ) {
|
||||||
return OSK_ESHUTDOWN;
|
return OSK_ESHUTDOWN;
|
||||||
|
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
|
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
error = solisten( socket, backlog );
|
error = solisten( socket, backlog );
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -524,11 +562,13 @@ int OskitTCPSetAddress( void *socket,
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return OSK_ESHUTDOWN;
|
return OSK_ESHUTDOWN;
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
inp = (struct inpcb *)so->so_pcb;
|
inp = (struct inpcb *)so->so_pcb;
|
||||||
inp->inp_laddr.s_addr = LocalAddress;
|
inp->inp_laddr.s_addr = LocalAddress;
|
||||||
inp->inp_lport = LocalPort;
|
inp->inp_lport = LocalPort;
|
||||||
inp->inp_faddr.s_addr = RemoteAddress;
|
inp->inp_faddr.s_addr = RemoteAddress;
|
||||||
inp->inp_fport = RemotePort;
|
inp->inp_fport = RemotePort;
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -544,11 +584,13 @@ int OskitTCPGetAddress( void *socket,
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return OSK_ESHUTDOWN;
|
return OSK_ESHUTDOWN;
|
||||||
|
|
||||||
|
OSKLock();
|
||||||
inp = (struct inpcb *)so->so_pcb;
|
inp = (struct inpcb *)so->so_pcb;
|
||||||
*LocalAddress = inp->inp_laddr.s_addr;
|
*LocalAddress = inp->inp_laddr.s_addr;
|
||||||
*LocalPort = inp->inp_lport;
|
*LocalPort = inp->inp_lport;
|
||||||
*RemoteAddress = inp->inp_faddr.s_addr;
|
*RemoteAddress = inp->inp_faddr.s_addr;
|
||||||
*RemotePort = inp->inp_fport;
|
*RemotePort = inp->inp_fport;
|
||||||
|
OSKUnlock();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue