mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-23 09:06:24 +00:00
support proxying to real DERPs, for testing
Change-Id: I27da972ed6c37188b2de17e3d9287410eace73e4 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -11,6 +12,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ import (
|
|||||||
"gvisor.dev/gvisor/pkg/waiter"
|
"gvisor.dev/gvisor/pkg/waiter"
|
||||||
"tailscale.com/net/stun"
|
"tailscale.com/net/stun"
|
||||||
"tailscale.com/syncs"
|
"tailscale.com/syncs"
|
||||||
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/util/set"
|
"tailscale.com/util/set"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,6 +56,10 @@ func main() {
|
|||||||
log.Fatalf("newServer: %v", err)
|
log.Fatalf("newServer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := s.populateDERPMapIPs(); err != nil {
|
||||||
|
log.Printf("warning: ignoring failure to populate DERP map: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Hard-coded world shape for me.
|
// Hard-coded world shape for me.
|
||||||
net1 := &network{
|
net1 := &network{
|
||||||
s: s,
|
s: s,
|
||||||
@@ -78,6 +85,25 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) populateDERPMapIPs() error {
|
||||||
|
out, err := exec.Command("tailscale", "debug", "derp-map").Output()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tailscale debug derp-map: %v", err)
|
||||||
|
}
|
||||||
|
var dm tailcfg.DERPMap
|
||||||
|
if err := json.Unmarshal(out, &dm); err != nil {
|
||||||
|
return fmt.Errorf("unmarshal DERPMap: %v", err)
|
||||||
|
}
|
||||||
|
for _, r := range dm.Regions {
|
||||||
|
for _, n := range r.Nodes {
|
||||||
|
if n.IPv4 != "" {
|
||||||
|
s.derpIPs.Add(netip.MustParseAddr(n.IPv4))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) registerNetwork(n *network) error {
|
func (s *Server) registerNetwork(n *network) error {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return errors.New("nil network")
|
return errors.New("nil network")
|
||||||
@@ -293,8 +319,14 @@ func (n *network) acceptTCP(r *tcp.ForwarderRequest) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if destIP == fakeControlplaneIP {
|
var targetDial string
|
||||||
c, err := net.Dial("tcp", "controlplane.tailscale.com:"+strconv.Itoa(int(reqDetails.LocalPort)))
|
if n.s.derpIPs.Contains(destIP) {
|
||||||
|
targetDial = destIP.String() + ":" + strconv.Itoa(int(reqDetails.LocalPort))
|
||||||
|
} else if destIP == fakeControlplaneIP {
|
||||||
|
targetDial = "controlplane.tailscale.com:" + strconv.Itoa(int(reqDetails.LocalPort))
|
||||||
|
}
|
||||||
|
if targetDial != "" {
|
||||||
|
c, err := net.Dial("tcp", targetDial)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Complete(true)
|
r.Complete(true)
|
||||||
log.Printf("Dial controlplane: %v", err)
|
log.Printf("Dial controlplane: %v", err)
|
||||||
@@ -394,6 +426,8 @@ type Server struct {
|
|||||||
shutdownCtx context.Context
|
shutdownCtx context.Context
|
||||||
shutdownCancel context.CancelFunc
|
shutdownCancel context.CancelFunc
|
||||||
|
|
||||||
|
derpIPs set.Set[netip.Addr]
|
||||||
|
|
||||||
nodes map[MAC]*node
|
nodes map[MAC]*node
|
||||||
networks set.Set[*network]
|
networks set.Set[*network]
|
||||||
networkByWAN map[netip.Addr]*network
|
networkByWAN map[netip.Addr]*network
|
||||||
@@ -404,9 +438,12 @@ func newServer() (*Server, error) {
|
|||||||
s := &Server{
|
s := &Server{
|
||||||
shutdownCtx: ctx,
|
shutdownCtx: ctx,
|
||||||
shutdownCancel: cancel,
|
shutdownCancel: cancel,
|
||||||
nodes: map[MAC]*node{},
|
|
||||||
networkByWAN: map[netip.Addr]*network{},
|
derpIPs: set.Of[netip.Addr](),
|
||||||
networks: set.Set[*network]{},
|
|
||||||
|
nodes: map[MAC]*node{},
|
||||||
|
networkByWAN: map[netip.Addr]*network{},
|
||||||
|
networks: set.Of[*network](),
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
@@ -684,7 +721,7 @@ func (n *network) HandleEthernetIPv4PacketForRouter(ep EthernetPacket) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if toForward && shouldInterceptTCP(packet) {
|
if toForward && n.s.shouldInterceptTCP(packet) {
|
||||||
ipp := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
|
ipp := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
|
||||||
pktCopy := make([]byte, 0, len(ipp.Contents)+len(ipp.Payload))
|
pktCopy := make([]byte, 0, len(ipp.Contents)+len(ipp.Payload))
|
||||||
pktCopy = append(pktCopy, ipp.Contents...)
|
pktCopy = append(pktCopy, ipp.Contents...)
|
||||||
@@ -830,7 +867,7 @@ func isMDNSQuery(pkt gopacket.Packet) bool {
|
|||||||
return ok && udp.SrcPort == 5353 && udp.DstPort == 5353
|
return ok && udp.SrcPort == 5353 && udp.DstPort == 5353
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldInterceptTCP(pkt gopacket.Packet) bool {
|
func (s *Server) shouldInterceptTCP(pkt gopacket.Packet) bool {
|
||||||
tcp, ok := pkt.Layer(layers.LayerTypeTCP).(*layers.TCP)
|
tcp, ok := pkt.Layer(layers.LayerTypeTCP).(*layers.TCP)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@@ -842,9 +879,9 @@ func shouldInterceptTCP(pkt gopacket.Packet) bool {
|
|||||||
if tcp.DstPort == 123 {
|
if tcp.DstPort == 123 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
dstIP, _ := netip.AddrFromSlice(ipv4.DstIP.To4())
|
||||||
if tcp.DstPort == 80 || tcp.DstPort == 443 {
|
if tcp.DstPort == 80 || tcp.DstPort == 443 {
|
||||||
dstIP, _ := netip.AddrFromSlice(ipv4.DstIP.To4())
|
if dstIP == fakeControlplaneIP || s.derpIPs.Contains(dstIP) {
|
||||||
if dstIP == fakeControlplaneIP {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user