mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[TCPIP]
- Implement support for SO_REUSEADDR svn path=/trunk/; revision=57116
This commit is contained in:
parent
e1499f3b9e
commit
4d9b81048b
6 changed files with 72 additions and 2 deletions
|
@ -16,6 +16,7 @@ NTSTATUS FileOpenAddress(
|
|||
PTDI_REQUEST Request,
|
||||
PTA_IP_ADDRESS AddrList,
|
||||
USHORT Protocol,
|
||||
BOOLEAN Shared,
|
||||
PVOID Options);
|
||||
|
||||
NTSTATUS FileCloseAddress(
|
||||
|
|
|
@ -135,6 +135,7 @@ typedef struct _ADDRESS_FILE {
|
|||
USHORT Family; /* Address family */
|
||||
USHORT Protocol; /* Protocol number */
|
||||
USHORT Port; /* Network port (network byte order) */
|
||||
LONG Sharers; /* Number of file objects with this addr file */
|
||||
UCHAR TTL; /* Time to live stored in packets sent from this address file */
|
||||
UINT DF; /* Don't fragment */
|
||||
UINT BCast; /* Receive broadcast packets */
|
||||
|
|
|
@ -99,6 +99,40 @@ BOOLEAN AddrReceiveMatch(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
PADDRESS_FILE AddrFindShared(
|
||||
PIP_ADDRESS BindAddress,
|
||||
USHORT Port,
|
||||
USHORT Protocol)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
KIRQL OldIrql;
|
||||
PADDRESS_FILE Current = NULL;
|
||||
|
||||
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
|
||||
|
||||
CurrentEntry = AddressFileListHead.Flink;
|
||||
while (CurrentEntry != &AddressFileListHead) {
|
||||
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry);
|
||||
|
||||
/* See if this address matches the search criteria */
|
||||
if ((Current->Port == Port) &&
|
||||
(Current->Protocol == Protocol))
|
||||
{
|
||||
/* Increase the sharer count */
|
||||
ASSERT(Current->Sharers != 0);
|
||||
InterlockedIncrement(&Current->Sharers);
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
Current = NULL;
|
||||
}
|
||||
|
||||
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
|
||||
|
||||
return Current;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: Searches through address file entries to find next match
|
||||
* ARGUMENTS:
|
||||
|
@ -254,6 +288,7 @@ VOID ControlChannelFree(
|
|||
* Request = Pointer to TDI request structure for this request
|
||||
* Address = Pointer to address to be opened
|
||||
* Protocol = Protocol on which to open the address
|
||||
* Shared = Specifies if the address is opened for shared access
|
||||
* Options = Pointer to option buffer
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
|
@ -262,12 +297,24 @@ NTSTATUS FileOpenAddress(
|
|||
PTDI_REQUEST Request,
|
||||
PTA_IP_ADDRESS Address,
|
||||
USHORT Protocol,
|
||||
BOOLEAN Shared,
|
||||
PVOID Options)
|
||||
{
|
||||
PADDRESS_FILE AddrFile;
|
||||
|
||||
TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));
|
||||
|
||||
/* If it's shared and has a port specified, look for a match */
|
||||
if ((Shared != FALSE) && (Address->Address[0].Address[0].sin_port != 0))
|
||||
{
|
||||
AddrFile = AddrFindShared(NULL, Address->Address[0].Address[0].sin_port, Protocol);
|
||||
if (AddrFile != NULL)
|
||||
{
|
||||
Request->Handle.AddressHandle = AddrFile;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
AddrFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(ADDRESS_FILE),
|
||||
ADDR_FILE_TAG);
|
||||
if (!AddrFile) {
|
||||
|
@ -279,6 +326,7 @@ NTSTATUS FileOpenAddress(
|
|||
|
||||
AddrFile->RefCount = 1;
|
||||
AddrFile->Free = AddrFileFree;
|
||||
AddrFile->Sharers = 1;
|
||||
|
||||
/* Set our default options */
|
||||
AddrFile->TTL = 128;
|
||||
|
@ -431,6 +479,13 @@ NTSTATUS FileCloseAddress(
|
|||
|
||||
LockObject(AddrFile, &OldIrql);
|
||||
|
||||
if (InterlockedDecrement(&AddrFile->Sharers) != 0)
|
||||
{
|
||||
/* Still other guys have open handles to this, so keep it around */
|
||||
UnlockObject(AddrFile, OldIrql);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* We have to close this listener because we started it */
|
||||
if( AddrFile->Listener )
|
||||
{
|
||||
|
|
|
@ -113,6 +113,7 @@ NTSTATUS TiCreateFileObject(
|
|||
PVOID ClientContext;
|
||||
NTSTATUS Status;
|
||||
ULONG Protocol;
|
||||
BOOLEAN Shared;
|
||||
|
||||
TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
|
||||
|
||||
|
@ -196,7 +197,9 @@ NTSTATUS TiCreateFileObject(
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = FileOpenAddress(&Request, Address, Protocol, NULL);
|
||||
Shared = (IrpSp->Parameters.Create.ShareAccess != 0);
|
||||
|
||||
Status = FileOpenAddress(&Request, Address, Protocol, Shared, NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
#define TCP_QUEUE_OOSEQ 1
|
||||
|
||||
#define SO_REUSE 1
|
||||
|
||||
/* FIXME: These MSS and TCP Window definitions assume an MTU
|
||||
* of 1500. We need to add some code to lwIP which would allow us
|
||||
* to change these values based upon the interface we are
|
||||
|
|
|
@ -317,6 +317,7 @@ void
|
|||
LibTCPBindCallback(void *arg)
|
||||
{
|
||||
struct lwip_callback_msg *msg = arg;
|
||||
PTCP_PCB pcb = msg->Input.Bind.Connection->SocketContext;
|
||||
|
||||
ASSERT(msg);
|
||||
|
||||
|
@ -326,7 +327,14 @@ LibTCPBindCallback(void *arg)
|
|||
goto done;
|
||||
}
|
||||
|
||||
msg->Output.Bind.Error = tcp_bind((PTCP_PCB)msg->Input.Bind.Connection->SocketContext,
|
||||
/* If this address file is shared, set the SOF_REUSEADDR flag in the PCB */
|
||||
ASSERT(msg->Input.Bind.Connection->AddressFile != NULL);
|
||||
if (msg->Input.Bind.Connection->AddressFile->Sharers != 1)
|
||||
{
|
||||
pcb->so_options |= SOF_REUSEADDR;
|
||||
}
|
||||
|
||||
msg->Output.Bind.Error = tcp_bind(pcb,
|
||||
msg->Input.Bind.IpAddress,
|
||||
ntohs(msg->Input.Bind.Port));
|
||||
|
||||
|
|
Loading…
Reference in a new issue