vi / websocat

Command-line client for WebSockets, like netcat (or curl) for ws:// with advanced socat-like functions
MIT License
7.01k stars 272 forks source link

websocat not working for IPv6 address #118

Open Pioter44 opened 3 years ago

Pioter44 commented 3 years ago

Hi,

I want to use websocat to ping WS Server on IPv6 address.

I've checked websocat and it is working fine (ping) for IPv4 and also for localhost IPv6 ( [::1] ) If I will specify normal IPv6 address (for example ws://[fe80::a394:39d0:768f:6538]:7688) then I'm getting error: WebSocketError: I/O failure Is anyone has got similar issue?

Below are detailed logs from websocat (strace)

user@user-VirtualBox:~$ user@user-VirtualBox:~$ websocat --binary ws://[fe80::a394:39d0:768f:6538]:7688 --ping-interval 3 websocat: WebSocketError: I/O failure websocat: error running user@user-VirtualBox:~$ user@user-VirtualBox:~$ strace -e trace=network -s 4096 websocat ws://localhost:7688 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 6 connect(6, {???????sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}???????, 110) = -1 ENOENT (No such file or directory) socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 6 connect(6, {???????sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}???????, 110) = -1 ENOENT (No such file or directory) socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 6 connect(6, {???????sa_family=AF_INET, sin_port=htons(7688), sin_addr=inet_addr("127.0.0.1")}???????, 16) = -1 EINPROGRESS (Operation now in progress) getsockopt(6, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 sendto(6, "GET / HTTP/1.1\r\nHost: localhost:7688\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: W8mGOKmyYr0oPH+h/xj+Ow==\r\n\r\n", 153, MSG_NOSIGNAL, NULL, 0) = 153 recvfrom(6, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: njTrLjXHXUecPB5bn+1sj+pu/7s=\r\n\r\n", 8192, 0, NULL, NULL) = 129 recvfrom(6, 0x55bfabd8fb11, 8063, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)

sendto(6, "\201\201\375n\312\26\367", 7, MSG_NOSIGNAL, NULL, 0) = 7 recvfrom(6, "\201\1\n", 8063, 0, NULL, NULL) = 3

recvfrom(6, 0x55bfabd8fb14, 8060, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)

sendto(6, "\201\201a\273;\303k", 7, MSG_NOSIGNAL, NULL, 0) = 7 recvfrom(6, "\201\1\n", 8060, 0, NULL, NULL) = 3

recvfrom(6, 0x55bfabd8fb17, 8057, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) www sendto(6, "\201\204\205\30\2463\362o\3219", 10, MSG_NOSIGNAL, NULL, 0) = 10 recvfrom(6, "\201\4www\n", 8057, 0, NULL, NULL) = 6 www recvfrom(6, 0x55bfabd8fb1d, 8051, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) ^Cstrace: Process 5158 detached

user@user-VirtualBox:~$ user@user-VirtualBox:~$ user@user-VirtualBox:~$ strace -e trace=network -s 4096 websocat ws://[::1]:7688socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 6 connect(6, {???????sa_family=AF_INET6, sin6_port=htons(7688), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_scope_id=0}???????, 28) = -1 EINPROGRESS (Operation now in progress) getsockopt(6, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 sendto(6, "GET / HTTP/1.1\r\nHost: [::1]:7688\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: auCpxb+lYL5AnUREvBysUw==\r\n\r\n", 149, MSG_NOSIGNAL, NULL, 0) = 149 recvfrom(6, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: 2dVwwWixrWzNLaxJTB1GUeLRih0=\r\n\r\n", 8192, 0, NULL, NULL) = 129 recvfrom(6, 0x561fca8d3bf1, 8063, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) sacid sendto(6, "\201\206\317\202\237|\274\343\374\25\253\210", 12, MSG_NOSIGNAL, NULL, 0) = 12 recvfrom(6, "\201\6sacid\n", 8063, 0, NULL, NULL) = 8 recvfrom(6, 0x561fca8d3bf9, 8055, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) sacid

sendto(6, "\201\201\344\20\306\277\356", 7, MSG_NOSIGNAL, NULL, 0) = 7 recvfrom(6, "\201\1\n", 8055, 0, NULL, NULL) = 3 recvfrom(6, 0x561fca8d3bfc, 8052, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)

piotr sendto(6, "\201\206\213\32D\\373s+(\371\20", 12, MSG_NOSIGNAL, NULL, 0) = 12 recvfrom(6, "\201\6piotr\n", 8052, 0, NULL, NULL) = 8 recvfrom(6, 0x561fca8d3c04, 8044, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) piotr

sendto(6, "\201\201\0324\203.\20", 7, MSG_NOSIGNAL, NULL, 0) = 7 recvfrom(6, "\201\1\n", 8044, 0, NULL, NULL) = 3 recvfrom(6, 0x561fca8d3c07, 8041, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)

^Cstrace: Process 5164 detached

user@user-VirtualBox:~$ user@user-VirtualBox:~$ user@user-VirtualBox:~$ strace -e trace=network -s 4096 websocat ws://[fe80::a394:39d0:768f:6538]:7688 socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 6 connect(6, {???????sa_family=AF_INET6, sin6_port=htons(7688), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "fe80::a394:39d0:768f:6538", &sin6_addr), sin6_scope_id=0}???????, 28) = -1 EINVAL (Invalid argument) websocat: WebSocketError: I/O failure websocat: error running +++ exited with 1 +++ user@user-VirtualBox:~$ user@user-VirtualBox:~$ user@user-VirtualBox:~$ ping fe80::a394:39d0:768f:6538 PING fe80::a394:39d0:768f:6538(fe80::a394:39d0:768f:6538) 56 data bytes ping: sendmsg: Invalid argument ping: sendmsg: Invalid argument ping: sendmsg: Invalid argument ping: sendmsg: Invalid argument ^C --- fe80::a394:39d0:768f:6538 ping statistics --- 4 packets transmitted, 0 received, 100% packet loss, time 3053ms

user@user-VirtualBox:~$ ifconfig enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255 inet6 fe80::a394:39d0:768f:6538 prefixlen 64 scopeid 0x20 ether 08:00:27:b2:93:d4 txqueuelen 1000 (Ethernet) RX packets 47186 bytes 61226178 (61.2 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 6458 bytes 427339 (427.3 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 864 bytes 78371 (78.3 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 864 bytes 78371 (78.3 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

image

Thanks, Piotr

vi commented 3 years ago

fe80

Unfortunately, Link-local IPv6 is problematic in Rust. Also you have not specified the address scope (special additional part of specifically fe80:* sort of addresses):

$ strace -fe trace=network /opt/websocat --binary ws://[fe80::a394:39d0:768f:6538]:7688 --ping-interval 3
...
[pid 15363] connect(6, {sa_family=AF_INET6, sin6_port=htons(7688), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "fe80::a394:39d0:768f:6538", &sin6_addr), sin6_scope_id=0}, 28) = -1 EINVAL (Invalid argument)

IPv6 linklocal link scopes in URL is poorly supported setup in general. Maybe assign some other (e.g. site-local or global) IPv6 address instead?

Workaround: use some external program to handle the TCPv6 part:

websocat --binary  --ping-interval=3  -  ws-c:cmd:'nc fe80::a394:39d0:768f:6538%lo 80'
vi commented 3 years ago

Localhost IPv6 works well in Websocat: websocat ws://[::1]:1234/ connects to websocat -s [::]:1234.