Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

TDI Listen/Accept Code Problem

Good day. I'm trying to write a kernel mode code that uses the TDI interface to accept incoming TCP-connections. And this I can not. Schematic code shown below. Attempt to connect via telnet for the first time succeeds - Irp->IoStatus.Status == STATUS_SUCCESS, but when I try to send / receive data through that connection, I get STATUS_INVALID_DEVICE_STATE (0xC0000184). At this time Process Explorer shows listening socket and the established connection on the same port. Subsequent attempts to connect get Irp->IoStatus.Status == STATUS_CONNECTION_INVALID (0xC000023A). I can not understand why. Maybe I do not understand the mechanism? I would be grateful for the help.

 

 

 

/* Listen-socket has two lists - the list of sockets that are waiting to connect - backlog, as I understand it,
** and the list of sockets that are already connected. Access to lists regulates the Queued-SpinLock -
** in order to operate on the list was possible on IRQL <= DISPATCH_LEVEL.
** KernelSocketAccept(__in PKERNEL_SOCKET Socket, __out PKERNEL_SOCKET * AcceptedConnectionSocket) interface function
** waits for SocketConnectedEvent and when connected socket(sockets) appears in the ConnectedSockets list, takes connected
** socket from this list and returns pointer on it in output parameter.
*/

 


typedef struct _TDI_ACCEPT_IRP_CONTEXT{

        PKERNEL_SOCKET ListeningSocket;
 
        PKERNEL_SOCKET AcceptSocket;

 

        TDI_CONNECTION_INFORMATION RequestConnectionInformation;
        TA_IP_ADDRESS RequestRemoteAddressIPv4;
        TA_IP6_ADDRESS RequestRemoteAddressIPv6;
} TDI_ACCEPT_IRP_CONTEXT, *PTDI_ACCEPT_IRP_CONTEXT;

 


IO_COMPLETION_ROUTINE TDIAcceptIRPCompletionRoutine;
static NTSTATUS TDIAcceptIRPCompletionRoutine(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID Context){

        PTDI_ACCEPT_IRP_CONTEXT TDIAcceptIRPContext = (PTDI_ACCEPT_IRP_CONTEXT)Context;


        if(TDIAcceptIRPContext){
                if(TDIAcceptIRPContext->ListeningSocket && TDIAcceptIRPContext->AcceptSocket){
                        if(Irp->IoStatus.Status == STATUS_SUCCESS){
                                TDIAcceptIRPContext->AcceptSocket->Connected = true;


                                AppendSocketToSocketList(&TDIAcceptIRPContext->ListeningSocket->ConnectedSockets, TDIAcceptIRPContext->AcceptSocket);


                                KeSetEvent(&TDIAcceptIRPContext->ListeningSocket->SocketConnectedEvent, IO_NO_INCREMENT, FALSE);
                        }
                }


                ExFreeToNPagedLookasideList(&KernelSocketsModule.DataBufferLookAsideList, TDIAcceptIRPContext);
        }

 

        IoFreeIrp(Irp);

 

        return STATUS_MORE_PROCESSING_REQUIRED;
}

 

 

0 Kudos
Message 1 of 3
(6,801 Views)

static NTSTATUS TDIClientEventIncomingConnection(IN PVOID TdiEventContext,
                                                 IN LONG RemoteAddressLength,
                                                 IN PVOID RemoteAddress,
                                                 IN LONG UserDataLength,
                                                 IN PVOID UserData,
                                                 IN LONG OptionsLength,
                                                 IN PVOID Options,
                                                 OUT CONNECTION_CONTEXT * ConnectionContext,
                                                 OUT PIRP * AcceptIrp){

        NTSTATUS ThisFunctionResult = STATUS_CONNECTION_REFUSED;
        *ConnectionContext = NULL;
        *AcceptIrp = NULL;


        PKERNEL_SOCKET Socket = (PKERNEL_SOCKET)TdiEventContext;

        if(RemoteAddress){
                if(RemoteAddressLength >= sizeof(TA_IP_ADDRESS)){
                        if(((PTA_IP_ADDRESS)RemoteAddress)->Address[0].AddressType == TDI_ADDRESS_TYPE_IP){
 
                                PIRP AcceptConnectionIRP = IoAllocateIrp(Socket->TransportDeviceObject->StackSize + 1, FALSE);

  
                                if(AcceptConnectionIRP){

                                        PTDI_ACCEPT_IRP_CONTEXT TDIAcceptIRPContext = (PTDI_ACCEPT_IRP_CONTEXT)ExAllocateFromNPagedLookasideList(&KernelSocketsModule.DataBufferLookAsideList);

  
                                        if(TDIAcceptIRPContext){
 
                                                local_memset(TDIAcceptIRPContext, 0x00, sizeof(TDI_ACCEPT_IRP_CONTEXT));

                                                TDIAcceptIRPContext->RequestRemoteAddressIPv4.TAAddressCount = 1;
                                                TDIAcceptIRPContext->RequestRemoteAddressIPv4.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
                                                TDIAcceptIRPContext->RequestRemoteAddressIPv4.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;

                                                TDIAcceptIRPContext->RequestRemoteAddressIPv4.Address[0].Address[0].in_addr = ((PTA_IP_ADDRESS)RemoteAddress)->Address[0].Address[0].in_addr;
                                                TDIAcceptIRPContext->RequestRemoteAddressIPv4.Address[0].Address[0].sin_port = ((PTA_IP_ADDRESS)RemoteAddress)->Address[0].Address[0].sin_port;

                                                TDIAcceptIRPContext->RequestConnectionInformation.RemoteAddressLength = sizeof(TA_IP_ADDRESS);
                                                TDIAcceptIRPContext->RequestConnectionInformation.RemoteAddress = &TDIAcceptIRPContext->RequestRemoteAddressIPv4;

  
                                               

0 Kudos
Message 2 of 3
(6,800 Views)
PKERNEL_SOCKET SocketFromTheWaitingList = TakeSocketFromSocketList(&Socket->WaitingSockets);

  
                                                if(SocketFromTheWaitingList){

                                                        TDIAcceptIRPContext->ListeningSocket = Socket;
                                                        TDIAcceptIRPContext->AcceptSocket = SocketFromTheWaitingList;

  
                                                        TdiBuildAccept(AcceptConnectionIRP, Socket->TransportDeviceObject, SocketFromTheWaitingList->TransportDeviceFile.Object, TDIAcceptIRPCompletionRoutine, TDIAcceptIRPContext, &TDIAcceptIRPContext->RequestConnectionInformation, NULL);

 

                                                        IoSetNextIrpStackLocation(AcceptConnectionIRP);


                                                        *ConnectionContext = (CONNECTION_CONTEXT)Socket;
                                                        *AcceptIrp = AcceptConnectionIRP;
                                                        ThisFunctionResult = STATUS_MORE_PROCESSING_REQUIRED;
                                                }
                                        }
                                }
                        }
                }
        }

        return ThisFunctionResult;
}

 

//Module interface function
NTSTATUS KernelSocketListen(__in PKERNEL_SOCKET Socket){

        /* Creation of a number of sockets for use in ClientEventConnect - backlog.
        ** Creation consists of opening the connection to the transport driver - ZwCreateFile()
        ** and subsequent TDI_ASSOCIATE_ADDRESS.
        ** Puts these sockets in the list, access to which regulates the Queued-SpinLock -
        ** in order to operate on the list was possible on IRQL <= DISPATCH_LEVEL.
        ** This list is tied to the current listening socket - for which this function is called.
        ** All these actions are fully successful.
        */

        /* Then form the IRP - TDI_SET_EVENT_HANDLER with EventType == TDI_EVENT_CONNECT and
        ** call IoCallDriver(). As PFILE_OBJECT FileObj gives the address file object of this listen socket.
        ** Returns STATUS_SUCCESS.
        */

        /* It seems that in this function everything is working properly */

        return ThisFunctionResult;
}

//-------------------------------------------------------------------------------------

0 Kudos
Message 3 of 3
(6,799 Views)