Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for abstract namespaces in Unix domain sockets #77931

Closed
cataggar opened this issue Nov 4, 2022 · 10 comments
Closed

add support for abstract namespaces in Unix domain sockets #77931

cataggar opened this issue Nov 4, 2022 · 10 comments

Comments

@cataggar
Copy link

cataggar commented Nov 4, 2022

It would be wonderful if support for abstract namespaces in Unix domain sockets was added.

Tracking Issue for abstract namespaces in Unix domain sockets #85410
Traditionally, Unix domain sockets (UDS) use a file to coordinate socket binding and connecting. On Linux, though, a specific extension exists to allow domain sockets to be created from a namespace which does not use the filesystem.
rust-lang/rust#85410

Support for "Linux abstract socket namespace" has been in Python since version 2.5 2006.
https://stackoverflow.com/a/27073584/23059

This is something that may benefit several WSL scenarios.
https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
https://devblogs.microsoft.com/commandline/windowswsl-interop-with-af_unix/

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Nov 5, 2022
@ghost
Copy link

ghost commented Nov 5, 2022

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

It would be wonderful if support for abstract namespaces in Unix domain sockets was added.

Tracking Issue for abstract namespaces in Unix domain sockets #85410
Traditionally, Unix domain sockets (UDS) use a file to coordinate socket binding and connecting. On Linux, though, a specific extension exists to allow domain sockets to be created from a namespace which does not use the filesystem.
rust-lang/rust#85410

Support for "Linux abstract socket namespace" has been in Python since version 2.5 2006.
https://stackoverflow.com/a/27073584/23059

This is something that may benefit several WSL scenarios.
https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
https://devblogs.microsoft.com/commandline/windowswsl-interop-with-af_unix/

Author: cataggar
Assignees: -
Labels:

area-System.Net.Sockets

Milestone: -

@cataggar
Copy link
Author

cataggar commented Nov 5, 2022

In my current use case, I was able to start mdsd (Geneva Logs) on WSL2 only when using its -u flag which "Use abstract domain sockets instead of file system paths". You can see that they are not on the filesystem, but the names are seen when using netstat -a:

cataggar@DESKTOP-VTIN789:/mnt/c/Users/cataggar/geneva$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 localhost:29130         0.0.0.0:*               LISTEN
tcp        0      0 localhost:29230         0.0.0.0:*               LISTEN
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  2      [ ACC ]     STREAM     LISTENING     31834    @/home/cataggar/mdsd_fluent.socket@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
unix  2      [ ACC ]     SEQPACKET  LISTENING     18539    /run/WSL/8_interop
unix  2      [ ACC ]     SEQPACKET  LISTENING     19475    /run/WSL/309_interop
unix  2      [ ACC ]     STREAM     LISTENING     31829    @/home/cataggar/mdsd_bond.socket@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
unix  2      [ ACC ]     SEQPACKET  LISTENING     20006    /run/WSL/2677_interop
unix  2      [ ]         DGRAM                    31836    @/home/cataggar/mdsd_syslog.socket@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
unix  2      [ ACC ]     STREAM     LISTENING     31830    @/home/cataggar/mdsd_djson.socket@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
unix  2      [ ACC ]     STREAM     LISTENING     31835    @/home/cataggar/mdsd_influx.socket@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
unix  2      [ ACC ]     STREAM     LISTENING     31831    @/home/cataggar/mdsd_json.socket@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
cataggar@DESKTOP-VTIN789:/mnt/c/Users/cataggar/geneva$ ls /home/cataggar
mdsd.lock  mdsd.pidport  vsdbg

Unfortunately, I can't connect to it using the GenevaExporter.

cataggar@DESKTOP-VTIN789:/mnt/c/Users/cataggar/geneva$ dotnet run
Unhandled exception. System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (99): Cannot assign requested address /home/cataggar/mdsd_fluent.socket
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at OpenTelemetry.Exporter.Geneva.UnixDomainSocketDataTransport.Connect()
   at OpenTelemetry.Exporter.Geneva.GenevaLogExporter..ctor(GenevaExporterOptions options)
   at Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(OpenTelemetryLoggerOptions options, Action`1 configure)
   at Program.<>c.<<Main>$>b__0_2(OpenTelemetryLoggerOptions openTelemetryLogger) in /mnt/c/Users/cataggar/geneva/Program.cs:line 9

Program.cs

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

using IHost host = Host.CreateDefaultBuilder(args)
 .ConfigureLogging(logging =>
     logging.AddOpenTelemetry(openTelemetryLogger=>
     {
         openTelemetryLogger.AddGenevaLogExporter(genevaExporter =>
         {
             genevaExporter.ConnectionString = "Endpoint=unix:/home/cataggar/mdsd_fluent.socket";
         });
     })
 )
 .ConfigureServices((_, services) =>
     services.AddHostedService<Worker>()
  )
 .Build();

await host.RunAsync();

internal class Worker : IHostedService
{
 ILogger log;
 public Worker(ILogger<Worker> log)
 {
     this.log = log;
 }

 public Task StartAsync(CancellationToken cancellationToken)
 {
     log.LogInformation("start");
     return Task.CompletedTask;
 }

 public Task StopAsync(CancellationToken cancellationToken)
 {
     log.LogInformation("stop");
     return Task.CompletedTask;
 }
}

csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
    <!-- The releases in August allows setting the TraceFlags, but avoids updating System.Diagnostics.DiagnosticSource -->
    <!-- https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/CHANGELOG.md -->
    <PackageReference Include="OpenTelemetry.Api" Version="1.4.0-alpha.1" />
    <PackageReference Include="OpenTelemetry.Exporter.Geneva" Version="1.3.0" />
    <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.0.0-rc9.5" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.0.0-rc9.5" />
  </ItemGroup>
</Project>

@stephentoub
Copy link
Member

stephentoub commented Nov 5, 2022

It would be wonderful if support for abstract namespaces in Unix domain sockets was added.

They're already supported on Linux and have been for years. Can you elaborate on what doesn't work? Paths that begin with null '\0' are abstract, e.g.

public void UnixDomainSocketEndPoint_RemoteEndPointEqualsBindAddress(bool abstractAddress)
{
string serverAddress;
string clientAddress;
string expectedClientAddress;
if (abstractAddress)
{
// abstract socket addresses are a Linux feature.
if (!OperatingSystem.IsLinux())
{
return;
}
// An abstract socket address starts with a zero byte.
serverAddress = '\0' + Guid.NewGuid().ToString();
clientAddress = '\0' + Guid.NewGuid().ToString();
expectedClientAddress = '@' + clientAddress.Substring(1);

@fbrosseau
Copy link

fbrosseau commented Nov 5, 2022

This is something that may benefit several WSL scenarios.

Unix sockets were supported as an interoperability bridge between Linux and Windows under WSL1. Unless things changed recently, they killed them in WSL2. Using WSL1 today is very niche (and I would not be surprised if they kill it altogether at some point).

Of course they do work in WSL2, but not as Windows<->Linux interopability anymore. Just local to Linux, as in any Linux system.

For portable zero-conf networking today (ie, avoiding TCP for some reason), the preferred method would be AF_HYPERV+AF_VSOCK.

@rzikm rzikm added os-linux Linux OS (any supported distro) and removed os-linux Linux OS (any supported distro) labels Nov 7, 2022
@wfurt
Copy link
Member

wfurt commented Nov 7, 2022

I think this is because for isolation win WSL2 -> I'm not sure we can cross the OS boundaries inside of .NET.
Adding better support for the "virtual" families may be way to go.

@antonfirsov
Copy link
Member

We have #58378 to track AF_HYPERV+AF_VSOCK.
Otherwise, this looks like a WSL issue. Or is there anything else the .NET runtime/BCL could improve here @cataggar?

@antonfirsov antonfirsov added the needs-author-action An issue or pull request that requires more info or actions from the author. label Nov 7, 2022
@ghost
Copy link

ghost commented Nov 7, 2022

This issue has been marked needs-author-action and may be missing some important information.

@cataggar
Copy link
Author

cataggar commented Nov 7, 2022

It is not a WSL issue. Forget that I mentioned WSL at all. Can support be added for Linux abstract namespaces in Unix domain sockets?

@ghost ghost added needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration and removed needs-author-action An issue or pull request that requires more info or actions from the author. labels Nov 7, 2022
@stephentoub
Copy link
Member

@cataggar, as I noted in #77931 (comment), UnixDomainSocketEndPoint in .NET already supports abstract addresses. What specifically isn't working?

@cataggar
Copy link
Author

cataggar commented Nov 7, 2022

Thanks for pointing that out again, @stephentoub. Closing this.

@cataggar cataggar closed this as completed Nov 7, 2022
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Nov 7, 2022
@karelz karelz removed the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Nov 14, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Dec 14, 2022
@karelz karelz added this to the 8.0.0 milestone Mar 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants