Skip to content

Commit fe043b9

Browse files
committed
Portmapping: add windowsAddress support
1 parent aeaf1f2 commit fe043b9

1 file changed

Lines changed: 98 additions & 13 deletions

File tree

src/windows/WslcSDK/wslcsdk.cpp

Lines changed: 98 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -594,24 +594,105 @@ CATCH_RETURN();
594594
STDAPI WslcStartContainer(_In_ WslcContainer container, _In_ WslcContainerStartFlags flags, _Outptr_opt_result_z_ PWSTR* errorMessage)
595595
try
596596
{
597+
RETURN_HR_IF_NULL(E_POINTER, container);
598+
*container = nullptr;
597599
ErrorInfoWrapper errorInfoWrapper{errorMessage};
598-
auto internalType = CheckAndGetInternalType(container);
599-
RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), internalType->container);
600+
auto internalSession = CheckAndGetInternalType(session);
601+
RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), internalSession->session);
602+
auto internalContainerSettings = CheckAndGetInternalType(containerSettings);
603+
604+
auto result = std::make_unique<WslcContainerImpl>();
605+
606+
WSLCContainerOptions containerOptions{};
607+
containerOptions.Image = internalContainerSettings->image;
608+
containerOptions.Name = internalContainerSettings->runtimeName;
609+
containerOptions.HostName = internalContainerSettings->HostName;
610+
containerOptions.DomainName = internalContainerSettings->DomainName;
611+
containerOptions.Flags = ConvertFlags(internalContainerSettings->containerFlags);
612+
613+
CopyProcessSettingsToRuntime(containerOptions.InitProcessOptions, internalContainerSettings->initProcessOptions);
614+
615+
std::unique_ptr<WSLCVolume[]> convertedVolumes;
616+
if (internalContainerSettings->volumes && internalContainerSettings->volumesCount)
617+
{
618+
convertedVolumes = std::make_unique<WSLCVolume[]>(internalContainerSettings->volumesCount);
619+
for (uint32_t i = 0; i < internalContainerSettings->volumesCount; ++i)
620+
{
621+
const WslcContainerVolume& internalVolume = internalContainerSettings->volumes[i];
622+
WSLCVolume& convertedVolume = convertedVolumes[i];
623+
624+
convertedVolume.HostPath = internalVolume.windowsPath;
625+
convertedVolume.ContainerPath = internalVolume.containerPath;
626+
convertedVolume.ReadOnly = internalVolume.readOnly;
627+
}
628+
containerOptions.Volumes = convertedVolumes.get();
629+
containerOptions.VolumesCount = static_cast<ULONG>(internalContainerSettings->volumesCount);
630+
}
631+
632+
std::unique_ptr<WSLCPortMapping[]> convertedPorts;
633+
std::vector<std::string> bindingAddressStrings;
634+
if (internalContainerSettings->ports && internalContainerSettings->portsCount)
635+
{
636+
convertedPorts = std::make_unique<WSLCPortMapping[]>(internalContainerSettings->portsCount);
637+
bindingAddressStrings.resize(internalContainerSettings->portsCount);
638+
for (uint32_t i = 0; i < internalContainerSettings->portsCount; ++i)
639+
{
640+
const WslcContainerPortMapping& internalPort = internalContainerSettings->ports[i];
641+
WSLCPortMapping& convertedPort = convertedPorts[i];
642+
643+
convertedPort.HostPort = internalPort.windowsPort;
644+
convertedPort.ContainerPort = internalPort.containerPort;
645+
646+
// TODO: Consider using standard protocol numbers instead of our own enum.
647+
convertedPort.Protocol = internalPort.protocol == WSLC_PORT_PROTOCOL_TCP ? IPPROTO_TCP : IPPROTO_UDP;
648+
649+
if (internalPort.windowsAddress != nullptr)
650+
{
651+
char addrBuf[INET6_ADDRSTRLEN]{};
652+
if (internalPort.windowsAddress->ss_family == AF_INET)
653+
{
654+
const auto* addr4 = reinterpret_cast<const sockaddr_in*>(internalPort.windowsAddress);
655+
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET, &addr4->sin_addr, addrBuf, sizeof(addrBuf)));
656+
convertedPort.Family = AF_INET;
657+
}
658+
else
659+
{
660+
const auto* addr6 = reinterpret_cast<const sockaddr_in6*>(internalPort.windowsAddress);
661+
THROW_HR_IF_NULL(E_UNEXPECTED, inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, sizeof(addrBuf)));
662+
convertedPort.Family = AF_INET6;
663+
}
664+
bindingAddressStrings[i] = addrBuf;
665+
convertedPort.BindingAddress = bindingAddressStrings[i].c_str();
666+
}
667+
else
668+
{
669+
convertedPort.Family = AF_INET;
670+
convertedPort.BindingAddress = "127.0.0.1";
671+
}
672+
}
673+
containerOptions.Ports = convertedPorts.get();
674+
containerOptions.PortsCount = static_cast<ULONG>(internalContainerSettings->portsCount);
675+
}
600676

601-
bool hasIOCallback = IOCallback::HasIOCallback(internalType->ioCallbackOptions);
602-
// If callbacks were provided, ATTACH must be used.
603-
// TODO: Consider if we should just override flags when callbacks were provided instead.
604-
RETURN_HR_IF(E_INVALIDARG, WI_IsFlagClear(flags, WSLC_CONTAINER_START_FLAG_ATTACH) && hasIOCallback);
677+
containerOptions.ContainerNetwork.ContainerNetworkType = internalContainerSettings->networking;
678+
679+
// TODO: No user access
680+
// containerOptions.Entrypoint;
681+
// containerOptions.Labels;
682+
// containerOptions.LabelsCount;
683+
// containerOptions.StopSignal;
684+
// containerOptions.ShmSize;
605685

606-
if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalType->container->Start(ConvertFlags(flags), nullptr))))
686+
if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalSession->session->CreateContainer(&containerOptions, &result->container))))
607687
{
608-
if (hasIOCallback)
688+
wsl::windows::common::security::ConfigureForCOMImpersonation(result->container.get());
689+
690+
if (IOCallback::HasIOCallback(internalContainerSettings->initProcessOptions))
609691
{
610-
wil::com_ptr<IWSLCProcess> process;
611-
RETURN_IF_FAILED(internalType->container->GetInitProcess(&process));
612-
wsl::windows::common::security::ConfigureForCOMImpersonation(process.get());
613-
internalType->ioCallbacks = std::make_shared<IOCallback>(process.get(), internalType->ioCallbackOptions);
692+
result->ioCallbackOptions = internalContainerSettings->initProcessOptions->ioCallbacks;
614693
}
694+
695+
*container = reinterpret_cast<WslcContainer>(result.release());
615696
}
616697

617698
return errorInfoWrapper;
@@ -693,7 +774,11 @@ try
693774

694775
for (uint32_t i = 0; i < portMappingCount; ++i)
695776
{
696-
RETURN_HR_IF(E_NOTIMPL, portMappings[i].windowsAddress != nullptr);
777+
if (portMappings[i].windowsAddress != nullptr)
778+
{
779+
const auto family = portMappings[i].windowsAddress->ss_family;
780+
RETURN_HR_IF(E_INVALIDARG, family != AF_INET && family != AF_INET6);
781+
}
697782
RETURN_HR_IF(E_NOTIMPL, portMappings[i].protocol != 0);
698783
}
699784

0 commit comments

Comments
 (0)