parent
920de86cee
commit
1555d38617
|
@ -9,6 +9,7 @@ package tsnet
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
crand "crypto/rand"
|
crand "crypto/rand"
|
||||||
|
"crypto/tls"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -645,7 +646,7 @@ func networkForFamily(netBase string, is6 bool) string {
|
||||||
// - ("tcp", "", port)
|
// - ("tcp", "", port)
|
||||||
//
|
//
|
||||||
// The netBase is "tcp" or "udp" (without any '4' or '6' suffix).
|
// The netBase is "tcp" or "udp" (without any '4' or '6' suffix).
|
||||||
func (s *Server) listenerForDstAddr(netBase string, dst netip.AddrPort) (_ *listener, ok bool) {
|
func (s *Server) listenerForDstAddr(netBase string, dst netip.AddrPort, funnel bool) (_ *listener, ok bool) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
for _, a := range [2]netip.Addr{0: dst.Addr()} {
|
for _, a := range [2]netip.Addr{0: dst.Addr()} {
|
||||||
|
@ -653,7 +654,7 @@ func (s *Server) listenerForDstAddr(netBase string, dst netip.AddrPort) (_ *list
|
||||||
networkForFamily(netBase, dst.Addr().Is6()),
|
networkForFamily(netBase, dst.Addr().Is6()),
|
||||||
netBase,
|
netBase,
|
||||||
} {
|
} {
|
||||||
if ln, ok := s.listeners[listenKey{net, a, dst.Port()}]; ok {
|
if ln, ok := s.listeners[listenKey{net, a, dst.Port(), funnel}]; ok {
|
||||||
return ln, true
|
return ln, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -675,7 +676,7 @@ func (s *Server) getTCPHandlerForFunnelFlow(src netip.AddrPort, dstPort uint16)
|
||||||
}
|
}
|
||||||
dst = netip.AddrPortFrom(ipv6, dstPort)
|
dst = netip.AddrPortFrom(ipv6, dstPort)
|
||||||
}
|
}
|
||||||
ln, ok := s.listenerForDstAddr("tcp", dst)
|
ln, ok := s.listenerForDstAddr("tcp", dst, true)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -683,7 +684,7 @@ func (s *Server) getTCPHandlerForFunnelFlow(src netip.AddrPort, dstPort uint16)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getTCPHandlerForFlow(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool) {
|
func (s *Server) getTCPHandlerForFlow(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool) {
|
||||||
ln, ok := s.listenerForDstAddr("tcp", dst)
|
ln, ok := s.listenerForDstAddr("tcp", dst, false)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, true // don't handle, don't forward to localhost
|
return nil, true // don't handle, don't forward to localhost
|
||||||
}
|
}
|
||||||
|
@ -691,7 +692,7 @@ func (s *Server) getTCPHandlerForFlow(src, dst netip.AddrPort) (handler func(net
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getUDPHandlerForFlow(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
|
func (s *Server) getUDPHandlerForFlow(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
|
||||||
ln, ok := s.listenerForDstAddr("udp", dst)
|
ln, ok := s.listenerForDstAddr("udp", dst, false)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, true // don't handle, don't forward to localhost
|
return nil, true // don't handle, don't forward to localhost
|
||||||
}
|
}
|
||||||
|
@ -760,6 +761,34 @@ func (s *Server) APIClient() (*tailscale.Client, error) {
|
||||||
// Listen announces only on the Tailscale network.
|
// Listen announces only on the Tailscale network.
|
||||||
// It will start the server if it has not been started yet.
|
// It will start the server if it has not been started yet.
|
||||||
func (s *Server) Listen(network, addr string) (net.Listener, error) {
|
func (s *Server) Listen(network, addr string) (net.Listener, error) {
|
||||||
|
return s.listen(network, addr, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) ListenFunnel(network string, addr string) (net.Listener, error) {
|
||||||
|
if network != "tcp" {
|
||||||
|
return nil, errors.New("only tcp is supported for ListenFunnel")
|
||||||
|
}
|
||||||
|
lc, err := s.LocalClient() // do local client first before listening.
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
st, err := lc.StatusWithoutPeers(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(st.CertDomains) == 0 {
|
||||||
|
return nil, errors.New("please enable HTTPS in the Tailscale admin panel")
|
||||||
|
}
|
||||||
|
ln, err := s.listen(network, addr, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tls.NewListener(ln, &tls.Config{
|
||||||
|
GetCertificate: lc.GetCertificate,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) listen(network, addr string, funnel bool) (net.Listener, error) {
|
||||||
switch network {
|
switch network {
|
||||||
case "", "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
|
case "", "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
|
||||||
default:
|
default:
|
||||||
|
@ -794,7 +823,7 @@ func (s *Server) Listen(network, addr string) (net.Listener, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
key := listenKey{network, bindHostOrZero, uint16(port)}
|
key := listenKey{network, bindHostOrZero, uint16(port), funnel}
|
||||||
ln := &listener{
|
ln := &listener{
|
||||||
s: s,
|
s: s,
|
||||||
key: key,
|
key: key,
|
||||||
|
@ -816,6 +845,7 @@ type listenKey struct {
|
||||||
network string
|
network string
|
||||||
host netip.Addr // or zero value for unspecified
|
host netip.Addr // or zero value for unspecified
|
||||||
port uint16
|
port uint16
|
||||||
|
funnel bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type listener struct {
|
type listener struct {
|
||||||
|
|
Loading…
Reference in New Issue