Skip to content

Richfr/portmapping#40037

Draft
1wizkid wants to merge 2 commits intofeature/wsl-for-appsfrom
richfr/portmapping
Draft

Richfr/portmapping#40037
1wizkid wants to merge 2 commits intofeature/wsl-for-appsfrom
richfr/portmapping

Conversation

@1wizkid
Copy link
Copy Markdown

@1wizkid 1wizkid commented Mar 30, 2026

Summary of the Pull Request

PR Checklist

  • Closes: Link to issue #xxx
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

Validation Steps Performed

Copilot AI review requested due to automatic review settings March 30, 2026 16:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the WSLC Client SDK’s container port-mapping path to support custom host binding addresses (including IPv6) instead of always binding to 127.0.0.1, and relaxes/updates validation around the windowsAddress field.

Changes:

  • Convert windowsAddress (IPv4/IPv6) into a string binding address for WSLCPortMapping during container creation.
  • Add input validation for windowsAddress->ss_family in WslcSetContainerSettingsPortMappings.

Comment on lines +566 to +577
if (internalPort.windowsAddress->ss_family == AF_INET)
{
const auto* addr4 = reinterpret_cast<const sockaddr_in*>(internalPort.windowsAddress);
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET, &addr4->sin_addr, addrBuf, sizeof(addrBuf)));
convertedPort.Family = AF_INET;
}
else
{
const auto* addr6 = reinterpret_cast<const sockaddr_in6*>(internalPort.windowsAddress);
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, sizeof(addrBuf)));
convertedPort.Family = AF_INET6;
}
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internalPort.windowsAddress->ss_family is treated as IPv6 for any value other than AF_INET, and the code unconditionally casts to sockaddr_in6. If the family is neither AF_INET nor AF_INET6 (or the caller passes a malformed sockaddr), this becomes an invalid cast and can lead to undefined behavior/crashes. Add an explicit AF_INET6 branch and return/throw E_INVALIDARG (or similar) for unsupported families before casting.

Suggested change
if (internalPort.windowsAddress->ss_family == AF_INET)
{
const auto* addr4 = reinterpret_cast<const sockaddr_in*>(internalPort.windowsAddress);
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET, &addr4->sin_addr, addrBuf, sizeof(addrBuf)));
convertedPort.Family = AF_INET;
}
else
{
const auto* addr6 = reinterpret_cast<const sockaddr_in6*>(internalPort.windowsAddress);
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, sizeof(addrBuf)));
convertedPort.Family = AF_INET6;
}
const auto family = internalPort.windowsAddress->ss_family;
if (family == AF_INET)
{
const auto* addr4 = reinterpret_cast<const sockaddr_in*>(internalPort.windowsAddress);
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET, &addr4->sin_addr, addrBuf, sizeof(addrBuf)));
convertedPort.Family = AF_INET;
}
else if (family == AF_INET6)
{
const auto* addr6 = reinterpret_cast<const sockaddr_in6*>(internalPort.windowsAddress);
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, sizeof(addrBuf)));
convertedPort.Family = AF_INET6;
}
else
{
// Unsupported or invalid address family; avoid invalid cast.
THROW_HR(E_INVALIDARG);
}

Copilot uses AI. Check for mistakes.
const auto family = portMappings[i].windowsAddress->ss_family;
RETURN_HR_IF(E_INVALIDARG, family != AF_INET && family != AF_INET6);
}
RETURN_HR_IF(E_NOTIMPL, portMappings[i].protocol != 0);
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WslcSetContainerSettingsPortMappings currently rejects any protocol value other than 0 (WSLC_PORT_PROTOCOL_TCP) via RETURN_HR_IF(E_NOTIMPL, portMappings[i].protocol != 0);. This makes WSLC_PORT_PROTOCOL_UDP unusable even though the public header documents UDP support and WslcCreateContainer maps non-TCP to IPPROTO_UDP. Update validation to accept both WSLC_PORT_PROTOCOL_TCP and WSLC_PORT_PROTOCOL_UDP (and return E_INVALIDARG for out-of-range values).

Suggested change
RETURN_HR_IF(E_NOTIMPL, portMappings[i].protocol != 0);
RETURN_HR_IF(
E_INVALIDARG,
portMappings[i].protocol != WSLC_PORT_PROTOCOL_TCP && portMappings[i].protocol != WSLC_PORT_PROTOCOL_UDP);

Copilot uses AI. Check for mistakes.
Comment on lines +563 to +585
if (internalPort.windowsAddress != nullptr)
{
char addrBuf[INET6_ADDRSTRLEN]{};
if (internalPort.windowsAddress->ss_family == AF_INET)
{
const auto* addr4 = reinterpret_cast<const sockaddr_in*>(internalPort.windowsAddress);
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET, &addr4->sin_addr, addrBuf, sizeof(addrBuf)));
convertedPort.Family = AF_INET;
}
else
{
const auto* addr6 = reinterpret_cast<const sockaddr_in6*>(internalPort.windowsAddress);
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, sizeof(addrBuf)));
convertedPort.Family = AF_INET6;
}
bindingAddressStrings[i] = addrBuf;
convertedPort.BindingAddress = bindingAddressStrings[i].c_str();
}
else
{
convertedPort.Family = AF_INET;
convertedPort.BindingAddress = "127.0.0.1";
}
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change adds support for custom binding addresses (including IPv6) when creating containers, but there are existing TAEF SDK tests for port mapping that currently only cover the default IPv4 localhost TCP case. Please add/extend tests to cover: (1) a mapping with windowsAddress set (IPv4 and IPv6) and (2) UDP mappings, to prevent regressions in address-family handling and string conversion.

Copilot uses AI. Check for mistakes.
Comment on lines +583 to +584
convertedPort.Family = AF_INET;
convertedPort.BindingAddress = "127.0.0.1";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just leave these unset if not provided? If the default behavior is "all addresses" this will force localhost only when no address is provided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants