Clients dynamic TX/RX sizes #1

Merged
Sirherobrine23 merged 3 commits from dynamic-size into main 2024-06-11 21:24:33 +00:00
17 changed files with 1086 additions and 277 deletions
Showing only changes of commit 24764ddd7f - Show all commits

View File

@ -8,6 +8,7 @@ import (
"log"
"net"
"net/netip"
"reflect"
"time"
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/pipe"
@ -67,6 +68,13 @@ func (client Client) Recive() (res *proto.Response, err error) {
recBuff := make([]byte, client.ResponseBuffer+proto.PacketSize)
var n int
if n, err = client.Conn.Read(recBuff); err != nil {
if opErr, isOp := err.(*net.OpError); isOp {
log.Println()
err = opErr.Err
if reflect.TypeOf(opErr.Err).String() == "poll.errNetClosing" {
return nil, io.EOF
}
}
return
}
@ -89,7 +97,9 @@ func (client Client) Send(req proto.Request) error {
return nil
}
// Send token to controller to connect to tunnel
func (client *Client) auth() (info *proto.AgentInfo, err error) {
attemps := 0
var res *proto.Response
for {
if err = client.Send(proto.Request{AgentAuth: &client.Token}); err != nil {
@ -103,6 +113,10 @@ func (client *Client) auth() (info *proto.AgentInfo, err error) {
if res.BadRequest || res.SendAuth {
// Wait seconds to resend token
<-time.After(time.Second * 3)
if attemps++; attemps >= 25 {
err = ErrAgentUnathorized // Cannot auth
return
}
continue // Reload auth
} else if res.Unauthorized {
// Close tunnel and break loop-de-loop 🦔
@ -115,19 +129,29 @@ func (client *Client) auth() (info *proto.AgentInfo, err error) {
return res.AgentInfo, nil
}
// Dial and Auth agent before require call in new gorotine client.Backgroud()
// Dial to controller and auto accept new responses from controller
func (client *Client) Dial() (info *proto.AgentInfo, err error) {
if client.Conn, err = net.DialUDP("udp", nil, net.UDPAddrFromAddrPort(client.ControlAddr)); err != nil {
return
}
go client.backgroud()
return client.auth()
}
// Watcher response from controller
func (client *Client) Backgroud() (err error) {
func (client *Client) backgroud() (err error) {
go func(){
for {
var current = time.Now()
client.Send(proto.Request{Ping: &current})
<-time.After(time.Second * 5)
}
}()
for {
log.Println("waiting response from controller")
var res *proto.Response
if res, err = client.Recive(); err != nil {
log.Println(err.Error())
if err == io.EOF {
break
}

View File

@ -56,30 +56,21 @@ var CmdClient = cli.Command{
}
fmt.Printf("Connected, Remote port: %d\n", info.LitenerPort)
fmt.Printf(" Remote address: %s\n", info.AddrPort.String())
go client.Backgroud()
localConnect := ctx.String("dial")
for {
var conn, dial net.Conn
select {
case tcp := <-client.NewTCPClient:
go func() {
conn, err := net.Dial("tcp", localConnect)
if err != nil {
return
}
go io.Copy(conn, tcp)
go io.Copy(tcp, conn)
}()
case udp := <-client.NewUDPClient:
go func () {
conn, err := net.DialUDP("udp", nil, net.UDPAddrFromAddrPort(netip.MustParseAddrPort(localConnect)))
if err != nil {
return
}
go io.Copy(conn, udp)
go io.Copy(udp, conn)
}()
case conn = <-client.NewTCPClient:
if dial, err = net.Dial("tcp", localConnect); err != nil {
continue
}
case conn = <-client.NewUDPClient:
if dial, err = net.DialUDP("udp", nil, net.UDPAddrFromAddrPort(netip.MustParseAddrPort(localConnect))); err != nil {
continue
}
}
go io.Copy(conn, dial)
go io.Copy(dial, conn)
}
},
}

View File

@ -13,14 +13,6 @@ type serverCalls struct {
XormEngine *xorm.Engine
}
type Tun struct {
ID int64 `xorm:"pk"` // Tunnel ID
User int64 // Agent ID
Token [36]byte // Tunnel Token
Proto uint8 // Proto accept
PortListen uint16 // Port listen agent
}
type User struct {
ID int64 `xorm:"pk"` // Client ID
Username string `xorm:"varchar(32) notnull unique 'user'"` // Username
@ -30,18 +22,35 @@ type User struct {
UpdateAt time.Time `xorm:"updated"` // Update date
}
type Tun struct {
ID int64 `xorm:"pk"` // Tunnel ID
User int64 `xorm:"notnull"` // Agent ID
Token [36]byte `xorm:"blob notnull unique"` // Tunnel Token
Proto uint8 `xorm:"default 3"` // Proto accept
PortListen uint16 // Port listen agent
}
type Ping struct {
ID int64 `json:"-" xorm:"pk"` // Tunnel ID
TunID int64 `json:"-"`
ServerTime time.Time `json:"server" xorm:"datetime notnull"`
AgentTime time.Time `json:"agent" xorm:"datetime notnull"`
}
func NewCall(DBConn string) (call *serverCalls, err error) {
call = new(serverCalls)
if call.XormEngine, err = xorm.NewEngine("sqlite", DBConn); err != nil {
return
}
call.XormEngine.SetMapper(names.SameMapper{})
call.XormEngine.CreateTables(Tun{}, User{})
session := call.XormEngine.NewSession()
defer session.Close()
session.CreateTable(User{})
session.CreateTable(Tun{})
session.CreateTable(Ping{})
return
}
func (call serverCalls) AgentShutdown(Token [36]byte) (err error) { return } // Ignore
func (call serverCalls) AgentInfo(Token [36]byte) (server.TunnelInfo, error) {
var tun = Tun{Token: Token}
if ok, err := call.XormEngine.Get(&tun); err != nil || !ok {
@ -55,3 +64,22 @@ func (call serverCalls) AgentInfo(Token [36]byte) (server.TunnelInfo, error) {
Proto: tun.Proto,
}, nil
}
func (call serverCalls) RegisterPing(serverTime, clientTime time.Time, Token [36]byte) error {
var tun = Tun{Token: Token}
if ok, err := call.XormEngine.Get(&tun); err != nil {
return err
} else if !ok {
return server.ErrNoAgent
}
ping := new(Ping)
ping.TunID = tun.ID
ping.ServerTime = serverTime
ping.AgentTime = clientTime
_, err := call.XormEngine.InsertOne(ping)
if err != nil {
return err
}
return nil
}

1
go.mod
View File

@ -24,6 +24,7 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.19.0 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.50.9 // indirect

3
go.sum
View File

@ -60,8 +60,9 @@ github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -0,0 +1,201 @@
package udplisterner
import (
"io"
"net"
"os"
"sync"
"time"
)
// pipeDeadline is an abstraction for handling timeouts.
type pipeDeadline struct {
mu sync.Mutex // Guards timer and cancel
timer *time.Timer
cancel chan struct{} // Must be non-nil
}
func makePipeDeadline() pipeDeadline {
return pipeDeadline{cancel: make(chan struct{})}
}
// set sets the point in time when the deadline will time out.
// A timeout event is signaled by closing the channel returned by waiter.
// Once a timeout has occurred, the deadline can be refreshed by specifying a
// t value in the future.
//
// A zero value for t prevents timeout.
func (d *pipeDeadline) set(t time.Time) {
d.mu.Lock()
defer d.mu.Unlock()
if d.timer != nil && !d.timer.Stop() {
<-d.cancel // Wait for the timer callback to finish and close cancel
}
d.timer = nil
// Time is zero, then there is no deadline.
closed := isClosedChan(d.cancel)
if t.IsZero() {
if closed {
d.cancel = make(chan struct{})
}
return
}
// Time in the future, setup a timer to cancel in the future.
if dur := time.Until(t); dur > 0 {
if closed {
d.cancel = make(chan struct{})
}
d.timer = time.AfterFunc(dur, func() {
close(d.cancel)
})
return
}
// Time in the past, so close immediately.
if !closed {
close(d.cancel)
}
}
// wait returns a channel that is closed when the deadline is exceeded.
func (d *pipeDeadline) wait() chan struct{} {
d.mu.Lock()
defer d.mu.Unlock()
return d.cancel
}
func isClosedChan(c <-chan struct{}) bool {
select {
case <-c:
return true
default:
return false
}
}
type pipe struct {
localAddr, remoteAddr net.Addr
wrMu sync.Mutex // Serialize Write operations
// Used by local Read to interact with remote Write.
// Successful receive on rdRx is always followed by send on rdTx.
rdRx <-chan []byte
rdTx chan<- int
// Used by local Write to interact with remote Read.
// Successful send on wrTx is always followed by receive on wrRx.
wrTx chan<- []byte
wrRx <-chan int
once sync.Once // Protects closing localDone
localDone chan struct{}
remoteDone <-chan struct{}
readDeadline pipeDeadline
writeDeadline pipeDeadline
}
func (p *pipe) LocalAddr() net.Addr { return p.localAddr }
func (p *pipe) RemoteAddr() net.Addr { return p.remoteAddr }
func (p *pipe) Read(b []byte) (int, error) {
n, err := p.read(b)
if err != nil && err != io.EOF && err != io.ErrClosedPipe {
err = &net.OpError{Op: "read", Net: "pipe", Err: err}
}
return n, err
}
func (p *pipe) read(b []byte) (n int, err error) {
switch {
case isClosedChan(p.localDone):
return 0, io.ErrClosedPipe
case isClosedChan(p.remoteDone):
return 0, io.EOF
case isClosedChan(p.readDeadline.wait()):
return 0, os.ErrDeadlineExceeded
}
select {
case bw := <-p.rdRx:
nr := copy(b, bw)
p.rdTx <- nr
return nr, nil
case <-p.localDone:
return 0, io.ErrClosedPipe
case <-p.remoteDone:
return 0, io.EOF
case <-p.readDeadline.wait():
return 0, os.ErrDeadlineExceeded
}
}
func (p *pipe) Write(b []byte) (int, error) {
n, err := p.write(b)
if err != nil && err != io.ErrClosedPipe {
err = &net.OpError{Op: "write", Net: "pipe", Err: err}
}
return n, err
}
func (p *pipe) write(b []byte) (n int, err error) {
switch {
case isClosedChan(p.localDone):
return 0, io.ErrClosedPipe
case isClosedChan(p.remoteDone):
return 0, io.ErrClosedPipe
case isClosedChan(p.writeDeadline.wait()):
return 0, os.ErrDeadlineExceeded
}
p.wrMu.Lock() // Ensure entirety of b is written together
defer p.wrMu.Unlock()
for once := true; once || len(b) > 0; once = false {
select {
case p.wrTx <- b:
nw := <-p.wrRx
b = b[nw:]
n += nw
case <-p.localDone:
return n, io.ErrClosedPipe
case <-p.remoteDone:
return n, io.ErrClosedPipe
case <-p.writeDeadline.wait():
return n, os.ErrDeadlineExceeded
}
}
return n, nil
}
func (p *pipe) SetDeadline(t time.Time) error {
if isClosedChan(p.localDone) || isClosedChan(p.remoteDone) {
return io.ErrClosedPipe
}
p.readDeadline.set(t)
p.writeDeadline.set(t)
return nil
}
func (p *pipe) SetReadDeadline(t time.Time) error {
if isClosedChan(p.localDone) || isClosedChan(p.remoteDone) {
return io.ErrClosedPipe
}
p.readDeadline.set(t)
return nil
}
func (p *pipe) SetWriteDeadline(t time.Time) error {
if isClosedChan(p.localDone) || isClosedChan(p.remoteDone) {
return io.ErrClosedPipe
}
p.writeDeadline.set(t)
return nil
}
func (p *pipe) Close() error {
p.once.Do(func() { close(p.localDone) })
return nil
}

View File

@ -0,0 +1,111 @@
package udplisterner
import (
"io"
"log"
"net"
)
type client struct {
ClientConn *pipe
rdRx, wrTx chan []byte
rdTx, wrRx chan int
localDone, remoteDone chan struct{}
}
type UDPListener struct {
conn *net.UDPConn // Root listener
toAccept chan any // Return accept connections
clients map[string]client // Clients
}
// Get address from UDP Listener
func (lis UDPListener) Addr() net.Addr {
return lis.conn.LocalAddr()
}
func (lis *UDPListener) Close() error {
for _, client := range lis.clients {
client.localDone <- struct{}{} // Close and wait response, ignoraing errors
}
close(lis.toAccept) // end channel
return lis.conn.Close()
}
func (lis UDPListener) Accept() (net.Conn, error) {
if rec, ok := <-lis.toAccept; ok {
if err, isErr := rec.(error); isErr {
return nil, err
}
return rec.(net.Conn), nil
}
return nil, io.ErrClosedPipe
}
func Listen(network string, address *net.UDPAddr) (net.Listener, error) {
var conn *net.UDPConn
var err error
if conn, err = net.ListenUDP(network, address); err != nil {
return nil, err
}
accepts := make(chan any)
listen := &UDPListener{conn, accepts, make(map[string]client)}
go func() {
var maxSize int = 1024
for {
log.Println("waiting request")
buff := make([]byte, maxSize)
n, from, err := conn.ReadFromUDPAddrPort(buff)
if err != nil {
break // end loop-de-loop
}
log.Printf("Request from: %s", from.String())
if tun, ok := listen.clients[from.String()]; ok {
tun.wrTx <- buff[:n]
<-tun.rdTx // but ignore
continue
}
go func() {
rdRx := make(chan []byte)
wrTx := make(chan []byte)
rdTx := make(chan int)
wrRx := make(chan int)
localDone := make(chan struct{})
remoteDone := make(chan struct{})
newClient := client{
rdRx: rdRx, rdTx: rdTx,
wrTx: wrTx, wrRx: wrRx,
localDone: localDone, remoteDone: remoteDone,
ClientConn: &pipe{
localAddr: conn.LocalAddr(),
remoteAddr: net.UDPAddrFromAddrPort(from),
rdRx: wrTx, rdTx: wrRx,
wrTx: rdRx, wrRx: rdTx,
localDone: remoteDone, remoteDone: localDone,
readDeadline: makePipeDeadline(),
writeDeadline: makePipeDeadline(),
},
}
listen.clients[from.String()] = newClient // Set to clients map
listen.toAccept <- newClient.ClientConn // Send to accept
newClient.wrTx <- buff[:n]
<-newClient.rdTx // but ignore
for {
if data, ok := <-rdRx; ok {
n, err := conn.WriteToUDPAddrPort(data, from)
if err != nil {
localDone <- struct{}{}
<-remoteDone // wait remote
break // end
}
wrRx <- n // send write data
continue
}
break
}
}()
}
}()
return listen, nil
}

View File

@ -0,0 +1,44 @@
package udplisterner
import (
"bytes"
"net"
"testing"
"time"
)
func TestListen(t *testing.T) {
addr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:0")
listen, err := Listen("udp", addr)
if err != nil {
t.Fatal(err)
}
defer listen.Close() // end test
go func(){
t.Logf("Waiting to accept client ...\n")
conn, err := listen.Accept()
if err != nil {
t.Fatal(err)
}
defer conn.Close()
buff := make([]byte, 4)
if _, err := conn.Read(buff); err != nil {
t.Fatal(err)
}
if bytes.Compare(buff, []byte{1, 9, 9, 1}) != 0 {
t.Fatalf("cannot get same buffer bytes")
}
conn.Write(buff)
}()
time.Sleep(time.Microsecond)
t.Logf("Connecting to %s\n", listen.Addr().String())
addr, _ = net.ResolveUDPAddr("udp", listen.Addr().String())
conn, err := net.DialUDP("udp", nil, addr)
if err != nil {
t.Fatal(err)
}
defer conn.Close()
conn.Write([]byte{1, 9, 9, 1})
conn.Read(make([]byte, 4))
}

View File

@ -85,7 +85,7 @@ func (close *Client) Reader(r io.Reader) (err error) {
type ClientData struct {
Client Client // Client Destination
Size uint64 // Data size
Data []byte // Bytes to send
Data []byte `json:"-"` // Bytes to send
}
func (data ClientData) Writer(w io.Writer) error {

View File

@ -177,6 +177,7 @@ func (res *Response) Reader(r io.Reader) error {
if *res.ResizeBuffer, err = bigendian.ReadUint64(r); err != nil {
return err
}
return nil
}
return ErrInvalidBody

View File

@ -2,6 +2,7 @@ package server
import (
"net"
"time"
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
)
@ -23,7 +24,7 @@ func getFreePort() (int, error) {
// Accept any agent in ramdom port
type DefaultCall struct{}
func (DefaultCall) AgentShutdown(Token [36]byte) error { return nil }
func (DefaultCall) RegisterPing(serverTime, clientTime time.Time, Token [36]byte) error { return nil }
func (d DefaultCall) AgentInfo(Token [36]byte) (TunnelInfo, error) {
port, err := getFreePort()
if err == nil {

View File

@ -2,15 +2,15 @@ package server
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net"
"net/netip"
"time"
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/udplisterner"
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/udplisterner/v2"
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
)
@ -37,15 +37,25 @@ type Tunnel struct {
// Interface to server accept and reject agents sessions
type ServerCalls interface {
AgentInfo(Token [36]byte) (TunnelInfo, error)
AgentShutdown(Token [36]byte) error
RegisterPing(serverTime, clientTime time.Time, Token [36]byte) error
}
type Server struct {
Conn *net.UDPConn // Local listen
RequestBuffer uint64 // Request Buffer
Tunnels map[string]Tunnel // Tunnels listened
ServerCalls ServerCalls // Server call to auth and more
}
func (server Server) Send(to netip.AddrPort, res proto.Response) error {
buff, err := res.Wbytes()
if err != nil {
return err
}
_, err = server.Conn.WriteToUDPAddrPort(buff, to)
return err
}
// Create new server struct
//
// if Calls is nil set DefaultCall and accept any new agent in random ports and TCP+UDP Proto
@ -62,12 +72,8 @@ func NewServer(Calls ServerCalls) Server {
// Close client and send dead to agent
func (tun *Tunnel) Close() {
if tun.TCPListener != nil {
tun.TCPListener.Close()
}
if tun.UDPListener != nil {
tun.UDPListener.Close()
}
tun.TCPListener.Close()
tun.UDPListener.Close()
for key, conn := range tun.UDPClients {
conn.Close() // End connection
@ -218,11 +224,11 @@ func (server *Server) Listen(ControllerPort uint16) (err error) {
if conn, err = net.ListenUDP("udp", net.UDPAddrFromAddrPort(netip.AddrPortFrom(netip.IPv4Unspecified(), ControllerPort))); err != nil {
return
}
server.Conn = conn
for {
var err error
var req proto.Request
var res proto.Response
var readSize int
var addr netip.AddrPort
log.Println("waiting to request")
@ -235,24 +241,22 @@ func (server *Server) Listen(ControllerPort uint16) (err error) {
}
if err := req.Reader(bytes.NewBuffer(buffer[:readSize])); err != nil {
res.BadRequest = true
if buffer, err = res.Wbytes(); err != nil {
continue // not send bad request to agent
}
conn.WriteToUDPAddrPort(buffer, addr) // Send bad request to agent
log.Printf("From %s, cannot reader buffer: %s", addr.String(), err.Error())
go server.Send(addr, proto.Response{BadRequest: true}) // Send bad request to agent
continue // Continue parsing new requests
}
if ping := req.Ping; ping != nil {
res.Pong = new(time.Time)
*res.Pong = time.Now()
data, _ := res.Wbytes()
conn.WriteToUDPAddrPort(data, addr)
continue
}
d,_ := json.Marshal(req)
log.Printf("From %s: %s", addr.String(), string(d))
// Process request if tunnel is authenticated
if tun, exist := server.Tunnels[addr.String()]; exist && tun.Authenticated {
if ping := req.Ping; ping != nil {
current := time.Now()
go server.ServerCalls.RegisterPing(current, *req.Ping, tun.Token)
go server.Send(addr, proto.Response{Pong: &current})
continue
}
go tun.Request(req) // process request to tunnel
continue // Call next message
}
@ -285,45 +289,53 @@ func (server *Server) Listen(ControllerPort uint16) (err error) {
}
if !server.Tunnels[addr.String()].Authenticated && req.AgentAuth == nil {
res.SendAuth = true
data, _ := res.Wbytes()
conn.WriteToUDPAddrPort(data, addr)
go server.Send(addr, proto.Response{SendAuth: true})
continue
}
info, err := server.ServerCalls.AgentInfo([36]byte(req.AgentAuth[:]))
if err != nil {
if err == ErrNoAgent {
// Client not found
res.Unauthorized = true
go server.Send(addr, proto.Response{Unauthorized: true})
} else {
// Cannot process request resend
res.SendAuth = true
go server.Send(addr, proto.Response{SendAuth: true})
}
data, _ := res.Wbytes()
conn.WriteToUDPAddrPort(data, addr)
continue
}
// Close tunnels tokens listened
for ared, tun := range server.Tunnels {
if ared == addr.String() {
continue
} else if bytes.Equal(tun.Token[:], req.AgentAuth[:]) {
log.Printf("Closing agent %s", ared)
tun.Close()
delete(server.Tunnels, ared)
}
}
tun := server.Tunnels[addr.String()]
tun.Token = *req.AgentAuth // Set token to tunnel
if info.Proto == 3 || info.Proto == 1 {
tun.TCPListener, err = net.ListenTCP("tcp", net.TCPAddrFromAddrPort(netip.AddrPortFrom(netip.IPv4Unspecified(), info.PortListen)))
if err != nil {
res.BadRequest = true
data, _ := res.Wbytes()
conn.WriteToUDPAddrPort(data, addr)
log.Printf("TCP Listener from %s: %s", addr.String(), err.Error())
go server.Send(addr, proto.Response{BadRequest: true})
continue
}
go tun.TCPAccepts() // Make accepts new requests
}
if info.Proto == 3 || info.Proto == 2 {
tun.UDPListener, err = udplisterner.Listen("udp", fmt.Sprintf("0.0.0.0:%d", info.PortListen))
tun.UDPListener, err = udplisterner.Listen("udp", net.UDPAddrFromAddrPort(netip.AddrPortFrom(netip.IPv4Unspecified(), info.PortListen)))
if err != nil {
log.Printf("UDP Listener from %s: %s", addr.String(), err.Error())
if tun.TCPListener != nil {
tun.TCPListener.Close()
}
res.BadRequest = true
data, _ := res.Wbytes()
conn.WriteToUDPAddrPort(data, addr)
go server.Send(addr, proto.Response{BadRequest: true})
continue
}
go tun.UDPAccepts() // Make accepts new requests
@ -331,13 +343,11 @@ func (server *Server) Listen(ControllerPort uint16) (err error) {
tun.Authenticated = true
server.Tunnels[addr.String()] = tun
res.AgentInfo = new(proto.AgentInfo)
res.AgentInfo.Protocol = info.Proto
res.AgentInfo.LitenerPort = info.PortListen
res.AgentInfo.AddrPort = addr
data, _ := res.Wbytes()
conn.WriteToUDPAddrPort(data, addr)
AgentInfo := new(proto.AgentInfo)
AgentInfo.Protocol = info.Proto
AgentInfo.LitenerPort = info.PortListen
AgentInfo.AddrPort = addr
go server.Send(addr, proto.Response{AgentInfo: AgentInfo})
continue
}
return