listen ???
От: Аноним  
Дата: 18.10.06 11:52
Оценка:
Здраствуйте.

Не подскажете как реализовать listen, на tdi уровне. Есть драйвер и создаваемый им поток который должен работать с сетью.

while (workThread)
    {
        switch (KeWaitForMultipleObjects(1, events, WaitAny, Executive, KernelMode, FALSE, NULL, waitBlocks))
        {
        case EV_COMMAND_WORK_TO_DO:
            {
                command = pBRDGDevExt->packet.command;
                switch(command)
                {
                case CONNECT:
                    {
                    
                        Status = k_Connect(pTCPContext);
                                     //...............................
                        break;
                    }
                case BIND:
                    {
                        Status = k_Bind(pTCPContext);
                          //..........................
                        break;
                    }
                case LISTEN:
                    {
                        Status = k_Listen(pTCPContext);
                           //........................

                        break;
                    }
                case ACCEPT:
                    {
                        Status = k_Accept(pTCPContext);
                          //...............................

                        break;
                    }
                      //....................................
                              // и так далее
                }
                break;
            }
        }

        pBRDGDevExt->packet.status = Status;


        KeReleaseSemaphore(&pBRDGDevExt->KScommand, 0, 1, FALSE);
    }


вот собственно сама ф-ия k_listen:

SOCKET k_listen(SOCKET s, SOCK_ADDR* addr, int addrlen)
{
    PSocketData    sdata = (PSocketData)s; 
    PSocketData NewSocket = NULL;
    NTSTATUS    status;
    PDEVICE_OBJECT pDeviceObject;

    if (k_IsValidSocket(s))
    {
        NewSocket = ExAllocatePool(NonPagedPool, sizeof(TSocketData));

        if (NewSocket)
        {
            RtlZeroMemory(NewSocket, sizeof(TSocketData)); //!
            NewSocket->Type         = sdata->Type;
            NewSocket->Protocol     = sdata->Protocol;
            NewSocket->m_Point.m_hAddress = INVALID_HANDLE_VALUE; 
            NewSocket->m_endPoint.m_hContext = INVALID_HANDLE_VALUE;


            status = k_OpenConnectionEndpoint(sdata, NewSocket, NewSocket);

            if (!NT_SUCCESS(status))
            {
                k_CloseConnectionEndpoint( &NewSocket->m_endPoint );

                ExFreePool(NewSocket);

                return SOCKET_ERROR;


            }


            pDeviceObject = IoGetRelatedDeviceObject(NewSocket->m_endPoint.m_pFileObject);

            NewSocket->m_pListenIrp = IoAllocateIrp(
                              pDeviceObject->StackSize,
                              FALSE
                              );

            if( !NewSocket->m_pListenIrp )
            {
                k_CloseConnectionEndpoint( &NewSocket->m_endPoint );
                return( STATUS_INSUFFICIENT_RESOURCES );
            }

            
            NewSocket->m_RemoteConnectionInfo.UserDataLength = 0;
            NewSocket->m_RemoteConnectionInfo.UserData = NULL;

            NewSocket->m_RemoteConnectionInfo.OptionsLength = 0;
            NewSocket->m_RemoteConnectionInfo.Options = NULL;

            NewSocket->m_RemoteConnectionInfo.RemoteAddressLength = sizeof( TA_IP_ADDRESS );
            NewSocket->m_RemoteConnectionInfo.RemoteAddress = &NewSocket->m_RemoteAddress;

            
            TdiBuildListen(
                    NewSocket->m_pListenIrp,
                    pDeviceObject,
                    NewSocket->m_endPoint.m_pFileObject,
                    k_ConnectedCallback, // Completion Routine
                    NewSocket,               // Completion Context
                    0,                      // Flags
                    NULL,                   // Request Connection Info
                    &NewSocket->m_RemoteConnectionInfo
                    );

            status = IoCallDriver( pDeviceObject, NewSocket->m_pListenIrp );

            if (NT_SUCCESS(status))    return (SOCKET)NewSocket;
        }
    }

    if (NewSocket) ExFreePool(NewSocket);
    return SOCKET_ERROR;
}


Вроде все нормально.Только при конекте клиента, сразу же происходит диконект, без события на recive. А callback ф-ия k_ConnectedCallback должна опять вызват listen, но она возвращает статус 0xC000023b(STATUS_CONNECTION_ACTIVE). Вот пример ф-ии

NTSTATUS
k_ConnectedCallback(
   IN PDEVICE_OBJECT pDeviceObject,
   IN PIRP pIrp,
   IN PVOID Context
   )
{
    PSocketData  pSocket = (PSocketData)Context;

    NTSTATUS Status = pIrp->IoStatus.Status;

    KdPrint(( "k_ConnectedCallback: FinalStatus: 0x%8.8x\n", Status ));



   if( NT_SUCCESS( Status ) )
   {
      pSocket->m_nBytesReceived = 0;

//      (pSocket->m_pReceiveMdl)->Next = NULL; 

        Status = k_ReceiveOnEndpoint(
                  &pSocket->m_endPoint,
                  NULL,       // User Completion Event
                  k_ReceiveCompletion,// User Completion Routine
                  pSocket,   // User Completion Context
                  &pSocket->m_pReceiveIoStatus,
                  pSocket->m_pReceiveMdl,
                  0           // Flags
                  );
  }

    return( STATUS_MORE_PROCESSING_REQUIRED );
}


Т.е. "листена" больше не происходит, даже после переинециализации девайса(не драйвера).
Re: listen ???
От: TarasCo  
Дата: 18.10.06 14:53
Оценка:
Здравствуйте, Аноним, Вы писали:

Попробуйте установить флаг TDI_QUERY_ACCEPT в запросе TDI_LISTEN. В функции обработчике окончания запроса TDI_LISTEN в случае успеха вызовете запрос TDI_ACCEPT, по успешному окончанию которого можно считать соединение успешно установленным.
Да пребудет с тобою сила
Re[2]: listen ???
От: Аноним  
Дата: 19.10.06 14:39
Оценка:
Здравствуйте, TarasCo, Вы писали:

TC>Здравствуйте, Аноним, Вы писали:


TC>Попробуйте установить флаг TDI_QUERY_ACCEPT в запросе TDI_LISTEN. В функции обработчике окончания запроса TDI_LISTEN в случае успеха вызовете запрос TDI_ACCEPT, по успешному окончанию которого можно считать соединение успешно установленным.


Не подскажете какая последовательность действий по созданию kernel-socket, вчастности интересует создание именно серверной части. Много просмотрел примеров, и у всех алгоритмы создания сокета разные, в отличе от SDK сокета

Для чего в некоторых реализациях используется TdiBuildInternalDeviceControlIrp?
Re[3]: listen ???
От: TarasCo  
Дата: 20.10.06 20:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Не подскажете какая последовательность действий по созданию kernel-socket, вчастности интересует создание именно серверной части. Много просмотрел примеров, и у всех алгоритмы создания сокета разные, в отличе от SDK сокета


Ну нужно, конкретные моменты сранивать. Работая на низком уровне у Вас есть определенная гибкость и в результате появляются варианты. Кстати, реалтзация сервера в режиме приложения не так одназначна, как Вам кажется. Например, стандартные сервисы при приеме соединения не используют вызов accept/WSAAccept, а нечто другое ( это так, для возбуждения любопытства ).

А>Для чего в некоторых реализациях используется TdiBuildInternalDeviceControlIrp?


Это делает код компактнее — не нужно самостоятельно создавать IRP, не нужно его потом удалять. Короче — вопрос стиля

Вот еше ссылка здесь же по теме:
http://rsdn.ru/Forum/Message.aspx?mid=2042652
Автор: TarasCo
Дата: 04.08.06
Да пребудет с тобою сила
Re[4]: listen ???
От: Аноним  
Дата: 25.10.06 12:54
Оценка:
Здравствуйте, TarasCo, Вы писали:


TC>Ну нужно, конкретные моменты сранивать. Работая на низком уровне у Вас есть определенная гибкость и в результате появляются варианты. Кстати, реалтзация сервера в режиме приложения не так одназначна, как Вам кажется. Например, стандартные сервисы при приеме соединения не используют вызов accept/WSAAccept, а нечто другое ( это так, для возбуждения любопытства ).


Не могли бы Вы пояснить насчет "нечто другое" ? Есть подозрение что устанавливается просто событие на конект/прием. Только как привязаться к нужному порту? И как проще организовать соединение точка-точка?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.