Re: Корректное завершение в обработчике TDI_EVENT_RECEIVE
От: x64 Россия  
Дата: 23.08.11 10:41
Оценка: 1 (1)
А>...как корректно завершать сессию подключения в своём установленном обработчике TDI_EVENT_RECEIVE/TDI_EVENT_RECEIVE_EXPEDITED.

Вопрос не очень понятен. Что именно нужно сделать в обработчике ClientEventReceive? Варианта обычно только три: или надо разорвать ещё активное соединение, или надо что-то сделать в ситуации, когда в этом обработчике стало известно, что соединение будет разорвано или уже в процессе завершения, или нужно временно блокировать приходящие данные (для конкретного соединения или для всех сразу). В первом случае нужно асинхронно послать запрос TDI_DISCONNECT транспорту (или нижележащему фильтру, не важно) с флагом TDI_DISCONNECT_ABORT, затем в *BytesTaken указать столько байт, сколько показано в BytesAvailable, и вернуть STATUS_SUCCESS. Во втором случае лучше всего, думаю, вернуть STATUS_DATA_NOT_ACCEPTED, хотя вообще-то эта ситуация маловероятна. И, наконец, в третьем случае либо ставим в *BytesTaken значение из BytesIndicated и возвращаем STATUS_SUCCESS, либо, если данные необходимо придержать до некоторого момента, то их надо где-то сохранить в очереди, чтобы потом передать клиенту. В последнем случае логика слегка навороченная будет, но если просто разрешать/запрещать трафик, то это всё не нужно.

А>Может, нужно ещё и комплитить IRP в IoRequestPacket?


Этот IRP создаёт и кладёт в *IoRequestPacket клиент, а завершает его транспорт.
Корректное завершение в обработчике TDI_EVENT_RECEIVE
От: Аноним  
Дата: 23.08.11 09:45
Оценка:
Доброго времени суток!

Не очень понимаю, как корректно завершать сессию подключения в своём установленном обработчике TDI_EVENT_RECEIVE/TDI_EVENT_RECEIVE_EXPEDITED. STATUS_ACCESS_DENIED возвращать явно нельзя, в инете никакой информации найти не удалось. Может, нужно ещё и комплитить IRP в IoRequestPacket?


if( (TDI_EVENT_RECEIVE==pTdiSetHandler->EventType)||\
    (TDI_EVENT_RECEIVE_EXPEDITED==pTdiSetHandler->EventType) ){

    if(pTdiSetHandler->EventHandler){

        {...}
                                                                        0);
    pTdiSetHandler->EventHandler=ClientEventReceive;

        {...}
    }


NTSTATUS CommonClientEventReceive(IN PVOID TdiEventContext,IN CONNECTION_CONTEXT ConnectionContext,
                IN ULONG ReceiveFlags,IN ULONG BytesIndicated,IN ULONG BytesAvailable,
                OUT ULONG *BytesTaken,IN PVOID Tsdu,OUT PIRP *IoRequestPacket){

    PEVENT_CONNECT_CONTEXT pContext=(PEVENT_CONNECT_CONTEXT)TdiEventContext;

        if(IsBlockConnection(pContext->pProcess)){

           ReportInternetBlockEvent(pContext->pProcess);

           return STATUS_ACCESS_DENIED;
    }

    return ((ClientEventReceive_t)pContext->OldClientEventHandler)(pContext->OldClientEvent,ConnectContext,ReceiveFlags,BytesIndicated,BytesAvailable,BytesTaken,Tsdu,IoRequestPacket);
}
Re[2]: Корректное завершение в обработчике TDI_EVENT_RECEIVE
От: Аноним  
Дата: 23.08.11 12:17
Оценка:
Здравствуйте, x64, Вы писали:

А>>...как корректно завершать сессию подключения в своём установленном обработчике TDI_EVENT_RECEIVE/TDI_EVENT_RECEIVE_EXPEDITED.


x64>Вопрос не очень понятен. Что именно нужно сделать в обработчике ClientEventReceive? Варианта обычно только три: или надо разорвать ещё активное соединение, или надо что-то сделать в ситуации, когда в этом обработчике стало известно, что соединение будет разорвано или уже в процессе завершения, или нужно временно блокировать приходящие данные (для конкретного соединения или для всех сразу). В первом случае нужно асинхронно послать запрос TDI_DISCONNECT транспорту (или нижележащему фильтру, не важно) с флагом TDI_DISCONNECT_ABORT, затем в *BytesTaken указать столько байт, сколько показано в BytesAvailable, и вернуть STATUS_SUCCESS. Во втором случае лучше всего, думаю, вернуть STATUS_DATA_NOT_ACCEPTED, хотя вообще-то эта ситуация маловероятна. И, наконец, в третьем случае либо ставим в *BytesTaken значение из BytesIndicated и возвращаем STATUS_SUCCESS, либо, если данные необходимо придержать до некоторого момента, то их надо где-то сохранить в очереди, чтобы потом передать клиенту. В последнем случае логика слегка навороченная будет, но если просто разрешать/запрещать трафик, то это всё не нужно.


Большое спасибо! К сожалению, +1 поставить не получается, ну не суть.

А интересно, если блокировать получение трафа в обработчике TDI_EVENT_RECEIVE/TDI_EVENT_RECEIVE_EXPEDITED, то нужно ли при этом блокировать так же приходящие TDI_RECEIVE/TDI_RECEIVE_DATAGRAM извне в самом фильтре?
Re[3]: Корректное завершение в обработчике TDI_EVENT_RECEIVE
От: x64 Россия  
Дата: 23.08.11 13:16
Оценка:
А>К сожалению, +1 поставить не получается, ну не суть.

Вообще-то, суть, ибо оценки я люблю.
Зарегистрируйся, ничего сложного в этом нет.

А>А интересно, если блокировать получение трафа в обработчике TDI_EVENT_RECEIVE/TDI_EVENT_RECEIVE_EXPEDITED, то нужно ли при этом блокировать так же приходящие TDI_RECEIVE/TDI_RECEIVE_DATAGRAM извне в самом фильтре?


Ты напиши сначала, что нужно-то? Если хочешь сохранить соединения живыми, то так лучше не делать, иначе приложение решит, что произошла фатальная ошибка и разорвёт соединение. В этом случае придётся брать на себя часть работы транспорта по организации очереди pending receives и пускать их дальше, когда трафик нужно будет разблокировать. А если пофиг на это, тогда да, завершать все приходящие TDI_RECEIVE со статусом STATUS_CONNECTION_DISCONNECTED, при этом, разумеется, нужно не забыть разорвать все уже установленные соединения.
Re[4]: Корректное завершение в обработчике TDI_EVENT_RECEIVE
От: IRabinovich  
Дата: 23.08.11 13:33
Оценка:
Здравствуйте, x64, Вы писали:

x64>Зарегистрируйся, ничего сложного в этом нет.


Уговорил.

x64>Вообще-то, суть, ибо оценки я люблю.


Поставил.

x64>Ты напиши сначала, что нужно-то? Если хочешь сохранить соединения живыми, то так лучше не делать, иначе приложение решит, что произошла фатальная ошибка и разорвёт соединение. В этом случае придётся брать на себя часть работы транспорта по организации очереди pending receives и пускать их дальше, когда трафик нужно будет разблокировать. А если пофиг на это, тогда да, завершать все приходящие TDI_RECEIVE со статусом STATUS_CONNECTION_DISCONNECTED, при этом, разумеется, нужно не забыть разорвать все уже установленные соединения.


Полагаю, что лучше пусть система думает, что всё хорошо, данные ходят, но реально приложение их не получает, потому что при работе с локальной сетью W7 при блокировании TDI_RECEIVE_DATAGRAM/TDI_RECEIVE в фильтре с STATUS_INVALID_CONNECTION выпадает в осадок, причём в полном составе. Кстати, это интересно, но если я возвращаю STATUS_ACCESS_DENIED в обработчике TDI_EVENT_RECEIVE/TDI_EVENT_RECEIVE_EXPEDITED, но не компличу TDI_RECEIVE_DATAGRAM/TDI_RECEIVE, то W7 работает нормально.

Вот даже интересно, что будет, если комплитить TDI_RECEIVE_DATAGRAM/TDI_RECEIVE с STATUS_SUCCESS в фильтре.
Re[5]: Корректное завершение в обработчике TDI_EVENT_RECEIVE
От: x64 Россия  
Дата: 23.08.11 13:39
Оценка:
IR>Вот даже интересно, что будет, если комплитить TDI_RECEIVE_DATAGRAM/TDI_RECEIVE с STATUS_SUCCESS в фильтре.

Я бы не стал так делать.
Это не совсем нормальная логика транспорта.
Эти запросы должны успешно завершаться только если есть данные.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.