Thanks Dmytro.
I’ll try this after my vacation. I think I’ll trace down setsockopt with
TCP_NODELAY to see what is the proper paramsters. By looking at your code, I
wonder if change entity to CO_TL_TCP will help.
Bi
-----Original Message-----
From: Dmytro Pohromskyy [mailto:xxxxx@synclive.com]
Sent: Thursday, December 05, 2002 3:45 PM
To: NT Developers Interest List
Subject: [ntdev] Re: TCP ACK of segments and timing
Hello Bi,
I’m strugging with Nagle too and have written the following
piece of code. It uses undocumented IOCTL to tcpip.sys to set extended
connection parameters. Some of the code was stolen from winsock helper
sample. The code returns STATUS_SUCCESS, but I don’t see any difference
in TCP timings.
Any suggestions why it doesn’t work?
Thank you.
IOCTL is sent to \Device\Tcp
{
Connect();
int OptionValue;
//
// Set TCP_NODELAY option
//
OptionValue = TRUE;
Status = SetTdiInformation(
TransportDeviceObject,
ConnectionFileObject,
CO_TL_ENTITY,
INFO_CLASS_PROTOCOL,
INFO_TYPE_CONNECTION,
TCP_SOCKET_NODELAY,
&OptionValue,
sizeof(OptionValue)
);
}
BOOLEAN TdiDeviceIoControl(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN ULONG IoControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
OUT PULONG OutputReturned
)
{
PIRP Irp;
NTSTATUS Status;
KEVENT Event;
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION StackLocation;
RtlZeroMemory(&IoStatusBlock, sizeof(IoStatusBlock));
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(
IoControlCode,
DeviceObject,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
FALSE,
&Event,
&IoStatusBlock
);
if(Irp == NULL)
{
DbgPrint(“TdiDeviceIoControl: Unable to allocate IRP\n”);
return FALSE;
}
StackLocation = IoGetNextIrpStackLocation( Irp );
StackLocation->FileObject = FileObject;
//
// Send Irp to the Device Object
//
Status = IoCallDriver(DeviceObject, Irp);
if(Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
}
else if(Status != STATUS_SUCCESS)
{
DbgPrint(“TdiDeviceIoControl: Status = %x\n”, Status);
return FALSE;
}
//
// Get Irp Final status
//
if( IoStatusBlock.Status != STATUS_SUCCESS)
{
DbgPrint(“TdiDeviceIoControl: Status = %x, Irp Status = 0x%08x\n”,
Status, IoStatusBlock.Status);
return FALSE;
}
if(OutputReturned != NULL)
*OutputReturned = IoStatusBlock.Information;
return TRUE;
}
NTSTATUS
SetTdiInformation (
IN PDEVICE_OBJECT TdiDeviceObject,
IN PFILE_OBJECT TdiFileObject,
IN ULONG Entity,
IN ULONG Class,
IN ULONG Type,
IN ULONG Id,
IN PVOID Value,
IN ULONG ValueLength
)
/*++
Routine Description:
Performs a TDI action to the TCP/IP driver. A TDI action translates
into a streams T_OPTMGMT_REQ.
Arguments:
TdiConnectionObjectHandle - a TDI connection object on which to perform
the TDI action.
Entity - value to put in the tei_entity field of the TDIObjectID
structure.
Class - value to put in the toi_class field of the TDIObjectID
structure.
Type - value to put in the toi_type field of the TDIObjectID
structure.
Id - value to put in the toi_id field of the TDIObjectID structure.
Value - a pointer to a buffer to set as the information.
ValueLength - the length of the buffer.
Return Value:
–*/
{
BOOLEAN CallResult;
PTCP_REQUEST_SET_INFORMATION_EX SetInfoEx;
ULONG BufferSize;
BufferSize = sizeof(TCP_REQUEST_SET_INFORMATION_EX) +
ValueLength - 1;
SetInfoEx = ExAllocatePool(NonPagedPool, BufferSize);
if(SetInfoEx == NULL)
{
DbgPrint(“SetTdiInformation is unable to allocate memory %d
bytes\n”, BufferSize);
return STATUS_NO_MEMORY;
}
SetInfoEx->ID.toi_entity.tei_entity = Entity;
SetInfoEx->ID.toi_entity.tei_instance = TL_INSTANCE;
SetInfoEx->ID.toi_class = Class;
SetInfoEx->ID.toi_type = Type;
SetInfoEx->ID.toi_id = Id;
RtlCopyMemory( SetInfoEx->Buffer, Value, ValueLength );
SetInfoEx->BufferSize = ValueLength;
CallResult = TdiDeviceIoControl(
TdiDeviceObject,
TdiFileObject,
IOCTL_TCP_SET_INFORMATION_EX,
SetInfoEx,
BufferSize,
NULL,
0,
NULL
);
ExFreePool(SetInfoEx);
if( !CallResult)
{
DbgPrint(“SetTdiInformation: DeviceIoControl failed\n”);
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
BC> Are you using Winsock in user mode or TDI client in kernel mode?
BC> In user mode, if you zero the send buffer on individual socket, it will
BC> disable Nagle algorithem. In kerenl TDI client, Max said that there are
BC> undocumented or special licensed way doing that.
Best regards,
Dmytro Pohromskyy mailto:xxxxx@synclive.com
Softick Card Export - Palm’s card as disk. Simple and powerful.
http://www.softick.com
You are currently subscribed to ntdev as: xxxxx@appstream.com
To unsubscribe send a blank email to %%email.unsub%%