mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 23:32:59 +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 KSPIN_LOCK ConnectionEndpointListLock;
|
||||
|
||||
|
||||
NTSTATUS FileOpenAddress(
|
||||
PTDI_REQUEST Request,
|
||||
PTA_IP_ADDRESS AddrList,
|
||||
|
@ -27,8 +26,6 @@ NTSTATUS FileOpenConnection(
|
|||
PTDI_REQUEST Request,
|
||||
PVOID ClientContext);
|
||||
|
||||
PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context );
|
||||
|
||||
NTSTATUS FileCloseConnection(
|
||||
PTDI_REQUEST Request);
|
||||
|
||||
|
|
|
@ -84,11 +84,6 @@ typedef struct _SLEEPING_THREAD {
|
|||
#define SRF_FIN TCP_FIN
|
||||
|
||||
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 */
|
||||
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
||||
|
@ -105,7 +100,6 @@ NTSTATUS TCPAccept
|
|||
PVOID Context );
|
||||
|
||||
/* tcp.c */
|
||||
ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection );
|
||||
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext );
|
||||
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
|
||||
|
||||
|
|
|
@ -153,7 +153,6 @@ typedef struct _ADDRESS_FILE {
|
|||
LIST_ENTRY ListEntry; /* Entry on list */
|
||||
KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */
|
||||
OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */
|
||||
USHORT Flags; /* Flags for address file (see below) */
|
||||
IP_ADDRESS Address; /* Address of this address file */
|
||||
USHORT Family; /* Address family */
|
||||
USHORT Protocol; /* Protocol number */
|
||||
|
@ -213,29 +212,6 @@ typedef struct _ADDRESS_FILE {
|
|||
BOOLEAN RegisteredChainedReceiveExpeditedHandler;
|
||||
} 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 */
|
||||
typedef struct _AF_SEARCH {
|
||||
PLIST_ENTRY Next; /* Next address file to check */
|
||||
|
@ -306,8 +282,6 @@ typedef struct _CONNECTION_ENDPOINT {
|
|||
LIST_ENTRY SendRequest; /* Queued send requests */
|
||||
|
||||
/* Signals */
|
||||
LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for
|
||||
* notification service to the client */
|
||||
UINT SignalState; /* Active signals from oskit */
|
||||
} 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">
|
||||
<file>lan.c</file>
|
||||
</directory>
|
||||
<directory name="recmutex">
|
||||
<file>recmutex.c</file>
|
||||
</directory>
|
||||
<directory name="tcpip">
|
||||
<file>ainfo.c</file>
|
||||
<file>buffer.c</file>
|
||||
|
|
|
@ -210,9 +210,8 @@ VOID NTAPI DispCancelListenRequest(
|
|||
|
||||
TCPRemoveIRP(Connection, Irp);
|
||||
|
||||
TCPAbortListenForSocket(
|
||||
Connection->AddressFile->Listener,
|
||||
Connection );
|
||||
TCPAbortListenForSocket(Connection->AddressFile->Listener,
|
||||
Connection);
|
||||
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
|
||||
|
@ -1044,7 +1043,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
|
|||
Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
|
||||
/* Set the event handler. if an event handler is associated with
|
||||
a specific event, it's flag (RegisteredXxxHandler) is TRUE.
|
||||
|
@ -1165,7 +1164,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
|
|||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -295,9 +295,6 @@ NTSTATUS FileOpenAddress(
|
|||
/* Initialize spin lock that protects the address file object */
|
||||
KeInitializeSpinLock(&AddrFile->Lock);
|
||||
|
||||
/* Set valid flag so the address can be used */
|
||||
AF_SET_VALID(AddrFile);
|
||||
|
||||
/* Return address file object */
|
||||
Request->Handle.AddressHandle = AddrFile;
|
||||
|
||||
|
@ -328,7 +325,7 @@ NTSTATUS FileCloseAddress(
|
|||
KIRQL OldIrql;
|
||||
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
|
||||
PDATAGRAM_SEND_REQUEST SendRequest;
|
||||
PLIST_ENTRY CurrentEntry, NextEntry;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
|
||||
AddrFile = Request->Handle.AddressHandle;
|
||||
|
||||
|
@ -339,8 +336,6 @@ NTSTATUS FileCloseAddress(
|
|||
RemoveEntryList(&AddrFile->ListEntry);
|
||||
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
|
||||
|
||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
|
||||
/* FIXME: Kill TCP connections on this address file object */
|
||||
|
||||
/* 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));
|
||||
|
||||
/* Go through pending receive request list and cancel them all */
|
||||
CurrentEntry = AddrFile->ReceiveQueue.Flink;
|
||||
while (CurrentEntry != &AddrFile->ReceiveQueue) {
|
||||
NextEntry = CurrentEntry->Flink;
|
||||
while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
|
||||
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);
|
||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
CurrentEntry = NextEntry;
|
||||
/* exFreePool(ReceiveRequest); FIXME: WTF? */
|
||||
}
|
||||
|
||||
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 */
|
||||
CurrentEntry = AddrFile->TransmitQueue.Flink;
|
||||
while (CurrentEntry != &AddrFile->TransmitQueue) {
|
||||
NextEntry = CurrentEntry->Flink;
|
||||
SendRequest = CONTAINING_RECORD(CurrentEntry,
|
||||
DATAGRAM_SEND_REQUEST, ListEntry);
|
||||
/* Abort the request and free its resources */
|
||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
|
||||
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
|
||||
(*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0);
|
||||
exFreePool(SendRequest);
|
||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
CurrentEntry = NextEntry;
|
||||
}
|
||||
|
||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
|
||||
/* Protocol specific handling */
|
||||
switch (AddrFile->Protocol) {
|
||||
case IPPROTO_TCP:
|
||||
TCPFreePort( AddrFile->Port );
|
||||
if( AddrFile->Listener ) {
|
||||
TCPClose( AddrFile->Listener );
|
||||
exFreePool( AddrFile->Listener );
|
||||
}
|
||||
if( AddrFile->Listener )
|
||||
TCPClose( AddrFile->Listener );
|
||||
break;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
|
@ -433,48 +412,11 @@ NTSTATUS FileOpenConnection(
|
|||
/* Return connection endpoint file object */
|
||||
Request->Handle.ConnectionContext = Connection;
|
||||
|
||||
/* Add connection endpoint to global list */
|
||||
ExInterlockedInsertTailList(
|
||||
&ConnectionEndpointListHead,
|
||||
&Connection->ListEntry,
|
||||
&ConnectionEndpointListLock);
|
||||
|
||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||
|
||||
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
|
||||
* ARGUMENTS:
|
||||
|
@ -486,20 +428,13 @@ NTSTATUS FileCloseConnection(
|
|||
PTDI_REQUEST Request)
|
||||
{
|
||||
PCONNECTION_ENDPOINT Connection;
|
||||
KIRQL OldIrql;
|
||||
|
||||
TI_DbgPrint(MID_TRACE, ("Called.\n"));
|
||||
|
||||
Connection = Request->Handle.ConnectionContext;
|
||||
|
||||
TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
|
||||
RemoveEntryList(&Connection->ListEntry);
|
||||
TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
|
||||
|
||||
TCPClose( Connection );
|
||||
|
||||
TCPFreeConnectionEndpoint(Connection);
|
||||
|
||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -44,16 +44,3 @@ VOID TcpipReleaseFastMutex( PFAST_MUTEX 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 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"));
|
||||
|
||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
|
||||
if (AddrFile->Protocol == IPPROTO_UDP)
|
||||
{
|
||||
|
@ -136,7 +136,7 @@ VOID DGDeliverData(
|
|||
&SrcAddress->Address.IPv4Address,
|
||||
sizeof(SrcAddress->Address.IPv4Address) );
|
||||
|
||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
|
||||
/* Complete the receive request */
|
||||
if (Current->BufferSize < DataSize)
|
||||
|
@ -144,11 +144,11 @@ VOID DGDeliverData(
|
|||
else
|
||||
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)
|
||||
{
|
||||
|
@ -157,8 +157,6 @@ VOID DGDeliverData(
|
|||
ReceiveHandler = AddrFile->ReceiveDatagramHandler;
|
||||
HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
|
||||
|
||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
|
||||
if (SrcAddress->Type == IP_ADDRESS_V4)
|
||||
{
|
||||
AddressLength = sizeof(IPv4_RAW_ADDRESS);
|
||||
|
@ -170,6 +168,8 @@ VOID DGDeliverData(
|
|||
SourceAddress = SrcAddress->Address.IPv6Address;
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
|
||||
Status = (*ReceiveHandler)(HandlerContext,
|
||||
AddressLength,
|
||||
SourceAddress,
|
||||
|
@ -184,7 +184,7 @@ VOID DGDeliverData(
|
|||
}
|
||||
else
|
||||
{
|
||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
|
||||
}
|
||||
|
||||
|
@ -228,76 +228,67 @@ NTSTATUS DGReceiveDatagram(
|
|||
* This is the high level interface for receiving DG datagrams
|
||||
*/
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
NTSTATUS Status;
|
||||
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
|
||||
KIRQL OldIrql;
|
||||
|
||||
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));
|
||||
if (ReceiveRequest)
|
||||
/* Initialize a receive request */
|
||||
|
||||
/* Extract the remote address filter from the request (if any) */
|
||||
if ((ConnInfo->RemoteAddressLength != 0) &&
|
||||
(ConnInfo->RemoteAddress))
|
||||
{
|
||||
/* Initialize a receive request */
|
||||
|
||||
/* Extract the remote address filter from the request (if any) */
|
||||
if ((ConnInfo->RemoteAddressLength != 0) &&
|
||||
(ConnInfo->RemoteAddress))
|
||||
Status = AddrGetAddress(ConnInfo->RemoteAddress,
|
||||
&ReceiveRequest->RemoteAddress,
|
||||
&ReceiveRequest->RemotePort);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Status = AddrGetAddress(ConnInfo->RemoteAddress,
|
||||
&ReceiveRequest->RemoteAddress,
|
||||
&ReceiveRequest->RemotePort);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
exFreePool(ReceiveRequest);
|
||||
return Status;
|
||||
}
|
||||
exFreePool(ReceiveRequest);
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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));
|
||||
|
||||
return Status;
|
||||
|
|
|
@ -195,6 +195,9 @@ NTSTATUS RawIPSendDatagram(
|
|||
USHORT RemotePort;
|
||||
NTSTATUS Status;
|
||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||
KIRQL OldIrql;
|
||||
|
||||
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
|
||||
AddrFile, ConnInfo, BufferData, DataSize));
|
||||
|
@ -209,13 +212,17 @@ NTSTATUS RawIPSendDatagram(
|
|||
break;
|
||||
|
||||
default:
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
|
||||
|
||||
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress )))
|
||||
{
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
return STATUS_NETWORK_UNREACHABLE;
|
||||
}
|
||||
|
||||
LocalAddress = AddrFile->Address;
|
||||
if (AddrIsUnspecified(&LocalAddress))
|
||||
|
@ -237,18 +244,24 @@ NTSTATUS RawIPSendDatagram(
|
|||
DataSize );
|
||||
|
||||
if( !NT_SUCCESS(Status) )
|
||||
{
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
return Status;
|
||||
}
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
|
||||
|
||||
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL )))
|
||||
{
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
FreeNdisPacket(Packet.NdisPacket);
|
||||
return Status;
|
||||
}
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Leaving\n"));
|
||||
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
/* Listener->Lock MUST be acquired */
|
||||
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
||||
PCONNECTION_ENDPOINT Connection,
|
||||
PTDI_REQUEST_KERNEL Request ) {
|
||||
|
@ -26,18 +27,15 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
|||
WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)
|
||||
Request->ReturnConnectionInformation;
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
|
||||
Status = TCPTranslateError
|
||||
( OskitTCPAccept( Listener->SocketContext,
|
||||
&Connection->SocketContext,
|
||||
Connection,
|
||||
&OutAddr,
|
||||
sizeof(OutAddr),
|
||||
&OutAddrLen,
|
||||
Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) );
|
||||
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
|
||||
|
||||
if( NT_SUCCESS(Status) && Status != STATUS_PENDING ) {
|
||||
|
@ -71,11 +69,14 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
|||
NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
SOCKADDR_IN AddressToBind;
|
||||
KIRQL OldIrql;
|
||||
|
||||
ASSERT(Connection);
|
||||
ASSERT_KM_POINTER(Connection->SocketContext);
|
||||
ASSERT_KM_POINTER(Connection->AddressFile);
|
||||
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("TCPListen started\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));
|
||||
|
||||
TcpipRecursiveMutexEnter( &TCPLock );
|
||||
|
||||
Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext,
|
||||
&AddressToBind,
|
||||
sizeof(AddressToBind) ) );
|
||||
|
@ -98,7 +97,7 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
|||
if (NT_SUCCESS(Status))
|
||||
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
|
||||
|
||||
TcpipRecursiveMutexLeave( &TCPLock );
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
|
||||
|
||||
|
@ -137,12 +136,17 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
|
|||
{
|
||||
NTSTATUS Status;
|
||||
PTDI_BUCKET Bucket;
|
||||
KIRQL OldIrql;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
|
||||
|
||||
KeAcquireSpinLock(&Listener->Lock, &OldIrql);
|
||||
|
||||
Status = TCPServiceListeningSocket( Listener, Connection,
|
||||
(PTDI_REQUEST_KERNEL)Request );
|
||||
|
||||
KeReleaseSpinLock(&Listener->Lock, OldIrql);
|
||||
|
||||
if( Status == STATUS_PENDING ) {
|
||||
Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
|
||||
|
||||
|
@ -150,8 +154,8 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
|
|||
Bucket->AssociatedEndpoint = Connection;
|
||||
Bucket->Request.RequestNotifyObject = Complete;
|
||||
Bucket->Request.RequestContext = Context;
|
||||
IoMarkIrpPending((PIRP)Context);
|
||||
ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, &Listener->Lock );
|
||||
ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry,
|
||||
&Listener->Lock );
|
||||
} else
|
||||
Status = STATUS_NO_MEMORY;
|
||||
}
|
||||
|
|
|
@ -15,56 +15,30 @@ int TCPSocketState(void *ClientData,
|
|||
void *WhichConnection,
|
||||
OSK_UINT NewState ) {
|
||||
PCONNECTION_ENDPOINT Connection = WhichConnection;
|
||||
ULONG OldState;
|
||||
KIRQL OldIrql;
|
||||
|
||||
ASSERT_LOCKED(&TCPLock);
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n",
|
||||
TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n",
|
||||
Connection,
|
||||
NewState & SEL_CONNECT ? 'C' : 'c',
|
||||
NewState & SEL_READ ? 'R' : 'r',
|
||||
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",
|
||||
NewState, Connection,
|
||||
Connection ? Connection->SignalState ^ NewState :
|
||||
Connection->SignalState ^ 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;
|
||||
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
|
||||
/* 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);
|
||||
KeReleaseSpinLockFromDpcLevel(&Connection->Lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -86,8 +60,6 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
|
|||
IP_ADDRESS RemoteAddress, LocalAddress;
|
||||
PIPv4_HEADER Header;
|
||||
|
||||
ASSERT_LOCKED(&TCPLock);
|
||||
|
||||
if( *data == 0x45 ) { /* IPv4 */
|
||||
Header = (PIPv4_HEADER)data;
|
||||
LocalAddress.Type = IP_ADDRESS_V4;
|
||||
|
@ -181,8 +153,6 @@ void *TCPMalloc( void *ClientData,
|
|||
void *v;
|
||||
ULONG Signature;
|
||||
|
||||
ASSERT_LOCKED(&TCPLock);
|
||||
|
||||
#if 0 != MEM_PROFILE
|
||||
static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0;
|
||||
static OSK_UINT ArrayUsed = 0, AllocationCount = 0;
|
||||
|
@ -258,8 +228,6 @@ void TCPFree( void *ClientData,
|
|||
void *data, OSK_PCHAR File, OSK_UINT Line ) {
|
||||
ULONG Signature;
|
||||
|
||||
ASSERT_LOCKED(&TCPLock);
|
||||
|
||||
UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') );
|
||||
data = (void *)((char *) data - sizeof(ULONG));
|
||||
Signature = *((ULONG *) data);
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
LONG TCP_IPIdentification = 0;
|
||||
static BOOLEAN TCPInitialized = FALSE;
|
||||
static NPAGED_LOOKASIDE_LIST TCPSegmentList;
|
||||
LIST_ENTRY SignalledConnectionsList;
|
||||
KSPIN_LOCK SignalledConnectionsLock;
|
||||
RECURSIVE_MUTEX TCPLock;
|
||||
PORT_SET TCPPorts;
|
||||
|
||||
ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
|
||||
static VOID DrainSignals() {
|
||||
PCONNECTION_ENDPOINT Connection;
|
||||
PLIST_ENTRY CurrentEntry, NextEntry;
|
||||
KIRQL OldIrql;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PTCP_COMPLETION_ROUTINE Complete;
|
||||
PTDI_BUCKET Bucket;
|
||||
|
@ -28,279 +28,290 @@ ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
|
|||
PIRP Irp;
|
||||
PMDL Mdl;
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
|
||||
Connection, Connection->SocketContext));
|
||||
|
||||
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)
|
||||
KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
|
||||
CurrentEntry = ConnectionEndpointListHead.Flink;
|
||||
while (CurrentEntry != &ConnectionEndpointListHead)
|
||||
{
|
||||
NextEntry = CurrentEntry->Flink;
|
||||
KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
|
||||
|
||||
Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT,
|
||||
SignalList );
|
||||
ListEntry );
|
||||
|
||||
KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
|
||||
NewState = HandleSignalledConnection(Connection);
|
||||
KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
if (NewState == SEL_FIN || NewState == 0)
|
||||
{
|
||||
RemoveEntryList(CurrentEntry);
|
||||
TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
|
||||
Connection, Connection->SocketContext));
|
||||
|
||||
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 ) {
|
||||
|
@ -314,7 +325,7 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
|
|||
RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
|
||||
|
||||
/* Initialize spin lock that protects the connection endpoint file object */
|
||||
TcpipInitializeSpinLock(&Connection->Lock);
|
||||
KeInitializeSpinLock(&Connection->Lock);
|
||||
InitializeListHead(&Connection->ConnectRequest);
|
||||
InitializeListHead(&Connection->ListenRequest);
|
||||
InitializeListHead(&Connection->ReceiveRequest);
|
||||
|
@ -323,19 +334,32 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
|
|||
/* Save client context pointer */
|
||||
Connection->ClientContext = ClientContext;
|
||||
|
||||
/* Add connection endpoint to global list */
|
||||
ExInterlockedInsertTailList(&ConnectionEndpointListHead,
|
||||
&Connection->ListEntry,
|
||||
&ConnectionEndpointListLock);
|
||||
|
||||
return Connection;
|
||||
}
|
||||
|
||||
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) {
|
||||
KIRQL OldIrql;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
|
||||
|
||||
TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
|
||||
RemoveEntryList(&Connection->ListEntry);
|
||||
TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
|
||||
|
||||
exFreePool( Connection );
|
||||
}
|
||||
|
||||
NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
|
||||
UINT Family, UINT Type, UINT Proto ) {
|
||||
NTSTATUS Status;
|
||||
KIRQL OldIrql;
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, "
|
||||
"Proto %d\n",
|
||||
|
@ -352,7 +376,7 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
|
|||
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
|
||||
Connection->SocketContext));
|
||||
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -370,13 +394,9 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
|
|||
IPPacket->TotalSize,
|
||||
IPPacket->HeaderSize));
|
||||
|
||||
TcpipRecursiveMutexEnter( &TCPLock );
|
||||
|
||||
OskitTCPReceiveDatagram( IPPacket->Header,
|
||||
IPPacket->TotalSize,
|
||||
IPPacket->HeaderSize );
|
||||
|
||||
TcpipRecursiveMutexLeave( &TCPLock );
|
||||
}
|
||||
|
||||
/* event.c */
|
||||
|
@ -447,10 +467,7 @@ TimerThread(PVOID Context)
|
|||
PsTerminateSystemThread(Status);
|
||||
}
|
||||
|
||||
TcpipRecursiveMutexEnter( &TCPLock );
|
||||
TimerOskitTCP( Next == NextFast, Next == NextSlow );
|
||||
TcpipRecursiveMutexLeave( &TCPLock );
|
||||
|
||||
if (Next == NextSlow) {
|
||||
DrainSignals();
|
||||
}
|
||||
|
@ -483,9 +500,6 @@ NTSTATUS TCPStartup(VOID)
|
|||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TcpipRecursiveMutexInit( &TCPLock );
|
||||
KeInitializeSpinLock( &SignalledConnectionsLock );
|
||||
InitializeListHead( &SignalledConnectionsList );
|
||||
Status = TCPMemStartup();
|
||||
if ( ! NT_SUCCESS(Status) ) {
|
||||
return Status;
|
||||
|
@ -497,10 +511,8 @@ NTSTATUS TCPStartup(VOID)
|
|||
return Status;
|
||||
}
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
RegisterOskitTCPEventHandlers( &EventHandlers );
|
||||
InitOskitTCP();
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
|
||||
/* Register this protocol with IP layer */
|
||||
IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
|
||||
|
@ -545,9 +557,7 @@ NTSTATUS TCPShutdown(VOID)
|
|||
|
||||
TCPInitialized = FALSE;
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
DeinitOskitTCP();
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
|
||||
PortsShutdown( &TCPPorts );
|
||||
|
||||
|
@ -597,6 +607,7 @@ NTSTATUS TCPConnect
|
|||
USHORT RemotePort;
|
||||
PTDI_BUCKET Bucket;
|
||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||
KIRQL OldIrql;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
|
||||
|
||||
|
@ -625,7 +636,7 @@ NTSTATUS TCPConnect
|
|||
AddressToBind = AddressToConnect;
|
||||
AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
Status = TCPTranslateError
|
||||
( OskitTCPBind( Connection->SocketContext,
|
||||
|
@ -640,26 +651,29 @@ NTSTATUS TCPConnect
|
|||
|
||||
Status = TCPTranslateError
|
||||
( OskitTCPConnect( Connection->SocketContext,
|
||||
Connection,
|
||||
&AddressToConnect,
|
||||
sizeof(AddressToConnect) ) );
|
||||
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
|
||||
if( !Bucket ) return STATUS_NO_MEMORY;
|
||||
if( !Bucket )
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
Bucket->Request.RequestNotifyObject = (PVOID)Complete;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -671,12 +685,11 @@ NTSTATUS TCPDisconnect
|
|||
PTCP_COMPLETION_ROUTINE Complete,
|
||||
PVOID Context ) {
|
||||
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
ASSERT_LOCKED(&TCPLock);
|
||||
KIRQL OldIrql;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("started\n"));
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
if (Flags & TDI_DISCONNECT_RELEASE)
|
||||
Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext));
|
||||
|
@ -684,7 +697,7 @@ NTSTATUS TCPDisconnect
|
|||
if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
|
||||
Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
|
||||
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status));
|
||||
|
||||
|
@ -694,20 +707,20 @@ NTSTATUS TCPDisconnect
|
|||
NTSTATUS TCPClose
|
||||
( PCONNECTION_ENDPOINT Connection ) {
|
||||
NTSTATUS Status;
|
||||
KIRQL OldIrql;
|
||||
PVOID Socket;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("TCPClose started\n"));
|
||||
|
||||
/* Make our code remove all pending IRPs */
|
||||
Connection->SignalState |= SEL_FIN;
|
||||
HandleSignalledConnection(Connection);
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
|
||||
Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) );
|
||||
if (Status == STATUS_SUCCESS)
|
||||
Connection->SocketContext = NULL;
|
||||
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
Socket = Connection->SocketContext;
|
||||
Connection->SocketContext = NULL;
|
||||
Status = TCPTranslateError( OskitTCPClose( Socket ) );
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Connection->SocketContext = Socket;
|
||||
}
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status));
|
||||
|
||||
|
@ -726,17 +739,18 @@ NTSTATUS TCPReceiveData
|
|||
UINT DataLen, Received = 0;
|
||||
NTSTATUS Status;
|
||||
PTDI_BUCKET Bucket;
|
||||
KIRQL OldIrql;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
|
||||
ReceiveLength, Connection->SocketContext));
|
||||
|
||||
ASSERT_KM_POINTER(Connection->SocketContext);
|
||||
|
||||
NdisQueryBuffer( 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
|
||||
( OskitTCPRecv
|
||||
|
@ -746,7 +760,7 @@ NTSTATUS TCPReceiveData
|
|||
&Received,
|
||||
ReceiveFlags ) );
|
||||
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received));
|
||||
|
||||
|
@ -763,9 +777,8 @@ NTSTATUS TCPReceiveData
|
|||
Bucket->Request.RequestContext = Context;
|
||||
*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"));
|
||||
} else {
|
||||
TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received));
|
||||
|
@ -788,8 +801,9 @@ NTSTATUS TCPSendData
|
|||
UINT Sent = 0;
|
||||
NTSTATUS Status;
|
||||
PTDI_BUCKET Bucket;
|
||||
KIRQL OldIrql;
|
||||
|
||||
ASSERT_LOCKED(&TCPLock);
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
|
||||
SendLength, Connection->SocketContext));
|
||||
|
@ -800,14 +814,12 @@ NTSTATUS TCPSendData
|
|||
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
|
||||
Connection->SocketContext));
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
|
||||
Status = TCPTranslateError
|
||||
( OskitTCPSend( Connection->SocketContext,
|
||||
(OSK_PCHAR)BufferData, SendLength,
|
||||
&Sent, 0 ) );
|
||||
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent));
|
||||
|
||||
|
@ -823,10 +835,9 @@ NTSTATUS TCPSendData
|
|||
Bucket->Request.RequestNotifyObject = Complete;
|
||||
Bucket->Request.RequestContext = Context;
|
||||
*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"));
|
||||
} else {
|
||||
TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
|
||||
|
@ -865,14 +876,15 @@ NTSTATUS TCPGetSockAddress
|
|||
OSK_UI16 LocalPort, RemotePort;
|
||||
PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
|
||||
NTSTATUS Status;
|
||||
KIRQL OldIrql;
|
||||
|
||||
TcpipRecursiveMutexEnter(&TCPLock);
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext,
|
||||
&LocalAddress, &LocalPort,
|
||||
&RemoteAddress, &RemotePort));
|
||||
|
||||
TcpipRecursiveMutexLeave(&TCPLock);
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
|
|
@ -172,6 +172,9 @@ NTSTATUS UDPSendDatagram(
|
|||
USHORT RemotePort;
|
||||
NTSTATUS Status;
|
||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||
KIRQL OldIrql;
|
||||
|
||||
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
|
||||
AddrFile, ConnInfo, BufferData, DataSize));
|
||||
|
@ -186,10 +189,12 @@ NTSTATUS UDPSendDatagram(
|
|||
break;
|
||||
|
||||
default:
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
return STATUS_NETWORK_UNREACHABLE;
|
||||
}
|
||||
|
||||
|
@ -213,14 +218,20 @@ NTSTATUS UDPSendDatagram(
|
|||
DataSize );
|
||||
|
||||
if( !NT_SUCCESS(Status) )
|
||||
{
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
|
||||
{
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
FreeNdisPacket(Packet.NdisPacket);
|
||||
return Status;
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ extern int OskitTCPSend( void *socket,
|
|||
OSK_UINT *OutLen,
|
||||
OSK_UINT Flags );
|
||||
|
||||
extern int OskitTCPConnect( void *socket, void *connection,
|
||||
extern int OskitTCPConnect( void *socket,
|
||||
void *nam, OSK_UINT namelen );
|
||||
extern int OskitTCPClose( void *socket );
|
||||
|
||||
|
@ -131,7 +131,7 @@ extern int OskitTCPBind( void *socket,
|
|||
void *nam, OSK_UINT namelen );
|
||||
|
||||
extern int OskitTCPAccept( void *socket, void **new_socket,
|
||||
void *addr_out,
|
||||
void *context, void *addr_out,
|
||||
OSK_UINT addr_len,
|
||||
OSK_UINT *out_addr_len,
|
||||
OSK_UINT finish_accept );
|
||||
|
@ -187,4 +187,27 @@ void fbsd_free( void *data, char *file, unsigned line, ... );
|
|||
#define FREAD 0x0001
|
||||
#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*/
|
||||
|
|
|
@ -23,6 +23,8 @@ OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 };
|
|||
//OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
|
||||
OSK_UINT OskitDebugTraceLevel = 0;
|
||||
|
||||
KSPIN_LOCK OSKLock;
|
||||
|
||||
/* SPL */
|
||||
unsigned cpl;
|
||||
unsigned net_imask;
|
||||
|
@ -45,6 +47,7 @@ void fbsd_free( void *data, char *file, unsigned line, ... ) {
|
|||
|
||||
void InitOskitTCP() {
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Init Called\n"));
|
||||
KeInitializeSpinLock(&OSKLock);
|
||||
OS_DbgPrint(OSK_MID_TRACE,("MB Init\n"));
|
||||
mbinit();
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n"));
|
||||
|
@ -66,12 +69,19 @@ void DeinitOskitTCP() {
|
|||
}
|
||||
|
||||
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 ) {
|
||||
tcp_slowtimo();
|
||||
}
|
||||
if ( FastTimer ) {
|
||||
tcp_fasttimo();
|
||||
}
|
||||
OSKUnlockAndLower(OldIrql);
|
||||
}
|
||||
|
||||
void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) {
|
||||
|
@ -115,12 +125,16 @@ int OskitTCPSocket( void *context,
|
|||
int proto )
|
||||
{
|
||||
struct socket *so;
|
||||
|
||||
OSKLock();
|
||||
int error = socreate(domain, &so, type, proto);
|
||||
if( !error ) {
|
||||
so->so_connection = context;
|
||||
so->so_state |= SS_NBIO;
|
||||
*aso = so;
|
||||
}
|
||||
OSKUnlock();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -153,8 +167,11 @@ int OskitTCPRecv( void *connection,
|
|||
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
|
||||
|
||||
OSKLock();
|
||||
error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */,
|
||||
&tcp_flags );
|
||||
OSKUnlock();
|
||||
|
||||
*OutLen = Len - uio.uio_resid;
|
||||
|
||||
return error;
|
||||
|
@ -182,14 +199,15 @@ int OskitTCPBind( void *socket,
|
|||
addr.sa_family = addr.sa_len;
|
||||
addr.sa_len = sizeof(struct sockaddr);
|
||||
|
||||
OSKLock();
|
||||
error = sobind(so, &sabuf);
|
||||
OSKUnlock();
|
||||
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int OskitTCPConnect( void *socket, void *connection,
|
||||
void *nam, OSK_UINT namelen ) {
|
||||
int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) {
|
||||
struct socket *so = socket;
|
||||
int error = EFAULT;
|
||||
struct mbuf sabuf;
|
||||
|
@ -197,8 +215,7 @@ int OskitTCPConnect( void *socket, void *connection,
|
|||
|
||||
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)) {
|
||||
error = EALREADY;
|
||||
goto done;
|
||||
|
@ -217,7 +234,9 @@ int OskitTCPConnect( void *socket, void *connection,
|
|||
|
||||
error = soconnect(so, &sabuf);
|
||||
|
||||
if (error)
|
||||
if (error == EINPROGRESS)
|
||||
goto done;
|
||||
else if (error)
|
||||
goto bad;
|
||||
|
||||
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
|
||||
|
@ -232,34 +251,49 @@ bad:
|
|||
error = EINTR;
|
||||
|
||||
done:
|
||||
OSKUnlock();
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int OskitTCPDisconnect(void *socket)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (!socket)
|
||||
return OSK_ESHUTDOWN;
|
||||
|
||||
return sodisconnect(socket);
|
||||
OSKLock();
|
||||
error = sodisconnect(socket);
|
||||
OSKUnlock();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int OskitTCPShutdown( void *socket, int disconn_type ) {
|
||||
int error;
|
||||
|
||||
if (!socket)
|
||||
return OSK_ESHUTDOWN;
|
||||
|
||||
return soshutdown( socket, disconn_type );
|
||||
OSKLock();
|
||||
error = soshutdown( socket, disconn_type );
|
||||
OSKUnlock();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int OskitTCPClose( void *socket ) {
|
||||
struct socket *so = socket;
|
||||
int error;
|
||||
|
||||
if (!socket)
|
||||
return OSK_ESHUTDOWN;
|
||||
|
||||
so->so_connection = 0;
|
||||
soclose( so );
|
||||
return 0;
|
||||
OSKLock();
|
||||
error = soclose( socket );
|
||||
OSKUnlock();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
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_procp = NULL;
|
||||
|
||||
OSKLock();
|
||||
error = sosend( socket, NULL, &uio, NULL, NULL, 0 );
|
||||
OSKUnlock();
|
||||
|
||||
*OutLen = Len - uio.uio_resid;
|
||||
|
||||
return error;
|
||||
|
@ -289,6 +326,7 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
|
|||
|
||||
int OskitTCPAccept( void *socket,
|
||||
void **new_socket,
|
||||
void *context,
|
||||
void *AddrOut,
|
||||
OSK_UINT AddrLen,
|
||||
OSK_UINT *OutAddrLen,
|
||||
|
@ -317,11 +355,12 @@ int OskitTCPAccept( void *socket,
|
|||
/* that's a copyin actually */
|
||||
namelen = *OutAddrLen;
|
||||
|
||||
OSKLock();
|
||||
|
||||
s = splnet();
|
||||
|
||||
#if 0
|
||||
if ((head->so_options & SO_ACCEPTCONN) == 0) {
|
||||
splx(s);
|
||||
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
|
||||
head->so_options, SO_ACCEPTCONN));
|
||||
error = EINVAL;
|
||||
|
@ -333,39 +372,10 @@ int OskitTCPAccept( void *socket,
|
|||
head->so_q, head->so_state));
|
||||
|
||||
if ((head->so_state & SS_NBIO) && head->so_q == NULL) {
|
||||
splx(s);
|
||||
error = EWOULDBLOCK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||
while (head->so_q == NULL && head->so_error == 0) {
|
||||
if (head->so_state & SS_CANTRCVMORE) {
|
||||
head->so_error = ECONNABORTED;
|
||||
break;
|
||||
}
|
||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||
error = tsleep((caddr_t)&head->so_timeo, PSOCK | PCATCH,
|
||||
"accept", 0);
|
||||
if (error) {
|
||||
splx(s);
|
||||
goto out;
|
||||
}
|
||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||
}
|
||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||
|
||||
#if 0
|
||||
if (head->so_error) {
|
||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||
error = head->so_error;
|
||||
head->so_error = 0;
|
||||
splx(s);
|
||||
goto out;
|
||||
}
|
||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* At this point we know that there is at least one connection
|
||||
* ready to be accepted. Remove it from the queue.
|
||||
|
@ -384,19 +394,20 @@ int OskitTCPAccept( void *socket,
|
|||
head->so_q = so->so_q;
|
||||
head->so_qlen--;
|
||||
|
||||
*newso = so;
|
||||
|
||||
/*so->so_state &= ~SS_COMP;*/
|
||||
|
||||
mnam.m_data = (char *)&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_qlen = 0;
|
||||
so->so_head = 0;
|
||||
so->so_connection = context;
|
||||
|
||||
*newso = so;
|
||||
|
||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||
if (name) {
|
||||
|
@ -406,9 +417,10 @@ int OskitTCPAccept( void *socket,
|
|||
*OutAddrLen = namelen; /* copyout actually */
|
||||
}
|
||||
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
|
||||
splx(s);
|
||||
}
|
||||
out:
|
||||
splx(s);
|
||||
OSKUnlock();
|
||||
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error));
|
||||
return (error);
|
||||
}
|
||||
|
@ -421,10 +433,20 @@ out:
|
|||
|
||||
void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
|
||||
OSK_UINT IpHeaderLen ) {
|
||||
struct mbuf *Ip = m_devget( (char *)Data, Len, 0, NULL, NULL );
|
||||
struct mbuf *Ip;
|
||||
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 );
|
||||
Ip->m_pkthdr.len = IpHeaderLen;
|
||||
|
@ -439,6 +461,7 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
|
|||
IpHeaderLen));
|
||||
|
||||
tcp_input(Ip, IpHeaderLen);
|
||||
OSKUnlockAndLower(OldIrql);
|
||||
|
||||
/* The buffer Ip is freed by tcp_input */
|
||||
}
|
||||
|
@ -450,6 +473,7 @@ int OskitTCPSetSockOpt(void *socket,
|
|||
int size)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int error;
|
||||
|
||||
if (!socket)
|
||||
return OSK_ESHUTDOWN;
|
||||
|
@ -457,16 +481,23 @@ int OskitTCPSetSockOpt(void *socket,
|
|||
if (size >= MLEN)
|
||||
return OSK_EINVAL;
|
||||
|
||||
OSKLock();
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
if (!m)
|
||||
{
|
||||
OSKUnlock();
|
||||
return OSK_ENOMEM;
|
||||
}
|
||||
|
||||
m->m_len = size;
|
||||
|
||||
memcpy(m->m_data, buffer, size);
|
||||
|
||||
/* m is freed by sosetopt */
|
||||
return sosetopt(socket, level, optname, m);
|
||||
error = sosetopt(socket, level, optname, m);
|
||||
OSKUnlock();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int OskitTCPGetSockOpt(void *socket,
|
||||
|
@ -481,6 +512,7 @@ int OskitTCPGetSockOpt(void *socket,
|
|||
if (!socket)
|
||||
return OSK_ESHUTDOWN;
|
||||
|
||||
OSKLock();
|
||||
error = sogetopt(socket, level, optname, &m);
|
||||
if (!error)
|
||||
{
|
||||
|
@ -489,6 +521,7 @@ int OskitTCPGetSockOpt(void *socket,
|
|||
if (!buffer || oldsize < m->m_len)
|
||||
{
|
||||
m_freem(m);
|
||||
OSKUnlock();
|
||||
return OSK_EINVAL;
|
||||
}
|
||||
|
||||
|
@ -496,6 +529,7 @@ int OskitTCPGetSockOpt(void *socket,
|
|||
|
||||
m_freem(m);
|
||||
}
|
||||
OSKUnlock();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -507,7 +541,11 @@ int OskitTCPListen( void *socket, int backlog ) {
|
|||
return OSK_ESHUTDOWN;
|
||||
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
|
||||
|
||||
OSKLock();
|
||||
error = solisten( socket, backlog );
|
||||
OSKUnlock();
|
||||
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
|
||||
|
||||
return error;
|
||||
|
@ -524,11 +562,13 @@ int OskitTCPSetAddress( void *socket,
|
|||
if (!socket)
|
||||
return OSK_ESHUTDOWN;
|
||||
|
||||
OSKLock();
|
||||
inp = (struct inpcb *)so->so_pcb;
|
||||
inp->inp_laddr.s_addr = LocalAddress;
|
||||
inp->inp_lport = LocalPort;
|
||||
inp->inp_faddr.s_addr = RemoteAddress;
|
||||
inp->inp_fport = RemotePort;
|
||||
OSKUnlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -544,11 +584,13 @@ int OskitTCPGetAddress( void *socket,
|
|||
if (!socket)
|
||||
return OSK_ESHUTDOWN;
|
||||
|
||||
OSKLock();
|
||||
inp = (struct inpcb *)so->so_pcb;
|
||||
*LocalAddress = inp->inp_laddr.s_addr;
|
||||
*LocalPort = inp->inp_lport;
|
||||
*RemoteAddress = inp->inp_faddr.s_addr;
|
||||
*RemotePort = inp->inp_fport;
|
||||
OSKUnlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue