playit.gg go implementation #1
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,3 +21,4 @@
|
|||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
|
||||||
|
main.go
|
||||||
|
@ -3,7 +3,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
"fmt"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -21,7 +21,7 @@ type AgentTunnel struct {
|
|||||||
RegionNum uint16 `json:"region_num"`
|
RegionNum uint16 `json:"region_num"`
|
||||||
Port PortRange `json:"port"`
|
Port PortRange `json:"port"`
|
||||||
Proto string `json:"proto"`
|
Proto string `json:"proto"`
|
||||||
LocalIp net.IP `json:"local_ip"`
|
LocalIp netip.Addr `json:"local_ip"`
|
||||||
LocalPort uint16 `json:"local_port"`
|
LocalPort uint16 `json:"local_port"`
|
||||||
TunnelType string `json:"tunnel_type"`
|
TunnelType string `json:"tunnel_type"`
|
||||||
AssignedDomain string `json:"assigned_domain"`
|
AssignedDomain string `json:"assigned_domain"`
|
||||||
@ -29,6 +29,20 @@ type AgentTunnel struct {
|
|||||||
Disabled *any `json:"disabled"`
|
Disabled *any `json:"disabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tun *AgentTunnel) DestString() string {
|
||||||
|
return fmt.Sprintf("%s:%d", tun.LocalIp, tun.LocalPort)
|
||||||
|
}
|
||||||
|
func (tun *AgentTunnel) SourceString() string {
|
||||||
|
var addr string
|
||||||
|
if addr = tun.CustomDomain; addr == "" {
|
||||||
|
addr = tun.AssignedDomain
|
||||||
|
}
|
||||||
|
if tun.TunnelType == "minecraft-java" {
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s:%d", addr, tun.Port.From)
|
||||||
|
}
|
||||||
|
|
||||||
type AgentPendingTunnel struct {
|
type AgentPendingTunnel struct {
|
||||||
ID uuid.UUID `json:"id"` // Agent ID
|
ID uuid.UUID `json:"id"` // Agent ID
|
||||||
Name string `json:"name"` // Agent Name
|
Name string `json:"name"` // Agent Name
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
"sirherobrine23.org/playit-cloud/go-playit/api"
|
"sirherobrine23.org/playit-cloud/go-playit/api"
|
||||||
@ -14,3 +15,83 @@ type AddressValue[V any] struct {
|
|||||||
type AddressLookup[Value any] interface {
|
type AddressLookup[Value any] interface {
|
||||||
Lookup(IP netip.Addr, Port uint16, Proto api.PortProto) *AddressValue[Value]
|
Lookup(IP netip.Addr, Port uint16, Proto api.PortProto) *AddressValue[Value]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MatchIP struct {
|
||||||
|
IPNumber uint64
|
||||||
|
RegionID *uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slef *MatchIP) Matches(ip netip.Addr) bool {
|
||||||
|
if ip.Is6() {
|
||||||
|
other := NewMatchIP(ip)
|
||||||
|
return slef.IPNumber == other.IPNumber && slef.RegionID == other.RegionID
|
||||||
|
}
|
||||||
|
octs := ip.As4()
|
||||||
|
if uint64(octs[3]) != slef.IPNumber {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if slef.RegionID == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return RegionNumberV4(ip) == *slef.RegionID
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMatchIP(ip netip.Addr) MatchIP {
|
||||||
|
parts := ip.As16()
|
||||||
|
regionID := binary.BigEndian.Uint16([]byte{parts[6], parts[7]})
|
||||||
|
ipNumber := binary.BigEndian.Uint64([]byte{
|
||||||
|
parts[8],
|
||||||
|
parts[9],
|
||||||
|
parts[10],
|
||||||
|
parts[11],
|
||||||
|
parts[12],
|
||||||
|
parts[13],
|
||||||
|
parts[14],
|
||||||
|
parts[15],
|
||||||
|
})
|
||||||
|
info := MatchIP{IPNumber: ipNumber}
|
||||||
|
if regionID != 0 {
|
||||||
|
info.RegionID = new(uint16)
|
||||||
|
*info.RegionID = regionID
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegionNumberV4(ip netip.Addr) uint16 {
|
||||||
|
octs := ip.As4();
|
||||||
|
if octs[0] == 147 && octs[1] == 185 && octs[2] == 221 { /* 147.185.221.0/24 (1) */
|
||||||
|
return 1
|
||||||
|
} else if octs[0] == 209 && octs[1] == 25 && octs[2] >= 140 && octs[2] <= 143 { /* 209.25.140.0/22 (2 to 5) */
|
||||||
|
return uint16(2 + (octs[2] - 140))
|
||||||
|
} else if octs[0] == 23 && octs[1] == 133 && octs[2] == 216 { /* 23.133.216.0/24 (6) */
|
||||||
|
return 6
|
||||||
|
}
|
||||||
|
/* global IP */
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type MappingOverride struct {
|
||||||
|
Proto api.PortProto
|
||||||
|
Port api.PortRange
|
||||||
|
LocalAddr netip.AddrPort
|
||||||
|
MatchIP MatchIP
|
||||||
|
}
|
||||||
|
|
||||||
|
type LookupWithOverrides []MappingOverride
|
||||||
|
|
||||||
|
func (look *LookupWithOverrides) Lookup(IP netip.Addr, Port uint16, Proto api.PortProto) *AddressValue[netip.AddrPort] {
|
||||||
|
for _, over := range *look {
|
||||||
|
if (over.Port.From <= Port && Port < over.Port.To) && (over.Proto == "both" || over.Proto == Proto) {
|
||||||
|
return &AddressValue[netip.AddrPort]{
|
||||||
|
Value: over.LocalAddr,
|
||||||
|
FromPort: over.Port.From,
|
||||||
|
ToPort: over.Port.To,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &AddressValue[netip.AddrPort]{
|
||||||
|
Value: netip.AddrPortFrom(netip.IPv4Unspecified(), Port),
|
||||||
|
FromPort: Port,
|
||||||
|
ToPort: Port+1,
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@ func asLocalMasked(ip uint32) uint32 {
|
|||||||
return ip | 0x7F000000
|
return ip | 0x7F000000
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapToLocalIP4(ip net.IP) net.IP {
|
func mapToLocalIP4(ip net.IP) netip.Addr {
|
||||||
var ipUint32 uint32
|
var ipUint32 uint32
|
||||||
if ip.To4() != nil { // Check if it's already IPv4
|
if ip.To4() != nil { // Check if it's already IPv4
|
||||||
ipUint32 = binary.BigEndian.Uint32(ip.To4())
|
ipUint32 = binary.BigEndian.Uint32(ip.To4())
|
||||||
@ -33,25 +33,23 @@ func mapToLocalIP4(ip net.IP) net.IP {
|
|||||||
shuffle(binary.BigEndian.Uint32(bytes[12:16]))
|
shuffle(binary.BigEndian.Uint32(bytes[12:16]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return net.IPv4(
|
return netip.AddrFrom4([4]byte{
|
||||||
byte(asLocalMasked(ipUint32)>>24),
|
byte(asLocalMasked(ipUint32)>>24),
|
||||||
byte(asLocalMasked(ipUint32)>>16),
|
byte(asLocalMasked(ipUint32)>>16),
|
||||||
byte(asLocalMasked(ipUint32)>>8),
|
byte(asLocalMasked(ipUint32)>>8),
|
||||||
byte(asLocalMasked(ipUint32)),
|
byte(asLocalMasked(ipUint32)),
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TcpSocket(SpecialLan bool, Peer, Host netip.AddrPort) (*net.TCPConn, error) {
|
func TcpSocket(SpecialLan bool, Peer, Host netip.AddrPort) (*net.TCPConn, error) {
|
||||||
isLoopback := Host.Addr().IsLoopback()
|
isLoopback := Host.Addr().IsLoopback()
|
||||||
if isLoopback && SpecialLan {
|
if isLoopback && SpecialLan {
|
||||||
local_ip := mapToLocalIP4(Peer.Addr().AsSlice());
|
stream, err := net.DialTCP("tcp", net.TCPAddrFromAddrPort(netip.AddrPortFrom(mapToLocalIP4(Peer.Addr().AsSlice()), 0)), net.TCPAddrFromAddrPort(Host))
|
||||||
stream, err := net.DialTCP("tcp4", net.TCPAddrFromAddrPort(netip.AddrPortFrom(netip.AddrFrom4([4]byte(local_ip.To4())), 0)), net.TCPAddrFromAddrPort(Host))
|
if err == nil {
|
||||||
if err != nil {
|
|
||||||
// logDebug.Printf("Failed to establish connection using special lan %s for flow %s -> %s\n", local_ip, Peer.String(), Host.String())
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return stream, nil
|
return stream, nil
|
||||||
}
|
}
|
||||||
|
// logDebug.Printf("Failed to establish connection using special lan %s for flow %s -> %s\n", local_ip, Peer.String(), Host.String())
|
||||||
|
}
|
||||||
// logDebug.Printf("Failed to bind connection to special local address to support IP based banning")
|
// logDebug.Printf("Failed to bind connection to special local address to support IP based banning")
|
||||||
stream, err := net.DialTCP("tcp", nil, net.TCPAddrFromAddrPort(Host))
|
stream, err := net.DialTCP("tcp", nil, net.TCPAddrFromAddrPort(Host))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -66,20 +64,14 @@ func UdpSocket(SpecialLan bool, Peer, Host netip.AddrPort) (*net.UDPConn, error)
|
|||||||
if isLoopback && SpecialLan {
|
if isLoopback && SpecialLan {
|
||||||
local_ip := mapToLocalIP4(Peer.Addr().AsSlice());
|
local_ip := mapToLocalIP4(Peer.Addr().AsSlice());
|
||||||
local_port := 40000 + (Peer.Port() % 24000);
|
local_port := 40000 + (Peer.Port() % 24000);
|
||||||
stream, err := net.DialUDP("udp4", net.UDPAddrFromAddrPort(netip.AddrPortFrom(netip.AddrFrom16([16]byte(local_ip)), local_port)), net.UDPAddrFromAddrPort(Host))
|
stream, err := net.ListenUDP("udp4", net.UDPAddrFromAddrPort(netip.AddrPortFrom(local_ip, local_port)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// logDebug.Printf("Failed to bind UDP port to %d to have connections survive agent restart: %s", local_port, err.Error())
|
stream, err = net.ListenUDP("udp4", net.UDPAddrFromAddrPort(netip.AddrPortFrom(local_ip, 0)))
|
||||||
stream, err = net.DialUDP("udp4", net.UDPAddrFromAddrPort(netip.AddrPortFrom(netip.AddrFrom16([16]byte(local_ip)), 0)), net.UDPAddrFromAddrPort(Host))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// err2 := err
|
stream, err = net.ListenUDP("udp4", nil)
|
||||||
stream, err = net.DialUDP("udp4", nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// logDebug.Printf("Failed to bind UDP to special local address, in-game ip banning will not work: %s", err2.Error())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stream, nil
|
return stream, err
|
||||||
}
|
}
|
||||||
return net.DialUDP("udp", nil, net.UDPAddrFromAddrPort(Host))
|
return net.DialUDP("udp", nil, net.UDPAddrFromAddrPort(Host))
|
||||||
}
|
}
|
@ -105,7 +105,7 @@ func (self *UdpClients) ClientCount() int {
|
|||||||
|
|
||||||
func (self *UdpClients) ForwardPacket(Flow tunnel.UdpFlow, data []byte) error {
|
func (self *UdpClients) ForwardPacket(Flow tunnel.UdpFlow, data []byte) error {
|
||||||
flowDst := Flow.Dst()
|
flowDst := Flow.Dst()
|
||||||
found := self.lookup.Lookup(flowDst.Addr(), Flow.Dst().Port(), api.PortProto("udp"))
|
found := self.lookup.Lookup(flowDst.Addr(), flowDst.Port(), api.PortProto("udp"))
|
||||||
if found == nil {
|
if found == nil {
|
||||||
return fmt.Errorf("could not find tunnel")
|
return fmt.Errorf("could not find tunnel")
|
||||||
}
|
}
|
||||||
@ -116,8 +116,9 @@ func (self *UdpClients) ForwardPacket(Flow tunnel.UdpFlow, data []byte) error {
|
|||||||
return client.SendLocal(flowDst.Port(), data)
|
return client.SendLocal(flowDst.Port(), data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.udpClientsLocker.Lock()
|
|
||||||
defer self.udpClientsLocker.Unlock()
|
defer self.udpClientsLocker.Unlock()
|
||||||
|
self.udpClientsLocker.Lock()
|
||||||
|
|
||||||
client, err := func() (*UdpClient, error) {
|
client, err := func() (*UdpClient, error) {
|
||||||
for kkey, client := range self.udpClients {
|
for kkey, client := range self.udpClients {
|
||||||
@ -128,23 +129,18 @@ func (self *UdpClients) ForwardPacket(Flow tunnel.UdpFlow, data []byte) error {
|
|||||||
localAddr := found.Value
|
localAddr := found.Value
|
||||||
var sendFlow tunnel.UdpFlow
|
var sendFlow tunnel.UdpFlow
|
||||||
var clientAddr netip.AddrPort
|
var clientAddr netip.AddrPort
|
||||||
if Flow.V4 != nil {
|
if Flow.IPSrc.Addr().Is4() {
|
||||||
clientAddr = netip.AddrPortFrom(Flow.V4.Src.Addr(), Flow.V4.Src.Port())
|
clientAddr = netip.AddrPortFrom(Flow.IPSrc.Addr(), Flow.IPSrc.Port())
|
||||||
sendFlow.V4 = &tunnel.UdpFlowBase{
|
sendFlow = tunnel.UdpFlow{
|
||||||
Src: netip.AddrPortFrom(Flow.V4.Dst.Addr(), found.FromPort),
|
IPSrc: netip.AddrPortFrom(Flow.IPDst.Addr(), found.FromPort),
|
||||||
Dst: Flow.Src(),
|
IPDst: Flow.Src(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clientAddr = netip.AddrPortFrom(Flow.V6.Src.Addr(), Flow.V6.Src.Port())
|
clientAddr = netip.AddrPortFrom(Flow.IPSrc.Addr(), Flow.IPSrc.Port())
|
||||||
sendFlow.V6 = &struct {
|
sendFlow = tunnel.UdpFlow{
|
||||||
tunnel.UdpFlowBase
|
IPSrc: netip.AddrPortFrom(Flow.IPDst.Addr(), found.FromPort),
|
||||||
Flow uint32
|
IPDst: Flow.Src(),
|
||||||
}{
|
Flow: sendFlow.Flow,
|
||||||
Flow: sendFlow.V6.Flow,
|
|
||||||
UdpFlowBase: tunnel.UdpFlowBase{
|
|
||||||
Src: netip.AddrPortFrom(Flow.V6.Dst.Addr(), found.FromPort),
|
|
||||||
Dst: Flow.Src(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,9 +386,6 @@ func (pong *Pong) ReadFrom(r io.Reader) error {
|
|||||||
} else if err := enc.ReadOption(r, func(r io.Reader) (err error) {
|
} else if err := enc.ReadOption(r, func(r io.Reader) (err error) {
|
||||||
pong.SessionExpireAt = new(time.Time)
|
pong.SessionExpireAt = new(time.Time)
|
||||||
*pong.SessionExpireAt = time.UnixMilli(enc.Read64(r)) // Fix set SessionExpireAt
|
*pong.SessionExpireAt = time.UnixMilli(enc.Read64(r)) // Fix set SessionExpireAt
|
||||||
// expAt := time.UnixMilli(enc.Read64(r)) // Fix set SessionExpireAt
|
|
||||||
// fmt.Printf("pong.SessionExpireAt: %s\n", expAt.String())
|
|
||||||
// pong.SessionExpireAt = &expAt
|
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
|
107
runner/autorun.go
Normal file
107
runner/autorun.go
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package runner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"sirherobrine23.org/playit-cloud/go-playit/api"
|
||||||
|
"sirherobrine23.org/playit-cloud/go-playit/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TunnelEntry struct {
|
||||||
|
PubAddress string
|
||||||
|
MatchIP network.MatchIP
|
||||||
|
PortType api.PortProto
|
||||||
|
FromPort, ToPort uint16
|
||||||
|
LocalStartAdress netip.AddrPort
|
||||||
|
}
|
||||||
|
|
||||||
|
type LocalLookup struct {
|
||||||
|
AdreessLock sync.Mutex
|
||||||
|
Adreess []TunnelEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (look *LocalLookup) Lookup(IP netip.Addr, Port uint16, Proto api.PortProto) *network.AddressValue[netip.AddrPort] {
|
||||||
|
look.AdreessLock.Lock()
|
||||||
|
defer look.AdreessLock.Unlock()
|
||||||
|
for _, tunnel := range look.Adreess {
|
||||||
|
if tunnel.PortType != Proto && tunnel.PortType != "both" {
|
||||||
|
continue
|
||||||
|
} else if !tunnel.MatchIP.Matches(IP) {
|
||||||
|
continue
|
||||||
|
} else if tunnel.FromPort <= Port && Port < tunnel.ToPort {
|
||||||
|
return &network.AddressValue[netip.AddrPort]{
|
||||||
|
Value: tunnel.LocalStartAdress,
|
||||||
|
FromPort: tunnel.FromPort,
|
||||||
|
ToPort: tunnel.ToPort,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (look *LocalLookup) Update(tunnels []api.AgentTunnel) {
|
||||||
|
entries := []TunnelEntry{}
|
||||||
|
for _, tunnel := range tunnels {
|
||||||
|
tun := TunnelEntry{
|
||||||
|
PortType: api.PortProto(tunnel.Proto),
|
||||||
|
FromPort: tunnel.Port.From,
|
||||||
|
ToPort: tunnel.Port.To,
|
||||||
|
LocalStartAdress: netip.AddrPortFrom(tunnel.LocalIp, tunnel.LocalPort),
|
||||||
|
MatchIP: network.MatchIP{IPNumber: uint64(tunnel.IpNum)},
|
||||||
|
}
|
||||||
|
if tunnel.RegionNum != 0 {
|
||||||
|
tun.MatchIP.RegionID = new(uint16)
|
||||||
|
*tun.MatchIP.RegionID = tunnel.RegionNum
|
||||||
|
}
|
||||||
|
entries = append(entries, tun)
|
||||||
|
}
|
||||||
|
look.AdreessLock.Lock()
|
||||||
|
defer look.AdreessLock.Unlock()
|
||||||
|
look.Adreess = entries
|
||||||
|
}
|
||||||
|
|
||||||
|
func Autorun(Api api.Api) error {
|
||||||
|
lookup := LocalLookup{Adreess: []TunnelEntry{}, AdreessLock: sync.Mutex{}}
|
||||||
|
tuns, err := Api.AgentInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lookup.Update(tuns.Tunnels)
|
||||||
|
for _, tun := range tuns.Tunnels {
|
||||||
|
src, dst := tun.SourceString(), tun.DestString()
|
||||||
|
if tun.Disabled != nil {
|
||||||
|
fmt.Printf("%s -> %s (Disabled)\n", src, dst)
|
||||||
|
} else if tun.TunnelType != "" {
|
||||||
|
fmt.Printf("%s -> %s (%s)\n", src, dst, tun.TunnelType)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s -> %s (Proto: %s, Port Count %d)\n", src, dst, tun.Proto, tun.Port.To - tun.Port.From)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var runner TunnelRunner
|
||||||
|
errorCount := 0
|
||||||
|
for {
|
||||||
|
runner, err = NewTunnelRunner(Api, &lookup)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
} else if errorCount++; errorCount > 5 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
<-time.After(time.Second*2)
|
||||||
|
}
|
||||||
|
runing := runner.Run()
|
||||||
|
go func(){
|
||||||
|
for runner.KeepRunning.Load() {
|
||||||
|
if tuns, err = Api.AgentInfo(); err != nil {
|
||||||
|
<-time.After(time.Second*3)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lookup.Update(tuns.Tunnels)
|
||||||
|
<-time.After(time.Second*3)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
defer runner.KeepRunning.Store(false)
|
||||||
|
return <- runing
|
||||||
|
}
|
@ -3,6 +3,7 @@ package runner
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -25,7 +26,7 @@ func NewTunnelRunner(Api api.Api, Lookup network.AddressLookup[netip.AddrPort])
|
|||||||
if err := tunnel.Setup(); err != nil {
|
if err := tunnel.Setup(); err != nil {
|
||||||
return TunnelRunner{}, err
|
return TunnelRunner{}, err
|
||||||
}
|
}
|
||||||
udp_clients := network.NewUdpClients(tunnel.UdpTunnel(), Lookup)
|
udp_clients := network.NewUdpClients(*tunnel.UdpTunnel(), Lookup)
|
||||||
var keep atomic.Bool
|
var keep atomic.Bool
|
||||||
keep.Store(true)
|
keep.Store(true)
|
||||||
return TunnelRunner{
|
return TunnelRunner{
|
||||||
@ -42,7 +43,7 @@ func (self *TunnelRunner) SetSpecialLan(setUse bool) {
|
|||||||
self.UdpClients.UseSpecialLan = setUse
|
self.UdpClients.UseSpecialLan = setUse
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TunnelRunner) Run() {
|
func (self *TunnelRunner) Run() chan error {
|
||||||
end := make(chan error)
|
end := make(chan error)
|
||||||
tunnel := self.Tunnel
|
tunnel := self.Tunnel
|
||||||
go func() {
|
go func() {
|
||||||
@ -54,33 +55,37 @@ func (self *TunnelRunner) Run() {
|
|||||||
if _, err := tunnel.ReloadControlAddr(); err != nil {
|
if _, err := tunnel.ReloadControlAddr(); err != nil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("Reload")
|
fmt.Println("Reciving new connection")
|
||||||
if new_client := tunnel.Update(); new_client != nil {
|
if new_client := tunnel.Update(); new_client != nil {
|
||||||
fmt.Println("New TCP Client")
|
fmt.Println("New TCP Client")
|
||||||
clients := self.TcpClients
|
|
||||||
found := self.Lookup.Lookup(new_client.ConnectAddr.Addr(), new_client.ConnectAddr.Port(), api.PortProto("tcp"))
|
found := self.Lookup.Lookup(new_client.ConnectAddr.Addr(), new_client.ConnectAddr.Port(), api.PortProto("tcp"))
|
||||||
if found == nil {
|
if found == nil {
|
||||||
|
fmt.Println("could not find local address for connection")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
local_addr := netip.AddrPortFrom(found.Value.Addr(), (new_client.ConnectAddr.Port()-found.FromPort)+found.Value.Port())
|
|
||||||
go func() {
|
go func() {
|
||||||
peerAddr := new_client.PeerAddr
|
var (
|
||||||
tunnel_conn, err := clients.Connect(*new_client)
|
tunnel_conn *network.TcpClient
|
||||||
if err != nil {
|
local_conn *net.TCPConn
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if tunnel_conn, err = self.TcpClients.Connect(*new_client); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer tunnel_conn.Stream.Close()
|
defer tunnel_conn.Stream.Close()
|
||||||
local_conn, err := network.TcpSocket(self.TcpClients.UseSpecialLAN, peerAddr, local_addr)
|
defer tunnel_conn.Dropper.Drop()
|
||||||
if err != nil {
|
|
||||||
|
|
||||||
|
if local_conn, err = network.TcpSocket(self.TcpClients.UseSpecialLAN, new_client.PeerAddr, netip.AddrPortFrom(found.Value.Addr(), (new_client.ConnectAddr.Port()-found.FromPort)+found.Value.Port())); err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
defer local_conn.Close()
|
defer local_conn.Close()
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
defer close(done)
|
||||||
go func() {
|
go func() {
|
||||||
io.Copy(&tunnel_conn.Stream, local_conn)
|
io.Copy(&tunnel_conn.Stream, local_conn)
|
||||||
done <- struct{}{}
|
done <- struct{}{}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
io.Copy(local_conn, &tunnel_conn.Stream)
|
io.Copy(local_conn, &tunnel_conn.Stream)
|
||||||
done <- struct{}{}
|
done <- struct{}{}
|
||||||
@ -92,25 +97,27 @@ func (self *TunnelRunner) Run() {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// udp_clients := self.UdpClients
|
|
||||||
// go func(){
|
// go func(){
|
||||||
// buffer := make([]byte, 2048)
|
// udp := tunnel.UdpTunnel()
|
||||||
// // had_success := false
|
|
||||||
// for self.KeepRunning.Load() {
|
// for self.KeepRunning.Load() {
|
||||||
|
// buffer := make([]byte, 2048)
|
||||||
|
// fmt.Println("udp rec")
|
||||||
// rx, err := udp.ReceiveFrom(buffer)
|
// rx, err := udp.ReceiveFrom(buffer)
|
||||||
// fmt.Println(rx)
|
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
|
// fmt.Println(err)
|
||||||
// time.Sleep(time.Second)
|
// time.Sleep(time.Second)
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
// if rx.ConfirmerdConnection {
|
// if rx.ConfirmerdConnection {
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
|
// d,_:=json.MarshalIndent(rx, "", " ")
|
||||||
|
// fmt.Printf("rx: %s\n", string(d))
|
||||||
// bytes, flow := rx.ReceivedPacket.Bytes, rx.ReceivedPacket.Flow
|
// bytes, flow := rx.ReceivedPacket.Bytes, rx.ReceivedPacket.Flow
|
||||||
// if err := udp_clients.ForwardPacket(flow, buffer[:bytes]); err != nil {
|
// if err := self.UdpClients.ForwardPacket(flow, buffer[:bytes]); err != nil {
|
||||||
// panic(err)
|
// panic(err)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }()
|
// }()
|
||||||
<-end
|
return end
|
||||||
}
|
}
|
||||||
|
@ -88,11 +88,9 @@ func (self *AuthenticatedControl) Authenticate() (AuthenticatedControl, error) {
|
|||||||
|
|
||||||
func (self *AuthenticatedControl) RecvFeedMsg() (proto.ControlFeed, error) {
|
func (self *AuthenticatedControl) RecvFeedMsg() (proto.ControlFeed, error) {
|
||||||
buff := make([]byte, 1024)
|
buff := make([]byte, 1024)
|
||||||
fmt.Println("RecvFeedMsg")
|
// self.Conn.Udp.SetReadDeadline(*new(time.Time))
|
||||||
self.Conn.Udp.SetReadDeadline(*new(time.Time))
|
self.Conn.Udp.SetReadDeadline(*new(time.Time)) // Remove deadline
|
||||||
// self.Conn.Udp.SetReadDeadline(time.Now().Add(23_000_000_000))
|
|
||||||
size, remote, err := self.Conn.Udp.ReadFromUDPAddrPort(buff)
|
size, remote, err := self.Conn.Udp.ReadFromUDPAddrPort(buff)
|
||||||
fmt.Println("End RecvFeedMsg")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return proto.ControlFeed{}, err
|
return proto.ControlFeed{}, err
|
||||||
} else if remote.Compare(self.Conn.ControlAddr) != 0 {
|
} else if remote.Compare(self.Conn.ControlAddr) != 0 {
|
||||||
|
@ -3,7 +3,6 @@ package tunnel
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
@ -137,8 +136,6 @@ func (self *ConnectedControl) Authenticate(Api api.Api) (AuthenticatedControl, e
|
|||||||
|
|
||||||
if response := feed.Response; response != nil {
|
if response := feed.Response; response != nil {
|
||||||
if response.RequestID != 10 {
|
if response.RequestID != 10 {
|
||||||
d,_:=json.MarshalIndent(feed, "", " ")
|
|
||||||
fmt.Printf("Setup: %s\n", string(d))
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if content := response.Content; content.RequestQueued {
|
if content := response.Content; content.RequestQueued {
|
||||||
|
@ -27,7 +27,7 @@ type SimpleTunnel struct {
|
|||||||
api api.Api
|
api api.Api
|
||||||
controlAddr netip.AddrPort
|
controlAddr netip.AddrPort
|
||||||
controlChannel AuthenticatedControl
|
controlChannel AuthenticatedControl
|
||||||
udpTunnel UdpTunnel
|
udpTunnel *UdpTunnel
|
||||||
lastKeepAlive, lastPing, lastPong, lastUdpAuth time.Time
|
lastKeepAlive, lastPing, lastPong, lastUdpAuth time.Time
|
||||||
lastControlTargets []netip.AddrPort
|
lastControlTargets []netip.AddrPort
|
||||||
}
|
}
|
||||||
@ -39,8 +39,8 @@ func NewSimpleTunnel(Api api.Api) SimpleTunnel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *SimpleTunnel) Setup() error {
|
func (self *SimpleTunnel) Setup() error {
|
||||||
udpTunnel := UdpTunnel{}
|
udpTunnel := new(UdpTunnel)
|
||||||
if err := AssignUdpTunnel(&udpTunnel); err != nil {
|
if err := AssignUdpTunnel(udpTunnel); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ func (self *SimpleTunnel) UpdateControlAddr(connected ConnectedControl) (bool, e
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SimpleTunnel) UdpTunnel() UdpTunnel {
|
func (self *SimpleTunnel) UdpTunnel() *UdpTunnel {
|
||||||
return self.udpTunnel
|
return self.udpTunnel
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,57 +119,62 @@ func (self *SimpleTunnel) Update() *proto.NewClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.UnixMilli() - self.lastPing.UnixMilli() > 1_000 {
|
if now.UnixMilli()-self.lastPing.UnixMilli() > 1_000 {
|
||||||
self.lastPing = now
|
self.lastPing = now
|
||||||
if err := self.controlChannel.SendPing(200, now); err != nil {}
|
if err := self.controlChannel.SendPing(200, now); err != nil {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if self.udpTunnel.RequiresAuth() {
|
if self.udpTunnel.RequiresAuth() {
|
||||||
if 5_000 < now.UnixMilli() - self.lastUdpAuth.UnixMilli() {
|
if 5_000 < now.UnixMilli()-self.lastUdpAuth.UnixMilli() {
|
||||||
self.lastUdpAuth = now
|
self.lastUdpAuth = now
|
||||||
if err := self.controlChannel.SendSetupUdpChannel(9_000); err != nil {}
|
if err := self.controlChannel.SendSetupUdpChannel(9_000); err != nil {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if self.udpTunnel.RequireResend() {
|
} else if self.udpTunnel.RequireResend() {
|
||||||
if 1_000 < now.UnixMilli() - self.lastUdpAuth.UnixMilli() {
|
if 1_000 < now.UnixMilli()-self.lastUdpAuth.UnixMilli() {
|
||||||
self.lastUdpAuth = now
|
self.lastUdpAuth = now
|
||||||
if _, err := self.udpTunnel.ResendToken(); err != nil {}
|
if _, err := self.udpTunnel.ResendToken(); err != nil {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeTillExpire := max(self.controlChannel.GetExpireAt().UnixMilli(), now.UnixMilli()) - now.UnixMilli()
|
timeTillExpire := max(self.controlChannel.GetExpireAt().UnixMilli(), now.UnixMilli()) - now.UnixMilli()
|
||||||
if 10_000 < now.UnixMilli() - self.lastKeepAlive.UnixMilli() && timeTillExpire < 30_000 {
|
if 10_000 < now.UnixMilli()-self.lastKeepAlive.UnixMilli() && timeTillExpire < 30_000 {
|
||||||
self.lastKeepAlive = now
|
self.lastKeepAlive = now
|
||||||
if err := self.controlChannel.SendKeepAlive(100); err != nil {}
|
if err := self.controlChannel.SendKeepAlive(100); err != nil {
|
||||||
if err := self.controlChannel.SendSetupUdpChannel(1); err != nil {}
|
}
|
||||||
|
if err := self.controlChannel.SendSetupUdpChannel(1); err != nil {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for range 30 {
|
for range 30 {
|
||||||
feed, err := self.controlChannel.RecvFeedMsg()
|
feed, err := self.controlChannel.RecvFeedMsg()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Printf("Update: %s", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
d,_:=json.MarshalIndent(feed, "", " ")
|
d, _ := json.MarshalIndent(feed, "", " ")
|
||||||
fmt.Printf("SimTunne: %s\n", string(d))
|
fmt.Println(string(d))
|
||||||
if newClient := feed.NewClient; newClient != nil {
|
if newClient := feed.NewClient; newClient != nil {
|
||||||
return newClient
|
return newClient
|
||||||
} else if msg := feed.Response; msg != nil {
|
} else if msg := feed.Response; msg != nil {
|
||||||
if content := msg.Content; content != nil {
|
if content := msg.Content; content != nil {
|
||||||
if details := content.UdpChannelDetails; details != nil {
|
if details := content.UdpChannelDetails; details != nil {
|
||||||
if err := self.udpTunnel.SetUdpTunnel(*details); err != nil {
|
if err := self.udpTunnel.SetUdpTunnel(details); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
} else if content.Unauthorized {
|
} else if content.Unauthorized {
|
||||||
self.controlChannel.SetExpired()
|
self.controlChannel.SetExpired()
|
||||||
} else if pong := content.Pong; pong != nil {
|
} else if pong := content.Pong; pong != nil {
|
||||||
self.lastPong = time.Now()
|
self.lastPong = time.Now()
|
||||||
if pong.ClientAddr.Compare(self.controlChannel.Conn.Pong.ClientAddr) != 0 {
|
// if pong.ClientAddr.Compare(self.controlChannel.Conn.Pong.ClientAddr) != 0 {
|
||||||
fmt.Println("client ip changed", pong.ClientAddr.String(), self.controlChannel.Conn.Pong.ClientAddr.String())
|
// fmt.Println("client ip changed", pong.ClientAddr.String(), self.controlChannel.Conn.Pong.ClientAddr.String())
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if self.lastPong.UnixMilli() != 0 && time.Now().UnixMilli()-self.lastPong.UnixMilli() > 6_000 {
|
||||||
if self.lastPong.UnixMilli() != 0 && time.Now().UnixMilli() - self.lastPong.UnixMilli() > 6_000 {
|
|
||||||
self.lastPong = time.UnixMilli(0)
|
self.lastPong = time.UnixMilli(0)
|
||||||
self.controlChannel.SetExpired()
|
self.controlChannel.SetExpired()
|
||||||
}
|
}
|
||||||
|
@ -20,83 +20,51 @@ const (
|
|||||||
V6_LEN int = 48
|
V6_LEN int = 48
|
||||||
)
|
)
|
||||||
|
|
||||||
type UdpFlowBase struct {
|
|
||||||
Src, Dst netip.AddrPort
|
|
||||||
}
|
|
||||||
|
|
||||||
type UdpFlow struct {
|
type UdpFlow struct {
|
||||||
V4 *UdpFlowBase
|
IPSrc, IPDst netip.AddrPort
|
||||||
V6 *struct {
|
|
||||||
UdpFlowBase
|
|
||||||
Flow uint32
|
Flow uint32
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *UdpFlow) Len() int {
|
func (w *UdpFlow) Len() int {
|
||||||
if w.V4 == nil {
|
if w.IPSrc.Addr().Is4() {
|
||||||
return V6_LEN
|
|
||||||
}
|
|
||||||
return V4_LEN
|
return V4_LEN
|
||||||
|
}
|
||||||
|
return V6_LEN
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *UdpFlow) Src() netip.AddrPort {
|
func (w *UdpFlow) Src() netip.AddrPort {
|
||||||
if w.V4 == nil {
|
return w.IPSrc
|
||||||
return w.V6.UdpFlowBase.Src
|
|
||||||
}
|
|
||||||
return w.V4.Src
|
|
||||||
}
|
}
|
||||||
func (w *UdpFlow) Dst() netip.AddrPort {
|
func (w *UdpFlow) Dst() netip.AddrPort {
|
||||||
if w.V4 == nil {
|
return w.IPDst
|
||||||
return w.V6.UdpFlowBase.Dst
|
|
||||||
}
|
|
||||||
return w.V4.Dst
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *UdpFlow) WithSrcPort(port uint16) UdpFlow {
|
func (w *UdpFlow) WithSrcPort(port uint16) UdpFlow {
|
||||||
if w.V4 == nil {
|
|
||||||
return UdpFlow{
|
return UdpFlow{
|
||||||
V6: &struct{UdpFlowBase; Flow uint32}{
|
IPSrc: netip.AddrPortFrom(w.IPSrc.Addr(), port),
|
||||||
Flow: w.V6.Flow,
|
IPDst: w.IPSrc,
|
||||||
UdpFlowBase: UdpFlowBase{
|
|
||||||
Src: netip.AddrPortFrom(w.V6.Src.Addr(), port),
|
|
||||||
Dst: w.V6.Src,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return UdpFlow{
|
|
||||||
V4: &UdpFlowBase{
|
|
||||||
Src: netip.AddrPortFrom(w.V4.Src.Addr(), port),
|
|
||||||
Dst: w.V4.Dst,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *UdpFlow) WriteTo(writer io.Writer) error {
|
func (w *UdpFlow) WriteTo(writer io.Writer) error {
|
||||||
var conn UdpFlowBase
|
if err := enc.WriteBytes(writer, w.IPSrc.Addr().AsSlice()); err != nil {
|
||||||
if w.V4 != nil {
|
|
||||||
conn = *w.V4
|
|
||||||
} else {
|
|
||||||
conn = w.V6.UdpFlowBase
|
|
||||||
}
|
|
||||||
if err := enc.WriteBytes(writer, conn.Src.Addr().AsSlice()); err != nil {
|
|
||||||
return err
|
return err
|
||||||
} else if err := enc.WriteBytes(writer, conn.Dst.Addr().AsSlice()); err != nil {
|
} else if err := enc.WriteBytes(writer, w.IPDst.Addr().AsSlice()); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err := enc.WriteU16(writer, conn.Src.Port()); err != nil {
|
} else if err := enc.WriteU16(writer, w.IPSrc.Port()); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err := enc.WriteU16(writer, conn.Dst.Port()); err != nil {
|
} else if err := enc.WriteU16(writer, w.IPDst.Port()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.V4 != nil {
|
if w.IPSrc.Addr().Is6() {
|
||||||
if err := enc.WriteU64(writer, REDIRECT_FLOW_4_FOOTER_ID_OLD); err != nil {
|
if err := enc.WriteU32(writer, w.Flow); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := enc.WriteU64(writer, REDIRECT_FLOW_6_FOOTER_ID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := enc.WriteU32(writer, w.V6.Flow); err != nil {
|
if err := enc.WriteU64(writer, REDIRECT_FLOW_4_FOOTER_ID_OLD); err != nil {
|
||||||
return err
|
|
||||||
} else if err := enc.WriteU64(writer, REDIRECT_FLOW_6_FOOTER_ID); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,53 +72,55 @@ func (w *UdpFlow) WriteTo(writer io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromTailUdpFlow(slice []byte) (*UdpFlow, uint64, error) {
|
func FromTailUdpFlow(slice []byte) (UdpFlow, uint64, error) {
|
||||||
if len(slice) < 8 {
|
if len(slice) < 8 {
|
||||||
return nil, 0, fmt.Errorf("not space to footer")
|
return UdpFlow{}, 0, fmt.Errorf("not space to footer")
|
||||||
}
|
}
|
||||||
footer := binary.BigEndian.Uint64(slice[len(slice)-8:])
|
|
||||||
switch footer {
|
footer := binary.BigEndian.Uint64(slice[(len(slice)-8):])
|
||||||
case REDIRECT_FLOW_4_FOOTER_ID | REDIRECT_FLOW_4_FOOTER_ID_OLD:
|
if footer == REDIRECT_FLOW_4_FOOTER_ID || footer == REDIRECT_FLOW_4_FOOTER_ID_OLD || footer == (REDIRECT_FLOW_4_FOOTER_ID | REDIRECT_FLOW_4_FOOTER_ID_OLD) {
|
||||||
if len(slice) < V4_LEN {
|
if len(slice) < V4_LEN {
|
||||||
return nil, 0, fmt.Errorf("v4 not have space")
|
return UdpFlow{}, 0, fmt.Errorf("v4 not have space")
|
||||||
}
|
}
|
||||||
slice = slice[len(slice)-V4_LEN:]
|
reader := bytes.NewReader(slice[len(slice)-V4_LEN:])
|
||||||
src_ip, _ := enc.ReadByteN(bytes.NewReader(slice), 4)
|
|
||||||
srcIP, _ := netip.AddrFromSlice(src_ip)
|
|
||||||
dst_ip, _ := enc.ReadByteN(bytes.NewReader(slice), 4)
|
|
||||||
dstIP, _ := netip.AddrFromSlice(dst_ip)
|
|
||||||
src_port, dst_port := enc.ReadU16(bytes.NewReader(slice)), enc.ReadU16(bytes.NewReader(slice))
|
|
||||||
|
|
||||||
return &UdpFlow{
|
var err error
|
||||||
V4: &UdpFlowBase{
|
var src_ip, dst_ip []byte
|
||||||
Src: netip.AddrPortFrom(srcIP, src_port),
|
if src_ip, err = enc.ReadByteN(reader, 4); err != nil {
|
||||||
Dst: netip.AddrPortFrom(dstIP, dst_port),
|
return UdpFlow{}, 0, err
|
||||||
},
|
} else if dst_ip, err = enc.ReadByteN(reader, 4); err != nil {
|
||||||
}, 0, nil
|
return UdpFlow{}, 0, err
|
||||||
case REDIRECT_FLOW_6_FOOTER_ID:
|
}
|
||||||
|
src_port, dst_port := enc.ReadU16(reader), enc.ReadU16(reader)
|
||||||
|
srcIP := netip.AddrFrom4([4]byte(src_ip))
|
||||||
|
dstIP := netip.AddrFrom4([4]byte(dst_ip))
|
||||||
|
|
||||||
|
var point UdpFlow
|
||||||
|
point.IPSrc = netip.AddrPortFrom(srcIP, src_port)
|
||||||
|
point.IPDst = netip.AddrPortFrom(dstIP, dst_port)
|
||||||
|
return point, 0, nil
|
||||||
|
} else if footer == REDIRECT_FLOW_6_FOOTER_ID {
|
||||||
if len(slice) < V6_LEN {
|
if len(slice) < V6_LEN {
|
||||||
return nil, footer, fmt.Errorf("v6 not have space")
|
return UdpFlow{}, footer, fmt.Errorf("v6 not have space")
|
||||||
}
|
}
|
||||||
slice = slice[len(slice)-V6_LEN:]
|
reader := bytes.NewReader(slice[len(slice)-V4_LEN:])
|
||||||
src_ip, _ := enc.ReadByteN(bytes.NewReader(slice), 16)
|
|
||||||
srcIP, _ := netip.AddrFromSlice(src_ip)
|
|
||||||
dst_ip, _ := enc.ReadByteN(bytes.NewReader(slice), 16)
|
|
||||||
dstIP, _ := netip.AddrFromSlice(dst_ip)
|
|
||||||
src_port, dst_port := enc.ReadU16(bytes.NewReader(slice)), enc.ReadU16(bytes.NewReader(slice))
|
|
||||||
flow := enc.ReadU32(bytes.NewReader(slice))
|
|
||||||
|
|
||||||
return &UdpFlow{
|
var err error
|
||||||
V6: &struct {
|
var src_ip, dst_ip []byte
|
||||||
UdpFlowBase
|
if src_ip, err = enc.ReadByteN(reader, 16); err != nil {
|
||||||
Flow uint32
|
return UdpFlow{}, 0, err
|
||||||
}{
|
} else if dst_ip, err = enc.ReadByteN(reader, 16); err != nil {
|
||||||
UdpFlowBase{
|
return UdpFlow{}, 0, err
|
||||||
Src: netip.AddrPortFrom(srcIP, src_port),
|
|
||||||
Dst: netip.AddrPortFrom(dstIP, dst_port),
|
|
||||||
},
|
|
||||||
flow,
|
|
||||||
},
|
|
||||||
}, 0, nil
|
|
||||||
}
|
}
|
||||||
return nil, footer, nil
|
src_port, dst_port, flow := enc.ReadU16(reader), enc.ReadU16(reader), enc.ReadU32(reader)
|
||||||
|
srcIP := netip.AddrFrom16([16]byte(src_ip))
|
||||||
|
dstIP := netip.AddrFrom16([16]byte(dst_ip))
|
||||||
|
|
||||||
|
var point UdpFlow
|
||||||
|
point.IPSrc = netip.AddrPortFrom(srcIP, src_port)
|
||||||
|
point.IPDst = netip.AddrPortFrom(dstIP, dst_port)
|
||||||
|
point.Flow = flow
|
||||||
|
return point, 0, nil
|
||||||
|
}
|
||||||
|
return UdpFlow{}, footer, fmt.Errorf("read fotter")
|
||||||
}
|
}
|
||||||
|
@ -82,9 +82,8 @@ func (udp *UdpTunnel) RequiresAuth() bool {
|
|||||||
return 5 < now_sec()-lastSend
|
return 5 < now_sec()-lastSend
|
||||||
}
|
}
|
||||||
|
|
||||||
func (udp *UdpTunnel) SetUdpTunnel(details proto.UdpChannelDetails) error {
|
func (udp *UdpTunnel) SetUdpTunnel(details *proto.UdpChannelDetails) error {
|
||||||
// LogDebug.Println("Updating Udp Tunnel")
|
// LogDebug.Println("Updating Udp Tunnel")
|
||||||
{
|
|
||||||
udp.locker.Lock()
|
udp.locker.Lock()
|
||||||
if current := udp.Details.Udp; current != nil {
|
if current := udp.Details.Udp; current != nil {
|
||||||
if bytes.Equal(current.Token, details.Token) && current.TunnelAddr.Compare(details.TunnelAddr) == 0 {
|
if bytes.Equal(current.Token, details.Token) && current.TunnelAddr.Compare(details.TunnelAddr) == 0 {
|
||||||
@ -97,11 +96,12 @@ func (udp *UdpTunnel) SetUdpTunnel(details proto.UdpChannelDetails) error {
|
|||||||
udp.Details.AddrHistory = append(udp.Details.AddrHistory, oldAddr)
|
udp.Details.AddrHistory = append(udp.Details.AddrHistory, oldAddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
udp.Details.Udp = &details
|
udp.Details.Udp = new(proto.UdpChannelDetails)
|
||||||
|
udp.Details.Udp.Token = details.Token
|
||||||
|
udp.Details.Udp.TunnelAddr = details.TunnelAddr
|
||||||
udp.locker.Unlock()
|
udp.locker.Unlock()
|
||||||
}
|
|
||||||
|
|
||||||
return udp.SendToken(&details)
|
return udp.SendToken(details)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (udp *UdpTunnel) ResendToken() (bool, error) {
|
func (udp *UdpTunnel) ResendToken() (bool, error) {
|
||||||
@ -175,12 +175,13 @@ func (Udp *UdpTunnel) GetToken() ([]byte, error) {
|
|||||||
return lock.Udp.Token[:], nil
|
return lock.Udp.Token[:], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type UdpTunnelRx struct {
|
type UdpTunnelRxPacket struct {
|
||||||
ConfirmerdConnection bool
|
|
||||||
ReceivedPacket *struct {
|
|
||||||
Bytes uint64
|
Bytes uint64
|
||||||
Flow UdpFlow
|
Flow UdpFlow
|
||||||
}
|
}
|
||||||
|
type UdpTunnelRx struct {
|
||||||
|
ConfirmerdConnection bool
|
||||||
|
ReceivedPacket UdpTunnelRxPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Udp *UdpTunnel) ReceiveFrom(buff []byte) (*UdpTunnelRx, error) {
|
func (Udp *UdpTunnel) ReceiveFrom(buff []byte) (*UdpTunnelRx, error) {
|
||||||
@ -191,6 +192,8 @@ func (Udp *UdpTunnel) ReceiveFrom(buff []byte) (*UdpTunnelRx, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// udp.SetReadDeadline(time.Now().Add(time.Second * 2))
|
||||||
byteSize, remote, err := udp.ReadFromUDPAddrPort(buff)
|
byteSize, remote, err := udp.ReadFromUDPAddrPort(buff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -203,36 +206,34 @@ func (Udp *UdpTunnel) ReceiveFrom(buff []byte) (*UdpTunnelRx, error) {
|
|||||||
return nil, fmt.Errorf("got data from other source")
|
return nil, fmt.Errorf("got data from other source")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
buff = buff[:byteSize]
|
||||||
token, err := Udp.GetToken()
|
token, err := Udp.GetToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogDebug.Println("Check token")
|
var point UdpTunnelRx
|
||||||
// LogDebug.Println(buff)
|
if bytes.Equal(buff, token) {
|
||||||
// LogDebug.Println(token)
|
|
||||||
// LogDebug.Println("end check token")
|
|
||||||
if bytes.Equal(buff[:byteSize], token) {
|
|
||||||
// LogDebug.Println("udp session confirmed")
|
// LogDebug.Println("udp session confirmed")
|
||||||
Udp.LastConfirm.Store(now_sec())
|
Udp.LastConfirm.Store(now_sec())
|
||||||
return &UdpTunnelRx{ConfirmerdConnection: true}, nil
|
point.ConfirmerdConnection = true
|
||||||
}
|
return &point, nil
|
||||||
|
} else if len(buff)+V6_LEN < byteSize {
|
||||||
if len(buff)+V6_LEN < byteSize {
|
|
||||||
return nil, fmt.Errorf("receive buffer too small")
|
return nil, fmt.Errorf("receive buffer too small")
|
||||||
}
|
}
|
||||||
|
|
||||||
footer, footerInt, err := FromTailUdpFlow(buff[byteSize:])
|
footer, footerInt, err := FromTailUdpFlow(buff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if footerInt == UDP_CHANNEL_ESTABLISH_ID {
|
if footerInt == UDP_CHANNEL_ESTABLISH_ID {
|
||||||
actual := hex.EncodeToString(buff[byteSize:])
|
actual := hex.EncodeToString(buff)
|
||||||
expected := hex.EncodeToString(token)
|
expected := hex.EncodeToString(token)
|
||||||
return nil, fmt.Errorf("unexpected UDP establish packet, actual: %s, expected: %s", actual, expected)
|
return nil, fmt.Errorf("unexpected UDP establish packet, actual: %s, expected: %s", actual, expected)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("failed to extract udp footer: %s, err: %s", hex.EncodeToString(buff[byteSize:]), err.Error())
|
return nil, fmt.Errorf("failed to extract udp footer: %s, err: %s", hex.EncodeToString(buff), err.Error())
|
||||||
}
|
}
|
||||||
return &UdpTunnelRx{ReceivedPacket: &struct {
|
point.ReceivedPacket = UdpTunnelRxPacket{
|
||||||
Bytes uint64
|
uint64(byteSize - footer.Len()),
|
||||||
Flow UdpFlow
|
footer,
|
||||||
}{uint64(byteSize) - uint64(footer.Len()), *footer}}, nil
|
}
|
||||||
|
return &point, nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user