feat(forwarder): split forwarder to different file
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/tsnet"
|
||||
)
|
||||
|
||||
var statusCache struct {
|
||||
mu sync.Mutex
|
||||
status *ipnstate.Status
|
||||
expires time.Time
|
||||
}
|
||||
|
||||
const statusCacheTTL = 5 * time.Second
|
||||
|
||||
func getCachedStatus(ctx context.Context, srv *tsnet.Server) (*ipnstate.Status, error) {
|
||||
statusCache.mu.Lock()
|
||||
if statusCache.status != nil && time.Now().Before(statusCache.expires) {
|
||||
st := statusCache.status
|
||||
statusCache.mu.Unlock()
|
||||
return st, nil
|
||||
}
|
||||
statusCache.mu.Unlock()
|
||||
|
||||
lc, err := srv.LocalClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
st, err := lc.Status(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
statusCache.mu.Lock()
|
||||
statusCache.status = st
|
||||
statusCache.expires = time.Now().Add(statusCacheTTL)
|
||||
statusCache.mu.Unlock()
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func isTsnetTarget(host string) bool {
|
||||
if ip, err := netip.ParseAddr(host); err == nil {
|
||||
tsnetV4 := netip.MustParsePrefix("100.64.0.0/10")
|
||||
tsnetV6 := netip.MustParsePrefix("fd7a:115c:a1e0::/48")
|
||||
return tsnetV4.Contains(ip) || tsnetV6.Contains(ip)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func getConnType(ctx context.Context, srv *tsnet.Server, remoteAddrStr string) string {
|
||||
st, err := getCachedStatus(ctx, srv)
|
||||
if err != nil {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
remoteHost, _, err := net.SplitHostPort(remoteAddrStr)
|
||||
if err != nil {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
for _, peer := range st.Peer {
|
||||
for _, addr := range peer.TailscaleIPs {
|
||||
if addr.String() == remoteHost {
|
||||
if peer.CurAddr != "" {
|
||||
return "direct"
|
||||
}
|
||||
if peer.Relay != "" {
|
||||
return fmt.Sprintf("derp(%s)", peer.Relay)
|
||||
}
|
||||
return "direct"
|
||||
}
|
||||
}
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
Reference in New Issue
Block a user