Add Match localnetwork / getifaddrs support on Windows#859
Conversation
The "Match localnetwork" ssh_config criterion (readconf.c check_match_ifaddrs) and the BindInterface interface enumeration in sshconnect.c are gated on HAVE_IFADDRS_H. The Windows build never defined it and win32compat provided no getifaddrs(), so the criterion returned "match localnetwork: not supported on this platform". Implement POSIX getifaddrs()/freeifaddrs() over the Win32 GetAdaptersAddresses() API and enable the feature: - contrib/win32/win32compat/inc/ifaddrs.h: struct ifaddrs, IFF_* flags (Windows has no <net/if.h>), getifaddrs/freeifaddrs prototypes. - contrib/win32/win32compat/getifaddrs.c: implementation over GetAdaptersAddresses(); ifa_name is the adapter friendly name, which is what BindInterface matches on Windows. Disabled/disconnected adapters are returned without IFF_UP, so the consumers skip them. - config.h.vs: define HAVE_IFADDRS_H and HAVE_GETIFADDRS. - win32iocompat.vcxproj(.filters): build the new sources into posix_compat.lib. - ssh.vcxproj: link Iphlpapi.lib (GetAdaptersAddresses). - regress/unittests/win32compat/getifaddrs_tests.c: unit tests for getifaddrs()/freeifaddrs(), registered in tests.c/tests.h and the unittest-win32compat project. Verified on Windows: ssh.exe (OpenSSH_for_Windows_10.0p2) builds and "Match localnetwork" evaluates correctly (matches a CIDR containing a local interface address, e.g. loopback 127.0.0.0/8); getifaddrs unit checks pass; sources also cross-compile for ARM64.
There was a problem hiding this comment.
Pull request overview
Adds Windows support for ssh_config’s Match localnetwork (and the BindInterface address enumeration path) by providing a Win32-backed getifaddrs()/freeifaddrs() implementation in win32compat, then enabling and wiring it into the Visual Studio build and unit tests.
Changes:
- Introduces
contrib/win32/win32compat/getifaddrs.cplus a Windowsifaddrs.hshim (including minimalIFF_*flags). - Enables the feature in the Windows build (
HAVE_IFADDRS_H,HAVE_GETIFADDRS) and builds/links the new code (addsIphlpapi.libwhere needed). - Adds a Win32compat unit test and registers it in the test runner.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| regress/unittests/win32compat/tests.h | Registers the new getifaddrs unit test symbol. |
| regress/unittests/win32compat/tests.c | Runs the new getifaddrs unit test. |
| regress/unittests/win32compat/getifaddrs_tests.c | Adds unit tests for the Windows getifaddrs/freeifaddrs shim. |
| contrib/win32/win32compat/inc/ifaddrs.h | Adds a Windows-compatible struct ifaddrs + prototypes + minimal IFF_* flags. |
| contrib/win32/win32compat/getifaddrs.c | Implements getifaddrs/freeifaddrs over GetAdaptersAddresses(). |
| contrib/win32/openssh/win32iocompat.vcxproj.filters | Adds the new source/header to the VS filters. |
| contrib/win32/openssh/win32iocompat.vcxproj | Builds the new getifaddrs.c into posix_compat.lib. |
| contrib/win32/openssh/unittest-win32compat.vcxproj | Builds the new unit test and links Iphlpapi.lib. |
| contrib/win32/openssh/ssh.vcxproj | Links Iphlpapi.lib for the client. |
| contrib/win32/openssh/config.h.vs | Defines HAVE_IFADDRS_H and HAVE_GETIFADDRS for Windows builds. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
6fc24f0 to
9238271
Compare
Address PR review feedback: - getifaddrs.c: guarantee ifa_name is always set. Previously an entry could be emitted with ifa_name == NULL if the friendly-name conversion failed and the AdapterName fallback was unavailable; the consumers (readconf.c, sshconnect.c) skip NULL-name entries, which would silently drop valid addresses and violates the getifaddrs(3) contract. Treat the no-name case (in practice an allocation failure) as ENOMEM instead. - getifaddrs_tests.c: drop the empty-list and IPv4-loopback assumptions (the implementation allows an empty list, and IPv4 may be disabled). Assert only the call result and per-entry invariants.
9238271 to
98cbc60
Compare
|
Thanks for the review. Both points are addressed in 98cbc60 (kept as a separate commit on top of the original):
|
Tracking issue: PowerShell/Win32-OpenSSH#2440
Summary
Adds support for the
Match localnetworkssh_config criterion on Windows by implementing POSIXgetifaddrs()/freeifaddrs()over the Win32GetAdaptersAddresses()API.Previously
check_match_ifaddrs()(readconf.c) and theBindInterfaceinterface enumeration (sshconnect.c) were gated onHAVE_IFADDRS_H, which the Windows build never defined, andwin32compathad nogetifaddrs()— soMatch localnetworkalways returned "not supported on this platform".Changes
contrib/win32/win32compat/inc/ifaddrs.h(new):struct ifaddrs,IFF_*flags (Windows has no<net/if.h>),getifaddrs/freeifaddrsprototypes.contrib/win32/win32compat/getifaddrs.c(new): implementation overGetAdaptersAddresses().contrib/win32/openssh/config.h.vs: defineHAVE_IFADDRS_HandHAVE_GETIFADDRS.contrib/win32/openssh/win32iocompat.vcxproj(+.filters): build the new sources intoposix_compat.lib.contrib/win32/openssh/ssh.vcxproj: linkIphlpapi.lib.regress/unittests/win32compat/getifaddrs_tests.c(new): unit tests, registered intests.c/tests.handunittest-win32compat.Notes
Match localnetworkis client-only in 10.0 (readconf.c/ ssh_config).ifa_nameis the adapter friendly name (whatBindInterfacematches on Windows).IFF_UP, so the existing consumers skip them (matches POSIXgetifaddrs(3)semantics).Testing
Built on Windows x64 (Release).
ssh.exe(OpenSSH_for_Windows_10.0p2) builds and links;Match localnetwork 127.0.0.0/8matches the loopback (enumerated viagetifaddrs),203.0.113.0/24does not, and the "not supported on this platform" path is gone. Thegetifaddrsunit checks pass. Sources also cross-compile for ARM64.