Ajay Ajay - 3 months ago 17
C Question

Bind HTTP connection to specific adapter (Hint: Metered Connection)

Windows 8 and above has setting to make a Wi-Fi (and other) connection to be metered (and have cost attached to it, but irrelevant here). I've used Native Wi-Fi API and WCM APIs to find required information.

With sockets, it is possible to bind, selectively send, and ignoring incoming packets from/to the metered-connection. But, how to do this with WinHTTP APIs?

Some answers on StackOverflow and SuperUser suggest using ForceBindIP, but we cannot simply use it.

If MS Windows has implemented metered connections, ideally there should be some approach to instruct WinHTTP services to not to use specific connections.

Answer

Unfortunately, neither WinInet nor WinHTTP natively support what you are asking for.

You would likely have to resort to using the WinSock API bind() function to manually bind a WinInet/WinHTTP session socket to the desired network connection.

Prior to Windows 7, you could get a SOCKET handle from an HINTERNET handle by using InternetQueryOption() with the INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO option. It fills an INTERNET_DIAGNOSTIC_SOCKET_INFO struct with information about the connection, including the actual SOCKET handle.

However, this option is no longer supported in Windows 7 and later. And while it might be possible to track down the SOCKET handle manually with some extra work, I don't think it would do you any good. A socket needs to be bound with bind() before it attempts to connect to a server. The relevant information provided by WinInet/WinHTTP that could be used to hunt down the SOCKET handle is not made available until the connect attempt is in progress. Just prior to connecting, the info is not in the TCP routing tables yet. And one connected, it is too late to re-bind the socket.

So I think you are out of luck on this, unless/until Microsoft exposes a new API to support binding WinInet/WinHTTP sessions, or otherwise expose access to the SOCKET handle again.