Filtering TCP out-of-band RRS feed

  • Question

  • I have implemented a driver that filters TCP streams according to MSDN design guides. It blocks all packets, puts them to queue with a call to FwpsCloneStreamData, then calls FwpsDiscardClonedStreamData for processed packets. The filtered data packets then injected back in a separate thread. When the queue above is too large, the driver returns FWPS_STREAM_ACTION_DEFER for a packet in classify routine to defer receives. When the queue becomes empty the driver calls FwpsStreamContinue to resume the inbound traffic.

    But the connection stalls after resuming  the inbound traffic. WFP indicates one or several inbound packets, and that’s all, nothing more after that.

    I have found in MSDN articles the words about FwpsStreamContinue restriction: “For out-of-band stream inspection callouts, FwpsStreamContinue0 must be not be called at the same time that the FwpStreamInjectAsync0 function is called.”.

    Also the comments in stmedit sample say the following: “   An OOB stream modification callout blocks all indicated data after cloning them for processing by a kernel mode worker thread (or marshalling the data to user mode for inspection); the resultant/edited data will then be put back to the stream via the stream injection API. For such a callout, the processed data must be (re-)injected back to the stream from within the ClassifyFn.”

    I guess the source of problem is in synchronization, because in my case FwpStreamInjectAsync is called outside the classify routine, and FWPS_STREAM_ACTION_DEFER can be returned when FwpStreamInjectAsync is in progress. The solution implemented in stmedit (injecting from ClassifyFn) is not an option, because it doesn’t allow injection when both sides of connection don’t send any data.

    Is there any usable way to synchronize the calls to FwpsStreamContinue, FwpStreamInjectAsync and ClassifyFn in a way allowing filtering the data out-of-band without hangs of the filtered connections?
    Thursday, May 23, 2013 2:22 PM


  • To those who have the same issue: I have implemented a workaround. I’m sure that there is a bug in WFP, related to deferring the inbound traffic. And hope that it will be fixed some day. I found no ways to make deferring work properly.

    My workaround: to defer receives my driver uses an additional callout with filters on layers FWPM_LAYER_OUTBOUND_TRANSPORT_V(4|6). It blocks TCP ACK packets when needed to defer the inbound traffic. Everything works similar to the method with FWPS_STREAM_ACTION_DEFER/FwpsStreamContinue0, but there are no issues described above.
    • Marked as answer by Vitaly.V Friday, May 24, 2013 1:29 AM
    Friday, May 24, 2013 1:25 AM

All replies

  • Hi, I am facing the same issue here. Could you give me a little more of a hint what packets do you block? To me it seems that it would lead me to blocking of every packet in the outgoing direction, since they all are (probably not neccessary but in reality yes) marked with the ACK flag. Wouldn't that cause unnecessary problems in the case of bi-directional/duplex traffic.  

    Thanks, Lukas

    Sunday, August 18, 2013 9:48 PM
  • I meant above the generic acknowledgement packets, having ACK in TCP flags field and zero length. Blocking such packets makes the remote side to delay sends until the acknowledgements are retransmitted.
    Monday, August 19, 2013 11:52 PM