mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 01:42:30 +00:00
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:
parent
aa11660dd0
commit
494edc04e5
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue