Search code examples
perlsocketsdebianwindows-subsystem-for-linux

WSL2 Debian socket Operation not supported


Im trying to open a socket from Perl on Debian in WSL2 and it gives me an operation not supported, whereas it is fine on Debian in a VMWare VM.

Diagnostics from my application are as follows:

On Debian on 5.15.79.1-microsoft-standard-WSL2 #1 SMP Wed Nov 23 01:01:46 UTC 2022 x86_64 it does this:

init_sockets...
  127.0.0.1:9996 => TH::accept_ftp_dat_session
  [::1]:9996 => TH::accept_ftp_dat_session
  127.0.0.1:4203 => TH::accept_ftp_cmd_session
  [::1]:4203 => TH::accept_ftp_cmd_session
  127.0.0.1:4200 => TH::accept_telnet_session
  [::1]:4200 => TH::accept_telnet_session
  127.0.0.1:4201 => TH::accept_telnet_session
  [::1]:4201 => TH::accept_telnet_session
  127.0.0.1:7979 => TH::accept_finger_session
  [::1]:7979 => TH::accept_finger_session
  127.0.0.1:4202 => TH::accept_telnet_session
  [::1]:4202 => TH::accept_telnet_session
  www-data/http.socket => TH::accept_http_session
Operation not supported at ./src/th_networking.pm line 1033.

On Debian 5.10.149-2 (2022-10-21) x86_64 on VM it does this:

init_sockets...
  127.0.0.1:4200 => TH::accept_telnet_session
  [::1]:4200 => TH::accept_telnet_session
  127.0.0.1:9996 => TH::accept_ftp_dat_session
  [::1]:9996 => TH::accept_ftp_dat_session
  127.0.0.1:4203 => TH::accept_ftp_cmd_session
  [::1]:4203 => TH::accept_ftp_cmd_session
  127.0.0.1:7979 => TH::accept_finger_session
  [::1]:7979 => TH::accept_finger_session
  127.0.0.1:4201 => TH::accept_telnet_session
  [::1]:4201 => TH::accept_telnet_session
  127.0.0.1:4202 => TH::accept_telnet_session
  [::1]:4202 => TH::accept_telnet_session
  www-data/http.socket => TH::accept_http_session
  proxied.socket => TH::accept_proxied_session

The relevant code is:

sub init_socket
{
    my ( $sockaddr ) = @_;

    my $family = sockaddr_family($sockaddr);
    my $socket;

    if ( $family == &AF_UNIX )
    {
        socket $socket, $family, &SOCK_STREAM, &IPPROTO_IP or die $!;
    }
    else
    {
        socket $socket, $family, &SOCK_STREAM, &IPPROTO_TCP or die $!;
        setsockopt $socket, &SOL_SOCKET, &SO_REUSEADDR, 1 or die $!;
        setsockopt $socket, &SOL_SOCKET, &SO_LINGER, pack( 'ii', 1, 0 ) or die $!;
        setsockopt $socket, &IPPROTO_IPV6, &IPV6_V6ONLY, 1 or die $! if $family == &AF_INET6;
    }

    fcntl $socket, &F_SETFL, &O_NONBLOCK or die $!;
    bind $socket, $sockaddr or die $!;
    listen $socket, 5 or die $!;

    return $socket;
}

It fails at the bind $socket, $sockaddr or die $!; line above.

I have tried WSL1 and WSL2 because I read WSL2 doesnt support AF, but that just gives a different error. Anyone can give me a clue on what to do?


Solution

  • Under WSL2 you may find your home or working directory mapped to something like /mnt/c/Users/username, which is a Windows filesystem not a linux filesystem. Windows filesystems dont support AF_UNIX sockets and consequently if you try to create one it fails.

    The solution is to move you working development directory in to the linux filesystem, such as under /home. After doing the you can create AF_UNIX sockets. However, this fs is not mappable to Windows and so cant directly be accessed by Windows hosted IDEs such as VSCode which renders the whole WSL2 as a dev environment for this kind of thing a bit useless.