Fixed for TCPIP

Regularized TCPSendData and TCPReceiveData parameters and calling.
Added number of bytes IoStatus for TDI_SEND_DATAGRAM and TDI_SEND as
specified in the OSR entry for TDI_SEND_DATAGRAM.
Fixed IRQL in packet send event.  We now use KeRaiseIrql to make sure we're
in DISPATCH_LEVEL.
Fixed socket state callback for new afd.  Now fully based on io completion.

svn path=/trunk/; revision=10032
This commit is contained in:
Art Yerkes 2004-07-08 06:36:04 +00:00
parent aa11660dd0
commit 494edc04e5
12 changed files with 304 additions and 266 deletions

View file

@ -11,7 +11,8 @@ NTSTATUS RawIPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
ULONG DataSize,
PULONG DataUsed);
VOID RawIPReceive(
PNET_TABLE_ENTRY NTE,

View file

@ -104,9 +104,10 @@ NTSTATUS TCPReceiveData(
NTSTATUS TCPSendData(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
ULONG DataSize,
ULONG Flags,
PULONG DataUsed);
NTSTATUS TCPStartup(
VOID);

View file

@ -100,7 +100,8 @@ typedef NTSTATUS (*DATAGRAM_SEND_ROUTINE)(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
ULONG DataSize,
PULONG DataUsed);
/* Datagram completion handler prototype */
typedef VOID (*DATAGRAM_COMPLETION_ROUTINE)(
@ -295,54 +296,31 @@ typedef struct _TCP_SEGMENT {
ULONG BytesDelivered; /* Number of bytes already delivered to the client */
} TCP_SEGMENT, *PTCP_SEGMENT;
typedef struct _TDI_BUCKET {
LIST_ENTRY Entry;
TDI_REQUEST Request;
} TDI_BUCKET, *PTDI_BUCKET;
/* Transport connection context structure A.K.A. Transmission Control Block
(TCB) in TCP terminology. The FileObject->FsContext2 field holds a pointer
to this structure */
typedef struct _CONNECTION_ENDPOINT {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to protect this structure */
ULONG RefCount; /* Number of references to this object */
PVOID ClientContext; /* Pointer to client context information */
PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */
PVOID SocketContext; /* Context for lower layer */
#if 0
PIP_ADDRESS LocalAddress; /* Pointer to local IP address */
USHORT LocalPort; /* Local port number (network byte order) */
PIP_ADDRESS RemoteAddress; /* Pointer to remote IP address */
USHORT RemotePort; /* Remote port number (network byte order) */
CONNECTION_STATE State; /* Connection state */
/* Send sequence variables */
ULONG SendUnacknowledged; /* Highest sequence number that is acknowledged */
ULONG SendNext; /* Sequence number of last data block sent */
ULONG SendWindow; /* Maximum allowed number of octets in a segment */
ULONG SendUrgentPointer; /* Sequence number of start of urgent data */
ULONG SendWL1; /* Sequence number used for last window update */
ULONG SendWL2; /* Acknowledgment number used for last window update */
ULONG SendISS; /* Initial send sequence number */
/* Receive sequence variables */
ULONG ReceiveNext; /* Next sequence number expected and start of receive window */
ULONG ReceiveWindow; /* Maximum allowed number of octets in a segment */
ULONG ReceiveUrgentPointer; /* Sequence number of start of urgent data */
ULONG ReceiveIRS; /* Initial receive sequence number */
ULONG ReceiveDelivered; /* Next sequence number to be delivered to the client */
/* Statistics for computing the retransmission timeout */
ULONG TimestampSend; /* Timestamp when sending a segment */
ULONG TimestampAck; /* Timestamp when receiving acknowledgment */
#endif
/* Requests */
PTDI_REQUEST ListenRequest; /* Queued listen request */
LIST_ENTRY ReceiveRequests; /* Queued receive requests */
/* Queues */
LIST_ENTRY ReceivedSegments;/* Segments that are received */
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to protect this structure */
ULONG RefCount; /* Number of references to this object */
PVOID ClientContext; /* Pointer to client context information */
PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */
PVOID SocketContext; /* Context for lower layer */
UINT State; /* Socket state W.R.T. oskit */
/* Requests */
LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */
LIST_ENTRY ListenRequest; /* Queued listen requests */
LIST_ENTRY ReceiveRequest; /* Queued receive requests */
/* Queues */
LIST_ENTRY ReceivedSegments;/* Segments that are received */
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;

View file

@ -42,7 +42,8 @@ NTSTATUS UDPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
ULONG DataSize,
PULONG DataUsed);
NTSTATUS UDPReceiveDatagram(
PTDI_REQUEST Request,

View file

@ -210,11 +210,22 @@ NTSTATUS AddrBuildAddress(
PTDI_ADDRESS_IP ValidAddr;
PIP_ADDRESS IPAddress;
if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP)
return STATUS_INVALID_ADDRESS;
TI_DbgPrint(MID_TRACE,("Address in:\n"));
OskitDumpBuffer( TdiAddress, sizeof(*TdiAddress) );
if (TdiAddress->AddressLength != TDI_ADDRESS_LENGTH_IP)
if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP) {
TI_DbgPrint
(MID_TRACE,("AddressType %x, Not valid\n",
TdiAddress->AddressType));
return STATUS_INVALID_ADDRESS;
}
if (TdiAddress->AddressLength < TDI_ADDRESS_LENGTH_IP) {
TI_DbgPrint
(MID_TRACE,("AddressLength %x, Not valid (expected %x)\n",
TdiAddress->AddressLength, TDI_ADDRESS_LENGTH_IP));
return STATUS_INVALID_ADDRESS;
}
ValidAddr = (PTDI_ADDRESS_IP)TdiAddress->Address;
@ -226,6 +237,9 @@ NTSTATUS AddrBuildAddress(
*Address = IPAddress;
*Port = ValidAddr->sin_port;
TI_DbgPrint(MID_TRACE,("Address out:\n"));
OskitDumpBuffer( IPAddress, sizeof(*IPAddress) );
return STATUS_SUCCESS;
}

View file

@ -187,9 +187,10 @@ VOID DispDataRequestComplete(
PTRANSPORT_CONTEXT TranContext;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
Context, Status, Count));
Irp = (PIRP)Context;
Irp = Context;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
@ -218,6 +219,10 @@ VOID DispDataRequestComplete(
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Count;
TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Status = %x\n",
Irp->IoStatus.Status));
TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Information = %d\n",
Irp->IoStatus.Information));
TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
IRPFinish(Irp, STATUS_SUCCESS);
@ -687,6 +692,7 @@ NTSTATUS DispTdiReceive(
IrpSp->FileObject->FsContext,
Irp,
(PDRIVER_CANCEL)DispCancelRequest);
TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
if (NT_SUCCESS(Status))
{
Status = TCPReceiveData(
@ -786,46 +792,63 @@ NTSTATUS DispTdiSend(
* Status of operation
*/
{
PIO_STACK_LOCATION IrpSp;
TDI_REQUEST Request;
PTDI_REQUEST_KERNEL_SEND SendInfo;
PTRANSPORT_CONTEXT TranContext;
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp;
PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
PTRANSPORT_CONTEXT TranContext;
TDI_REQUEST Request;
NTSTATUS Status;
ULONG BytesReceived;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
TranContext = IrpSp->FileObject->FsContext;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
/* Initialize a send request */
Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
Request.RequestNotifyObject = DispDataRequestComplete;
Request.RequestContext = Irp;
Status = DispPrepareIrpForCancel(
IrpSp->FileObject->FsContext,
Irp,
(PDRIVER_CANCEL)DispCancelRequest);
if (NT_SUCCESS(Status)) {
/* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
must be of type PTDI_ADDRESS_IP */
Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
&Request, NULL,
(PNDIS_BUFFER)Irp->MdlAddress, SendInfo->SendLength);
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
/* Return STATUS_PENDING because DispPrepareIrpForCancel
marks Irp as pending */
Status = STATUS_PENDING;
}
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_CONNECTION;
}
TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
if (TranContext->Handle.ConnectionContext == NULL)
{
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
return STATUS_INVALID_CONNECTION;
}
return Status;
/* Initialize a receive request */
Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
Request.RequestNotifyObject = DispDataRequestComplete;
Request.RequestContext = Irp;
Status = DispPrepareIrpForCancel(
IrpSp->FileObject->FsContext,
Irp,
(PDRIVER_CANCEL)DispCancelRequest);
TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
if (NT_SUCCESS(Status))
{
TI_DbgPrint(MID_TRACE,("About to TCPSendData\n"));
Status = TCPSendData(
&Request,
(PNDIS_BUFFER)Irp->MdlAddress,
ReceiveInfo->ReceiveLength,
ReceiveInfo->ReceiveFlags,
&BytesReceived);
if (Status != STATUS_PENDING)
{
DispDataRequestComplete(Irp, Status, BytesReceived);
}
}
if (Status != STATUS_PENDING)
{
IrpSp->Control &= ~SL_PENDING_RETURNED;
}
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
return Status;
}
@ -867,9 +890,10 @@ NTSTATUS DispTdiSendDatagram(
Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
&Request, DgramInfo->SendDatagramInformation,
(PNDIS_BUFFER)Irp->MdlAddress, DgramInfo->SendLength);
(PNDIS_BUFFER)Irp->MdlAddress, DgramInfo->SendLength,
&Irp->IoStatus.Information);
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information);
/* Return STATUS_PENDING because DispPrepareIrpForCancel
marks Irp as pending */
Status = STATUS_PENDING;

View file

@ -456,6 +456,9 @@ NTSTATUS FileOpenConnection(
/* Initialize spin lock that protects the connection endpoint file object */
KeInitializeSpinLock(&Connection->Lock);
InitializeListHead(&Connection->ConnectRequest);
InitializeListHead(&Connection->ListenRequest);
InitializeListHead(&Connection->ReceiveRequest);
/* Reference the object */
Connection->RefCount = 1;
@ -469,9 +472,6 @@ NTSTATUS FileOpenConnection(
IPPROTO_TCP );
DbgPrint("STATUS from OSKITTCP was %08x\n", Status);
/* Initialize receive requests queue */
InitializeListHead(&Connection->ReceiveRequests);
/* Initialize received segments queue */
InitializeListHead(&Connection->ReceivedSegments);

View file

@ -213,7 +213,14 @@ CP
(Address->TAAddressCount != 1) ||
(Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
(Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP)) {
TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
TI_DbgPrint(MIN_TRACE, ("Parameters are invalid:\n"));
TI_DbgPrint(MIN_TRACE, ("AddressCount: %d\n", Address->TAAddressCount));
if( Address->TAAddressCount == 1 ) {
TI_DbgPrint(MIN_TRACE, ("AddressLength: %\n",
Address->Address[0].AddressLength));
TI_DbgPrint(MIN_TRACE, ("AddressType: %\n",
Address->Address[0].AddressType));
}
ExFreePool(Context);
return STATUS_INVALID_PARAMETER;
}
@ -578,11 +585,12 @@ TiDispatch(
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp));
Irp->IoStatus.Information = 0;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
#ifdef _MSC_VER
Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
if (NT_SUCCESS(Status)) {

View file

@ -84,7 +84,8 @@ NTSTATUS RawIPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize)
ULONG DataSize,
PULONG DataUsed )
/*
* FUNCTION: Sends a raw IP datagram to a remote address
* ARGUMENTS:
@ -110,6 +111,8 @@ NTSTATUS RawIPSendDatagram(
TI_DbgPrint(MID_TRACE,("Packet.NdisPacket %x\n", Packet.NdisPacket));
*DataUsed = BufferLen;
if( Status == NDIS_STATUS_SUCCESS )
Status = BuildRawIPPacket( &Packet,
BufferLen,

View file

@ -23,150 +23,93 @@
extern ULONG TCP_IPIdentification;
void TCPRecvNotify( PCONNECTION_ENDPOINT Connection, UINT Flags ) {
int error = 0;
NTSTATUS Status = 0;
CHAR DataBuffer[1024];
UINT BytesRead = 0, BytesTaken = 0;
PTDI_IND_RECEIVE ReceiveHandler;
PTDI_IND_DISCONNECT DisconnectHandler;
PVOID HandlerContext;
SOCKADDR Addr;
typedef VOID
(*PTCP_COMPLETION_ROUTINE)( PVOID Context, NTSTATUS Status, ULONG Count );
TI_DbgPrint(MID_TRACE,("XX> Called\n"));
do {
error = OskitTCPRecv( Connection->SocketContext,
&Addr,
DataBuffer,
1024,
&BytesRead,
Flags | OSK_MSG_DONTWAIT | OSK_MSG_PEEK );
int TCPSocketState(void *ClientData,
void *WhichSocket,
void *WhichConnection,
OSK_UINT NewState ) {
PCONNECTION_ENDPOINT Connection = WhichConnection;
PTCP_COMPLETION_ROUTINE Complete;
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
switch( error ) {
case 0:
ReceiveHandler = Connection->AddressFile->ReceiveHandler;
HandlerContext = Connection->AddressFile->ReceiveHandlerContext;
TI_DbgPrint(MID_TRACE,("Received %d bytes\n", BytesRead));
if( Connection->AddressFile->RegisteredReceiveHandler )
Status = ReceiveHandler( HandlerContext,
NULL,
TDI_RECEIVE_NORMAL,
BytesRead,
BytesRead,
&BytesTaken,
DataBuffer,
NULL );
else
Status = STATUS_UNSUCCESSFUL;
if( Status == STATUS_SUCCESS ) {
OskitTCPRecv( Connection->SocketContext,
&Addr,
DataBuffer,
BytesTaken,
&BytesRead,
Flags | OSK_MSG_DONTWAIT );
}
break;
TI_DbgPrint(MID_TRACE,("Called: NewState %x\n", NewState));
case OSK_ESHUTDOWN:
case OSK_ECONNRESET:
DisconnectHandler = Connection->AddressFile->DisconnectHandler;
HandlerContext = Connection->AddressFile->DisconnectHandlerContext;
if( Connection->AddressFile->RegisteredDisconnectHandler )
Status = DisconnectHandler( HandlerContext,
NULL,
0,
NULL,
0,
NULL,
(error == OSK_ESHUTDOWN) ?
TDI_DISCONNECT_RELEASE :
TDI_DISCONNECT_ABORT );
else
Status = STATUS_UNSUCCESSFUL;
break;
default:
assert( 0 );
break;
}
} while( error == 0 && BytesRead > 0 && BytesTaken > 0 );
TI_DbgPrint(MID_TRACE,("XX> Leaving\n"));
}
void TCPCloseNotify( PCONNECTION_ENDPOINT Connection ) {
NTSTATUS Status;
PTDI_IND_DISCONNECT DisconnectHandler;
PVOID HandlerContext;
DisconnectHandler = Connection->AddressFile->DisconnectHandler;
HandlerContext = Connection->AddressFile->DisconnectHandlerContext;
/* XXX Distinguish TDI_DISCONNECT_RELEASE from TDI_DISCONNECT_ABORT */
if( Connection->AddressFile->RegisteredDisconnectHandler )
Status = DisconnectHandler( HandlerContext,
NULL,
0,
NULL,
0,
NULL,
TDI_DISCONNECT_ABORT );
else
Status = STATUS_UNSUCCESSFUL;
return Status;
}
char *FlagNames[] = { "SEL_CONNECT",
"SEL_FIN",
"SEL_ACCEPT",
"SEL_OOB",
"SEL_READ",
"SEL_WRITE",
0 };
int FlagValues[] = { SEL_CONNECT,
SEL_FIN,
SEL_ACCEPT,
SEL_OOB,
SEL_READ,
SEL_WRITE,
0 };
void TCPSocketState( void *ClientData,
void *WhichSocket,
void *WhichConnection,
OSK_UINT Flags,
OSK_UINT SocketState ) {
int i;
PCONNECTION_ENDPOINT Connection =
(PCONNECTION_ENDPOINT)WhichConnection;
TI_DbgPrint(MID_TRACE,("TCPSocketState: (socket %x) %x %x\n",
WhichSocket, Flags, SocketState));
for( i = 0; FlagValues[i]; i++ ) {
if( Flags & FlagValues[i] )
TI_DbgPrint(MID_TRACE,("Flag %s\n", FlagNames[i]));
if( !Connection ) {
TI_DbgPrint(MID_TRACE,("Socket closing.\n"));
return 0;
}
if( Flags & SEL_CONNECT )
/* TCPConnectNotify( Connection ); */ ;
if( Flags & SEL_FIN )
TCPCloseNotify( Connection );
if( Flags & SEL_ACCEPT )
/* TCPAcceptNotify( Connection ); */ ;
if( Flags & SEL_OOB )
TCPRecvNotify( Connection, MSG_OOB );
if( Flags & SEL_WRITE )
/* TCPSendNotify( Connection ); */ ;
if( Flags & SEL_READ )
TCPRecvNotify( Connection, 0 );
if( (NewState & SEL_CONNECT) &&
!(Connection->State & SEL_CONNECT) ) {
while( !IsListEmpty( &Connection->ConnectRequest ) ) {
Connection->State |= SEL_CONNECT;
Entry = RemoveHeadList( &Connection->ConnectRequest );
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Complete = Bucket->Request.RequestNotifyObject;
TI_DbgPrint(MID_TRACE,
("Completing Connect Request %x\n", Bucket->Request));
Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
/* Frees the bucket allocated in TCPConnect */
ExFreePool( Bucket );
}
} else if( NewState & SEL_READ ) {
while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
PIRP Irp;
OSK_UINT RecvLen = 0, Received = 0;
OSK_PCHAR RecvBuffer = 0;
PMDL Mdl;
NTSTATUS Status;
Entry = RemoveHeadList( &Connection->ReceiveRequest );
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Complete = Bucket->Request.RequestNotifyObject;
TI_DbgPrint(MID_TRACE,
("Readable, Completing read request %x\n",
Bucket->Request));
Irp = Bucket->Request.RequestContext;
Mdl = Irp->MdlAddress;
TI_DbgPrint(MID_TRACE,
("Getting the user buffer from %x\n", Mdl));
NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
TI_DbgPrint(MID_TRACE,
("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
Status = TCPTranslateError
( OskitTCPRecv( Connection->SocketContext,
RecvBuffer,
RecvLen,
&Received,
0 ) );
TI_DbgPrint(MID_TRACE,("TCP Bytes: %d\n", Received));
if( Status == STATUS_SUCCESS && Received != 0 ) {
TI_DbgPrint(MID_TRACE,("Received %d bytes with status %x\n",
Received, Status));
TI_DbgPrint(MID_TRACE,
("Completing Receive Request: %x\n",
Bucket->Request));
Complete( Bucket->Request.RequestContext,
STATUS_SUCCESS,
Received );
} else {
InsertHeadList( &Connection->ReceiveRequest,
&Bucket->Entry );
}
}
}
return 0;
}
void TCPPacketSendComplete( PVOID Context,
@ -294,6 +237,12 @@ int TCPPacketSend(void *ClientData,
&RemoteAddress.Address.IPv4Address,
&RemotePort );
DbgPrint("OSKIT SENDING PACKET *** %x:%d -> %x:%d\n",
LocalAddress.Address.IPv4Address,
LocalPort,
RemoteAddress.Address.IPv4Address,
RemotePort);
NCE = RouterGetRoute( &RemoteAddress, NULL );
if( !NCE ) return OSK_EADDRNOTAVAIL;
@ -302,8 +251,7 @@ int TCPPacketSend(void *ClientData,
ADE_UNICAST,
&LocalAddress.Address.IPv4Address );
if( Connection )
KeAcquireSpinLock( &Connection->Lock, &OldIrql );
KeRaiseIrql( DISPATCH_LEVEL, &OldIrql );
NdisStatus =
AllocatePacketWithBuffer( &SendRequest->PacketToSend, data, len );
@ -333,8 +281,7 @@ int TCPPacketSend(void *ClientData,
DbgPrint("Transmit called without connection.\n");
end:
if( Connection )
KeReleaseSpinLock( &Connection->Lock, OldIrql );
KeLowerIrql( OldIrql );
if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL;
else return 0;

View file

@ -52,11 +52,10 @@ VOID TCPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
}
/* event.c */
void TCPSocketState( void *ClientData,
void *WhichSocket,
void *WhichConnection,
OSK_UINT SelFlags,
OSK_UINT SocketState );
int TCPSocketState( void *ClientData,
void *WhichSocket,
void *WhichConnection,
OSK_UINT NewState );
int TCPPacketSend( void *ClientData,
void *WhichSocket,
@ -67,7 +66,7 @@ int TCPPacketSend( void *ClientData,
OSKITTCP_EVENT_HANDLERS EventHandlers = {
NULL, /* Client Data */
TCPSocketState, /* SocketState */
TCPPacketSend, /* PacketSend */
TCPPacketSend, /* PacketSend */
};
NTSTATUS TCPStartup(VOID)
@ -129,6 +128,8 @@ NTSTATUS TCPTranslateError( int OskitError ) {
case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break;
case OSK_ECONNREFUSED:
case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break;
case OSK_EINPROGRESS:
case OSK_EAGAIN: Status = STATUS_PENDING; break;
default: Status = STATUS_INVALID_CONNECTION; break;
}
@ -143,20 +144,30 @@ NTSTATUS TCPConnect
KIRQL OldIrql;
NTSTATUS Status;
SOCKADDR_IN AddressToConnect;
PCONNECTION_ENDPOINT Connection;
Connection = Request->Handle.ConnectionContext;
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
PCONNECTION_ENDPOINT Connection = Request->Handle.ConnectionContext;
PIP_ADDRESS RemoteAddress;
USHORT RemotePort;
PTDI_BUCKET Bucket;
Status = AddrBuildAddress(
(PTA_ADDRESS)(&((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress)->
Address[0]),
&RemoteAddress,
&RemotePort);
DbgPrint("TCPConnect: Called\n");
Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) );
if( !Bucket ) return STATUS_NO_MEMORY;
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
/* Freed in TCPSocketState */
Bucket->Request = *Request;
InsertHeadList( &Connection->ConnectRequest, &Bucket->Entry );
Status = AddrBuildAddress
((PTA_ADDRESS)ConnInfo->RemoteAddress,
&RemoteAddress,
&RemotePort);
DbgPrint("Connecting to address %x:%x\n",
RemoteAddress->Address.IPv4Address,
RemotePort);
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MID_TRACE, ("Could not AddrBuildAddress in TCPConnect\n"));
@ -171,11 +182,16 @@ NTSTATUS TCPConnect
sizeof(AddressToConnect.sin_addr) );
AddressToConnect.sin_port = RemotePort;
KeReleaseSpinLock(&Connection->Lock, OldIrql);
Status = OskitTCPConnect(Connection->SocketContext,
Connection,
&AddressToConnect,
sizeof(AddressToConnect));
return TCPTranslateError( OskitTCPConnect(Connection->SocketContext,
Connection,
&AddressToConnect,
sizeof(AddressToConnect)) );
if( Status == OSK_EINPROGRESS || Status == STATUS_SUCCESS )
return STATUS_PENDING;
else
return Status;
}
NTSTATUS TCPClose
@ -209,38 +225,76 @@ NTSTATUS TCPReceiveData
ULONG ReceiveLength,
ULONG ReceiveFlags,
PULONG BytesReceived ) {
KIRQL OldIrql;
PCONNECTION_ENDPOINT Connection;
PCHAR DataBuffer;
UINT DataLen, Received = 0;
NTSTATUS Status;
PTDI_BUCKET Bucket;
Connection = Request->Handle.ConnectionContext;
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
return TCPTranslateError
TI_DbgPrint(MID_TRACE,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
Status = TCPTranslateError
( OskitTCPRecv
( Connection->SocketContext,
DataBuffer,
DataLen,
&Received,
ReceiveFlags ) );
/* Keep this request around ... there was no data yet */
if( Status == STATUS_PENDING || Received == 0 ) {
/* Freed in TCPSocketState */
Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) );
if( !Bucket ) return STATUS_NO_MEMORY;
Bucket->Request = *Request;
InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
Status = STATUS_PENDING;
}
KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(MID_TRACE,("Status %x\n", Status));
return Status;
}
NTSTATUS TCPSendData
( PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize ) {
ULONG DataSize,
ULONG Flags,
PULONG DataUsed ) {
KIRQL OldIrql;
NTSTATUS Status;
PCONNECTION_ENDPOINT Connection;
PCHAR BufferData;
ULONG PacketSize;
int error;
Connection = Request->Handle.ConnectionContext;
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
NdisQueryBuffer( Buffer, &BufferData, &PacketSize );
Connection = Request->Handle.ConnectionContext;
return OskitTCPSend( Connection->SocketContext,
BufferData, PacketSize, 0 );
TI_DbgPrint(MID_TRACE,("Connection = %x\n", Connection));
TI_DbgPrint(MID_TRACE,("Connection->SocketContext = %x\n",
Connection->SocketContext));
Status = OskitTCPSend( Connection->SocketContext,
BufferData, PacketSize, (OSK_UINT *)DataUsed, 0 );
KeReleaseSpinLock(&Connection->Lock, OldIrql);
return Status;
}
NTSTATUS TCPTimeout(VOID) {

View file

@ -168,7 +168,8 @@ NTSTATUS UDPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize)
ULONG DataSize,
PULONG DataUsed )
/*
* FUNCTION: Sends an UDP datagram to a remote address
* ARGUMENTS:
@ -183,6 +184,12 @@ NTSTATUS UDPSendDatagram(
PDATAGRAM_SEND_REQUEST SendRequest;
PADDRESS_FILE AddrFile =
(PADDRESS_FILE)Request->Handle.AddressHandle;
PCHAR BufferData;
UINT BufferLen;
NdisQueryBuffer( Buffer, &BufferData, &BufferLen );
*DataUsed = BufferLen;
BuildUDPPacket( SendRequest,
(PIP_ADDRESS)&AddrFile->ADE->Address->Address.