tailscale / tailscale/tailcat

Add UDP support to serve and forward

Open
#122 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
7.5k
Forks
311
Avg merge
7h 7m
Merged PRs (30d)
59

Description

I wanted to run mosh through tailcat (over a DERP-relayed connection the typing lag is noticeable, and mosh's local echo fixes that), and found there's no way to get UDP to a served port from the CLI. The library has it all (Server.OnUDP, ServedUDPPorts, Client.DialUDPPort, ProxyPacketConns), and d0d599161 wired it up for exit nodes, but serve <ports> only ever sets OnTCP, and forward only listens on TCP. socks can dial UDP but mosh-client doesn't speak SOCKS.

Proposal:

tailcat serve --udp=60000-60010 no-auth-ssh      # proxy those UDP ports to loopback
tailcat forward <tc-addr> udp:60001              # local udp 60001 -> server udp 60001
tailcat forward <tc-addr> udp:16001:60001

Server side is tiny. It gates on the port set and calls the existing udpForwardTo, plus sets ServedUDPPorts. Client side is a UDP listener that opens one DialUDPPort flow per local source address and reaps idle ones. I have this working and can send a PR, but there are two things I'd want your call on first.

  • tailcat serve --udp=60000-60010 22,no-auth-ssh vs tailcat serve 22,udp:60000-60010,no-auth-ssh. The flag is less code. The inline form matches the udp: prefix on the client side.
  • Which loopback to proxy to. TCP dials localhost via localhostdns and falls back between 127.0.0.1 and ::1, but UDP can't fall back. The dial "succeeds" against whichever is first (Go picks ::1) and packets to a listener on the other one just vanish. I defaulted to 127.0.0.1 with a --udp-host override.

One thing to know for mosh specifically is that it only works over ::1. mosh sizes packets by address family, 1252 bytes over IPv4, which is over MaxUDPPayload (1232) and gets dropped, vs 1216 over IPv6, which fits. Keystrokes are small so an IPv4 setup looks like it works until the first big screen redraw stalls it. With mosh-server -i ::1, mosh-client ::1, and --udp-host=::1 it's fine.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the existing serve and forward CLI paths, then read Server.OnUDP, ServedUDPPorts, Client.DialUDPPort, ProxyPacketConns, and udpForwardTo. Confirm the command syntax and loopback choice before implementing; done means the proposed UDP serve and forward forms proxy traffic, including the IPv6 mosh case.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli, networking
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.