websocat icon indicating copy to clipboard operation
websocat copied to clipboard

When is websocat actually listening?

Open gerdstolpmann opened this issue 3 years ago • 5 comments

When you use websocat in programmatic context, it would be useful to be able to be notified when the listening socket is actually ready and accepting connections, so that the using process can start connecting. Currently, you don't know, and the only thing you can do is to wait for a little while (milliseconds) and then hope that everything is ready.

E.g. there could be an option --notify-listening and this outputs a line for each listening socket on stderr, like

$ websocat --notify-listening tcp-l:127.0.0.1:8000 ws://host
LISTEN tcp-listen:127.0.0.1:8000

This would also open the door to an additional little feature:

$ websocat --notify-listening tcp-l:127.0.0.1:0 ws://host
LISTEN tcp-listen:127.0.0.1:65345

gerdstolpmann avatar Jul 08 '21 19:07 gerdstolpmann

Indeed, there is currently no reliable message (even with increased verbosity) that happens after the listen(2) syscall.

I can implement this (and provide a prebuilt executable if needed).

As a workaround you can also move socket + listen away from Websocat by using --accept-from-fd option (like for integrating with systemd)

websocat --accept-from-fd -b -E ws-u:unix-listen:55 literal:$'Hello, world\n' 55<> something

vi avatar Jul 08 '21 20:07 vi

LISTEN tcp-listen:127.0.0.1:65345

Can you turn it into more a proper spec (or is there already some precedent for such lines)? How that would look for UDP sockets (including multicast), UNIX sockets (including Linux's abstract namespace)? Would it be just the square brackets for IPv6 (including link-local addresses with scope ids)?

vi avatar Jul 08 '21 20:07 vi

I don't have a spec - this is just an idea I had when writing the first issue. For me it would only be important that it can be easily parsed, i.e. split into words, and then run a regexp to check the details. In most cases you would just watch out for the presence of the LISTEN line.

Could also be something like LISTEN proto=tcp,ip=127.0.0.1,port=65345 (maybe the pcap format defines a number of these fields?)

gerdstolpmann avatar Jul 08 '21 20:07 gerdstolpmann

Implemented.

You haven't specified your preferred platform, so I built a static version for Linux: https://github.com/vi/websocat/releases/download/v1.8.0/websocat_announcelisten

$ strace -fe trace=network websocat_announcelisten --stdout-announce-listening-ports -s 1234
Listening on ws://127.0.0.1:1234/
socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 6
setsockopt(6, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(6, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
listen(6, 1024)                         = 0
LISTEN proto=tcp,ip=127.0.0.1,port=1234

vi avatar Jul 08 '21 20:07 vi

wow, that's quick... I'll give it a try tomorrow

gerdstolpmann avatar Jul 08 '21 21:07 gerdstolpmann