TDI - Check if TCP port is available

Hi,
I’m maintaining a TDI filter driver whose purpose is to assign source ports of connections within special per-user port ranges.

My TDI filter driver is intercepting IRP_MJ_CREATE requests, and assigning the source port of each opened TCP/UDP connection according to my needs. The driver is internally maintaining a table with the connections (including socket open/close and TCP grace-period/time-wait), but I still see rare cases where the driver has incorrect information regarding availability of specific ports (maybe because certain notifications are not caught be the driver), causing issues where the driver assigns a used TCP port to user processes, resulting in connection drops.
I improved the situation by calling from my user mode process GetTcpTable once in a few minutes and updating the driver internal tables accordingly, but it is still happens that I still miss a few ports and get a drop (only happens with very specific applications).

Do you know an efficient way to check for port availability before I assign it? Another approach that might overcome it?

Thanks

> Hi,

I’m maintaining a TDI filter driver whose purpose is to assign source
ports of connections within special per-user port ranges.

My TDI filter driver is intercepting IRP_MJ_CREATE requests, and assigning
the source port of each opened TCP/UDP connection according to my needs.
The driver is internally maintaining a table with the connections
(including socket open/close and TCP grace-period/time-wait), but I still
see rare cases where the driver has incorrect information regarding
availability of specific ports (maybe because certain notifications are
not caught be the driver), causing issues where the driver assigns a used
TCP port to user processes, resulting in connection drops.
I improved the situation by calling from my user mode process GetTcpTable
once in a few minutes and updating the driver internal tables accordingly,
but it is still happens that I still miss a few ports and get a drop (only
happens with very specific applications).

Do you know an efficient way to check for port availability before I
assign it? Another approach that might overcome it?

Thanks

By “efficient” I presume you mean “a method that does not require
enumerating every port in the range”. But if you run a user process, that
is already some hefty overhead. So you need to be careful how you
interpret “efficient”, for example “I want a method that is 100% reliable
but is no slower than my current method”, and, for the right call (if one
or sequence of same exist) it might involve doing the enumeration.

HOWEVER, if you cannot lock the structure that is being used to track
these, you are in an unsolvable race condition. I suspect that you need
to call some lower-level port allocation function which guarantees that
once it has allocated the port number to you that it will not give it out
again. The “is this port number available?” followed by “assign this port
number to me” cannot possibly work correctly, because in between those two
events, some other execution path can ask the same question and get “yes”:

T1: is 55000 available?
T1: sees “yes”
T2: is 55000 available?
T2: sees “yes”
T1: allocates 55000
T2: allocates 55000

Note that if T2 uses an atomic call, the problem still exists, because T1
doesn’t use it. The problem with synchronization is that it only works if
everyone follows the rules, every time.
joe


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Hi,
Thanks for the suggestions.
Indeed, synchronization is a hard problem here, but I don’t mind failing a few times (as long as it’s rare enough). The result is a single connection failure; most applications can handle such failure once in a while. By the way, I don’t mind running the user mode check in a shorter interval (now it’s about 5 minutes), assuming it would still be reasonably efficient.
The specific applications I was referring is simply Java - nothing fancy…

The solution I’m evaluating now is creating a transport address object with the source port I want to test; I’m not sure regarding its efficiency as it’s an extra call to ZwCreateFile for each opened connection.
I thought about checking directly the TCP driver state, but couldn’t find a way that does not require reverse engineering.