UDP working.

svn path=/trunk/; revision=11657
This commit is contained in:
Art Yerkes 2004-11-14 19:45:16 +00:00
parent 1dcd7629c6
commit 323b7c4460
10 changed files with 90 additions and 146 deletions

View file

@ -1,4 +1,4 @@
/* $Id: main.c,v 1.9 2004/11/12 09:27:02 arty Exp $
/* $Id: main.c,v 1.10 2004/11/14 19:45:16 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/main.c
@ -22,8 +22,8 @@
extern NTSTATUS DDKAPI MmCopyFromCaller( PVOID Dst, PVOID Src, UINT Size );
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = DEBUG_ULTRA;
//DWORD DebugTraceLevel = 0;
//DWORD DebugTraceLevel = DEBUG_ULTRA;
DWORD DebugTraceLevel = 0;
#endif /* DBG */

View file

@ -1,4 +1,4 @@
/* $Id: read.c,v 1.8 2004/11/12 07:34:56 arty Exp $
/* $Id: read.c,v 1.9 2004/11/14 19:45:16 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/read.c
@ -45,6 +45,7 @@ NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
i,
Map[i].BufferAddress,
BytesToCopy));
RtlCopyMemory( Map[i].BufferAddress,
FCB->Recv.Window + FCB->Recv.BytesUsed,
BytesToCopy );
@ -100,7 +101,7 @@ NTSTATUS DDKAPI ReceiveComplete
AFD_DbgPrint(MID_TRACE,("FCB %x Receive data waiting %d\n",
FCB, FCB->Recv.Content));
OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );
/*OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );*/
Status = STATUS_SUCCESS;
@ -253,6 +254,9 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
BytesToCopy =
MIN( RecvReq->BufferArray[0].len, BytesAvailable );
AFD_DbgPrint(MID_TRACE,("BytesToCopy: %d len %d\n", BytesToCopy,
RecvReq->BufferArray[0].len));
if( Map[0].Mdl ) {
Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode );
@ -260,6 +264,10 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
0,
Map[0].BufferAddress,
BytesToCopy));
/* OskitDumpBuffer
( FCB->Recv.Window + FCB->Recv.BytesUsed, BytesToCopy ); */
RtlCopyMemory( Map[0].BufferAddress,
FCB->Recv.Window + FCB->Recv.BytesUsed,
BytesToCopy );
@ -316,12 +324,12 @@ PacketSocketRecvComplete(
while( NT_SUCCESS(Status) &&
!IsListEmpty( &FCB->DatagramList ) &&
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV_DATAGRAM] ) ) {
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
ListEntry = RemoveHeadList( &FCB->DatagramList );
DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
ListEntry );
ListEntry = RemoveHeadList
( &FCB->PendingIrpList[FUNCTION_RECV_DATAGRAM] );
( &FCB->PendingIrpList[FUNCTION_RECV] );
NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
@ -396,6 +404,10 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if( !(RecvReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete
( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE );
RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
RecvReq->BufferCount,
TRUE );
if( !IsListEmpty( &FCB->DatagramList ) ) {
ListEntry = RemoveHeadList( &FCB->DatagramList );
@ -420,9 +432,6 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
}
} else {
RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
RecvReq->BufferCount,
TRUE );
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV_DATAGRAM );
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
}
}

View file

@ -1,4 +1,4 @@
/* $Id: afd.h,v 1.21 2004/11/12 07:34:56 arty Exp $
/* $Id: afd.h,v 1.22 2004/11/14 19:45:16 arty Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -50,10 +50,9 @@
#define FUNCTION_CONNECT 0
#define FUNCTION_RECV 1
#define FUNCTION_RECV_DATAGRAM 2
#define FUNCTION_SEND 3
#define FUNCTION_CLOSE 4
#define MAX_FUNCTIONS 5
#define FUNCTION_SEND 2
#define FUNCTION_CLOSE 3
#define MAX_FUNCTIONS 4
#define IN_FLIGHT_REQUESTS 3

View file

@ -0,0 +1,30 @@
#ifndef _TCPIP_PORTS_H
#define _TCPIP_PORTS_H
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/ports.h
* PURPOSE: Port allocation
* PROGRAMMERS: arty (ayerkes@speakeasy.net)
* REVISIONS:
* arty 20041114 Created
*/
typedef struct _PORT_SET {
RTL_BITMAP ProtoBitmap;
PVOID ProtoBitBuffer;
UINT StartingPort;
UINT PortsToOversee;
FAST_MUTEX Mutex;
} PORT_SET, *PPORT_SET;
VOID PortsStartup( PPORT_SET PortSet,
UINT StartingPort,
UINT PortsToManage );
VOID PortsShutdown( PPORT_SET PortSet );
VOID DeallocatePort( PPORT_SET PortSet, ULONG Port );
BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port );
ULONG AllocateAnyPort( PPORT_SET PortSet );
#endif/*_TCPIP_PORTS_H*/

View file

@ -7,6 +7,7 @@
#include <loopback.h>
#include <ip.h>
#include <lan.h>
#include <datagram.h>
#include <checksum.h>
#include <address.h>
#include <routines.h>
@ -26,7 +27,6 @@
#include <tilists.h>
#include <dispatch.h>
#include <fileobjs.h>
#include <datagram.h>
#include <info.h>
#include <lock.h>
#include <wait.h>
@ -34,3 +34,4 @@
#include <memtrack.h>
#include <oskittcp.h>
#include <interface.h>
#include <ports.h>

View file

@ -52,8 +52,6 @@
#include <titypes.h>
#include <ticonsts.h>
#include <udp.h>
/* Macros */
@ -156,7 +154,6 @@ extern KSPIN_LOCK EntityListLock;
extern TDIEntityInfo *EntityList;
extern ULONG EntityCount;
extern ULONG EntityMax;
extern UDP_STATISTICS UDPStats;
extern NTSTATUS TiGetProtocolNumber( PUNICODE_STRING FileName,
PULONG Protocol );

View file

@ -110,6 +110,8 @@ typedef VOID (*DATAGRAM_COMPLETION_ROUTINE)(
NDIS_STATUS Status,
ULONG Count);
typedef DATAGRAM_COMPLETION_ROUTINE PDATAGRAM_COMPLETION_ROUTINE;
typedef struct _DATAGRAM_RECEIVE_REQUEST {
LIST_ENTRY ListEntry; /* Entry on list */
IP_ADDRESS RemoteAddress; /* Remote address we receive from (NULL means any) */

View file

@ -7,6 +7,8 @@
#ifndef __UDP_H
#define __UDP_H
#define UDP_STARTING_PORT 0x8000
#define UDP_DYNAMIC_PORTS 0x8000
/* UDPv4 header structure */
typedef struct UDP_HEADER {
@ -34,6 +36,8 @@ typedef struct UDP_STATISTICS {
ULONG NumAddresses;
} UDP_STATISTICS, *PUDP_STATISTICS;
extern UDP_STATISTICS UDPStats;
VOID UDPSend(
PVOID Context,
PDATAGRAM_SEND_REQUEST SendRequest);
@ -52,7 +56,9 @@ NTSTATUS UDPReceiveDatagram(
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived);
PULONG BytesReceived,
PDATAGRAM_COMPLETION_ROUTINE Complete,
PVOID Context);
VOID UDPReceive(
PNET_TABLE_ENTRY NTE,
@ -63,6 +69,8 @@ NTSTATUS UDPStartup(
NTSTATUS UDPShutdown(
VOID);
UINT UDPAllocatePort( UINT HintPort );
VOID UDPFreePort( UINT Port );
#endif /* __UDP_H */

View file

@ -730,7 +730,9 @@ NTSTATUS DispTdiReceiveDatagram(
DgramInfo->ReceiveLength,
DgramInfo->ReceiveFlags,
DgramInfo->ReturnDatagramInformation,
&BytesReceived);
&BytesReceived,
(PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete,
Irp);
if (Status != STATUS_PENDING)
{
DispDataRequestComplete(Irp, Status, BytesReceived);

View file

@ -211,84 +211,6 @@ VOID DeleteConnectionEndpoint(
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
#if 0
VOID STDCALL RequestWorker(PVOID Context)
/*
* FUNCTION: Worker routine for processing address file object requests
* ARGUMENTS:
* Context = Pointer to context information (ADDRESS_FILE)
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PADDRESS_FILE AddrFile = Context;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Check it the address file should be deleted */
if (AF_IS_PENDING(AddrFile, AFF_DELETE)) {
DATAGRAM_COMPLETION_ROUTINE RtnComplete;
PVOID RtnContext;
RtnComplete = AddrFile->Complete;
RtnContext = AddrFile->Context;
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
(*RtnComplete)(RtnContext, TDI_SUCCESS, 0);
TI_DbgPrint(MAX_TRACE, ("Leaving (delete).\n"));
return;
}
/* Check if there is a pending send request */
if (AF_IS_PENDING(AddrFile, AFF_SEND)) {
if (!IsListEmpty(&AddrFile->TransmitQueue)) {
PDATAGRAM_SEND_REQUEST SendRequest;
CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
AF_CLR_BUSY(AddrFile);
ReferenceObject(AddrFile);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* The send routine processes the send requests in
the transmit queue on the address file. When the
queue is empty the pending send flag is cleared.
The routine may return with the pending send flag
set. This can happen if there was not enough free
resources available to complete all send requests */
DGSend(AddrFile, SendRequest);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
DereferenceObject(AddrFile);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (send request).\n"));
return;
} else
/* There was a pending send, but no send request.
Print a debug message and continue */
TI_DbgPrint(MIN_TRACE, ("Pending send, but no send request.\n"));
}
AF_CLR_BUSY(AddrFile);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
#endif
/*
* FUNCTION: Open an address file object
* ARGUMENTS:
@ -308,7 +230,7 @@ NTSTATUS FileOpenAddress(
PADDRESS_FILE AddrFile;
IPv4_RAW_ADDRESS IPv4Address;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));
AddrFile = ExAllocatePool(NonPagedPool, sizeof(ADDRESS_FILE));
if (!AddrFile) {
@ -329,9 +251,9 @@ NTSTATUS FileOpenAddress(
/* FIXME: IPv4 only */
IPv4Address = Address->Address[0].Address[0].in_addr;
if (IPv4Address == 0)
AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
else
AddrFile->ADE = AddrLocateADEv4(IPv4Address);
AddrFile->ADE = AddrLocateADEv4(IPv4Address);
if (!AddrFile->ADE) {
ExFreePool(AddrFile);
@ -339,8 +261,8 @@ NTSTATUS FileOpenAddress(
return STATUS_INVALID_PARAMETER;
}
TI_DbgPrint(MID_TRACE, ("Opening address %s for communication.\n",
A2S(&AddrFile->ADE->Address)));
TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n",
A2S(&AddrFile->ADE->Address), Protocol, IPPROTO_UDP));
/* Protocol specific handling */
switch (Protocol) {
@ -351,10 +273,12 @@ NTSTATUS FileOpenAddress(
break;
case IPPROTO_UDP:
/* FIXME: If specified port is 0, a port is chosen dynamically */
AddrFile->Port = Address->Address[0].Address[0].sin_port;
AddrFile->Send = UDPSendDatagram;
break;
TI_DbgPrint(MID_TRACE,("Allocating udp port\n"));
AddrFile->Port =
UDPAllocatePort(Address->Address[0].Address[0].sin_port);
TI_DbgPrint(MID_TRACE,("Setting port %d\n", AddrFile->Port));
AddrFile->Send = UDPSendDatagram;
break;
default:
/* Use raw IP for all other protocols */
@ -376,9 +300,6 @@ NTSTATUS FileOpenAddress(
InitializeListHead(&AddrFile->ReceiveQueue);
InitializeListHead(&AddrFile->TransmitQueue);
/* Initialize work queue item. We use this for pending requests */
/*ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);*/
/* Initialize spin lock that protects the address file object */
KeInitializeSpinLock(&AddrFile->Lock);
@ -420,40 +341,15 @@ NTSTATUS FileCloseAddress(
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (!AF_IS_BUSY(AddrFile)) {
/* Set address file object exclusive to us */
AF_SET_BUSY(AddrFile);
AF_CLR_VALID(AddrFile);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
} else {
if (!AF_IS_PENDING(AddrFile, AFF_DELETE)) {
AddrFile->Complete = Request->RequestNotifyObject;
AddrFile->Context = Request->RequestContext;
/* Shedule address file for deletion */
AF_SET_PENDING(AddrFile, AFF_DELETE);
AF_CLR_VALID(AddrFile);
if (!AF_IS_BUSY(AddrFile)) {
/* Worker function is not running, so shedule it to run */
AF_SET_BUSY(AddrFile);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
ExQueueWorkItem(&AddrFile->WorkItem, CriticalWorkQueue);
} else
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
return STATUS_PENDING;
} else
Status = STATUS_ADDRESS_CLOSED;
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
}
/* Set address file object exclusive to us */
AF_SET_BUSY(AddrFile);
AF_CLR_VALID(AddrFile);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
UDPFreePort( AddrFile->Port );
DeleteAddress(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return Status;