WIP: Update struct decode and encode #2
@ -1,8 +1,6 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -11,8 +9,6 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sandertv/go-raknet"
|
|
||||||
|
|
||||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/pipe"
|
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/pipe"
|
||||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/structcode"
|
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/structcode"
|
||||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
|
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
|
||||||
@ -20,6 +16,7 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ErrCannotConnect error = errors.New("cannot connect to controller")
|
ErrCannotConnect error = errors.New("cannot connect to controller")
|
||||||
|
ErrUnathorized error = errors.New("cannot auth in controller")
|
||||||
)
|
)
|
||||||
|
|
||||||
type NewClient struct {
|
type NewClient struct {
|
||||||
@ -28,17 +25,17 @@ type NewClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
Token [36]byte
|
Token []byte
|
||||||
RemoteAdress []netip.AddrPort
|
RemoteAdress netip.AddrPort
|
||||||
clientsTCP map[string]net.Conn
|
clientsTCP map[string]net.Conn
|
||||||
clientsUDP map[string]net.Conn
|
clientsUDP map[string]net.Conn
|
||||||
NewClient chan NewClient
|
NewClient chan NewClient
|
||||||
|
|
||||||
Conn *raknet.Conn
|
Conn net.Conn
|
||||||
AgentInfo *proto.AgentInfo
|
AgentInfo *proto.AgentInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateClient(Addres []netip.AddrPort, Token [36]byte) (*Client, error) {
|
func CreateClient(Addres netip.AddrPort, Token []byte) (*Client, error) {
|
||||||
cli := &Client{
|
cli := &Client{
|
||||||
Token: Token,
|
Token: Token,
|
||||||
RemoteAdress: Addres,
|
RemoteAdress: Addres,
|
||||||
@ -52,48 +49,28 @@ func CreateClient(Addres []netip.AddrPort, Token [36]byte) (*Client, error) {
|
|||||||
return cli, nil
|
return cli, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) Send(req proto.Request) error {
|
|
||||||
return structcode.NewEncode(client.Conn, req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (client *Client) Setup() error {
|
func (client *Client) Setup() error {
|
||||||
for _, addr := range client.RemoteAdress {
|
var err error
|
||||||
var err error
|
if client.Conn, err = net.DialTCP("tcp", nil, net.TCPAddrFromAddrPort(client.RemoteAdress)); err != nil {
|
||||||
if client.Conn, err = raknet.Dial(addr.String()); err != nil {
|
return err
|
||||||
|
}
|
||||||
|
for attemps := 0; attemps < 18; attemps++ {
|
||||||
|
if err := structcode.NewEncode(client.Conn, proto.Request{AgentAuth: &client.Token}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var res proto.Response
|
||||||
|
if err = structcode.NewDecode(client.Conn, &res); err != nil {
|
||||||
|
return fmt.Errorf("decode status from server, error: %s", err.Error())
|
||||||
|
} else if res.Unauthorized {
|
||||||
|
return ErrUnathorized
|
||||||
|
} else if res.AgentInfo == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
client.Conn.SetReadDeadline(time.Now().Add(time.Second * 5))
|
|
||||||
var auth = proto.AgentAuth(client.Token)
|
|
||||||
for {
|
|
||||||
client.Send(proto.Request{AgentAuth: &auth})
|
|
||||||
|
|
||||||
buff := make([]byte, 1024)
|
client.AgentInfo = res.AgentInfo
|
||||||
n, err := client.Conn.Read(buff)
|
go client.handlers()
|
||||||
if err != nil {
|
return nil
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var res proto.Response
|
|
||||||
if err = structcode.NewDecode(bytes.NewBuffer(buff[:n]), &res); err != nil {
|
|
||||||
if opt, isOpt := err.(*net.OpError); isOpt {
|
|
||||||
if opt.Timeout() {
|
|
||||||
<-time.After(time.Second * 3)
|
|
||||||
client.Send(proto.Request{AgentAuth: &auth})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// return err
|
|
||||||
break
|
|
||||||
} else if res.Unauthorized {
|
|
||||||
return ErrCannotConnect
|
|
||||||
} else if res.AgentInfo == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
client.AgentInfo = res.AgentInfo
|
|
||||||
client.Conn.SetReadDeadline(*new(time.Time)) // clear timeout
|
|
||||||
go client.handlers()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ErrCannotConnect
|
return ErrCannotConnect
|
||||||
}
|
}
|
||||||
@ -105,7 +82,7 @@ type toWr struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t toWr) Write(w []byte) (int, error) {
|
func (t toWr) Write(w []byte) (int, error) {
|
||||||
err := t.tun.Send(proto.Request{
|
err := structcode.NewEncode(t.tun.Conn, proto.Request{
|
||||||
DataTX: &proto.ClientData{
|
DataTX: &proto.ClientData{
|
||||||
Client: proto.Client{
|
Client: proto.Client{
|
||||||
Client: t.To,
|
Client: t.To,
|
||||||
@ -126,16 +103,17 @@ func (tun *Client) GetTargetWrite(Proto uint8, To netip.AddrPort) io.Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) handlers() {
|
func (client *Client) handlers() {
|
||||||
bufioBuff := bufio.NewReader(client.Conn)
|
|
||||||
var lastPing int64 = 0
|
var lastPing int64 = 0
|
||||||
for {
|
for {
|
||||||
if time.Now().UnixMilli()-lastPing > 3_000 {
|
if time.Now().UnixMilli()-lastPing > 3_000 {
|
||||||
var now = time.Now()
|
var req proto.Request
|
||||||
go client.Send(proto.Request{Ping: &now})
|
req.Ping = new(time.Time)
|
||||||
|
*req.Ping = time.Now()
|
||||||
|
go structcode.NewEncode(client.Conn, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
var res proto.Response
|
var res proto.Response
|
||||||
err := structcode.NewDecode(bufioBuff, &res)
|
err := structcode.NewDecode(client.Conn, &res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
if err == proto.ErrInvalidBody {
|
if err == proto.ErrInvalidBody {
|
||||||
@ -154,9 +132,9 @@ func (client *Client) handlers() {
|
|||||||
if res.Unauthorized || res.NotListened {
|
if res.Unauthorized || res.NotListened {
|
||||||
panic(fmt.Errorf("cannot recive requests")) // TODO: Require fix to agent shutdown graced
|
panic(fmt.Errorf("cannot recive requests")) // TODO: Require fix to agent shutdown graced
|
||||||
} else if res.SendAuth {
|
} else if res.SendAuth {
|
||||||
var auth = proto.AgentAuth(client.Token)
|
var auth = client.Token
|
||||||
for {
|
for {
|
||||||
client.Send(proto.Request{AgentAuth: &auth})
|
structcode.NewEncode(client.Conn, proto.Request{AgentAuth: &auth})
|
||||||
var res proto.Response
|
var res proto.Response
|
||||||
if err = structcode.NewDecode(client.Conn, &res); err != nil {
|
if err = structcode.NewDecode(client.Conn, &res); err != nil {
|
||||||
panic(err) // TODO: Require fix to agent shutdown graced
|
panic(err) // TODO: Require fix to agent shutdown graced
|
||||||
|
@ -28,14 +28,6 @@ var CmdClient = cli.Command{
|
|||||||
Required: true,
|
Required: true,
|
||||||
Usage: "agent token",
|
Usage: "agent token",
|
||||||
Aliases: []string{"t"},
|
Aliases: []string{"t"},
|
||||||
Action: func(ctx *cli.Context, s string) error {
|
|
||||||
if _, err := uuid.Parse(s); err == nil {
|
|
||||||
return nil
|
|
||||||
} else if len(s) == len(proto.AgentAuth{}) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("set valid token")
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "dial",
|
Name: "dial",
|
||||||
@ -49,7 +41,8 @@ var CmdClient = cli.Command{
|
|||||||
if addr, err = netip.ParseAddrPort(ctx.String("url")); err != nil {
|
if addr, err = netip.ParseAddrPort(ctx.String("url")); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
client, err := client.CreateClient([]netip.AddrPort{addr}, [36]byte([]byte(ctx.String("token"))))
|
key, _ := uuid.MustParse(ctx.String("token")).MarshalBinary()
|
||||||
|
client, err := client.CreateClient(addr, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,12 @@ type User struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Tun struct {
|
type Tun struct {
|
||||||
ID int64 `xorm:"pk"` // Tunnel ID
|
ID int64 `xorm:"pk"` // Tunnel ID
|
||||||
User int64 `xorm:"notnull"` // Agent ID
|
User int64 `xorm:"notnull"` // Agent ID
|
||||||
Token [36]byte `xorm:"blob notnull unique"` // Tunnel Token
|
Token []byte `xorm:"blob notnull unique"` // Tunnel Token
|
||||||
Proto uint8 `xorm:"default 3"` // Proto accept
|
Proto uint8 `xorm:"default 3"` // Proto accept
|
||||||
TPCListen uint16 // Port listen TCP agent
|
TPCListen uint16 // Port listen TCP agent
|
||||||
UDPListen uint16 // Port listen UDP agent
|
UDPListen uint16 // Port listen UDP agent
|
||||||
}
|
}
|
||||||
|
|
||||||
type Ping struct {
|
type Ping struct {
|
||||||
@ -104,7 +104,7 @@ func (tun *TunCallbcks) BlockedAddr(AddrPort string) bool {
|
|||||||
func (tun *TunCallbcks) AgentPing(agent, server time.Time) {
|
func (tun *TunCallbcks) AgentPing(agent, server time.Time) {
|
||||||
c, _ := tun.XormEngine.Count(Ping{})
|
c, _ := tun.XormEngine.Count(Ping{})
|
||||||
tun.XormEngine.InsertOne(&Ping{
|
tun.XormEngine.InsertOne(&Ping{
|
||||||
ID: c,
|
ID: c,
|
||||||
TunID: tun.tunID,
|
TunID: tun.tunID,
|
||||||
ServerTime: server,
|
ServerTime: server,
|
||||||
AgentTime: agent,
|
AgentTime: agent,
|
||||||
@ -130,7 +130,7 @@ func (tun *TunCallbcks) RegisterTX(client netip.AddrPort, Size int, Proto uint8)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (caller *serverCalls) AgentAuthentication(Token [36]byte) (server.TunnelInfo, error) {
|
func (caller *serverCalls) AgentAuthentication(Token []byte) (server.TunnelInfo, error) {
|
||||||
var tun = Tun{Token: Token}
|
var tun = Tun{Token: Token}
|
||||||
if ok, err := caller.XormEngine.Get(&tun); err != nil || !ok {
|
if ok, err := caller.XormEngine.Get(&tun); err != nil || !ok {
|
||||||
if !ok {
|
if !ok {
|
||||||
|
15
internal/structcode/bytes.go
Normal file
15
internal/structcode/bytes.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package structcode
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Marshal(target any) ([]byte, error) {
|
||||||
|
buff := new(bytes.Buffer)
|
||||||
|
err := NewEncode(buff, target)
|
||||||
|
return buff.Bytes(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Unmarshal(b []byte, target any) error {
|
||||||
|
return NewDecode(bytes.NewReader(b), target)
|
||||||
|
}
|
107
internal/structcode/decode.go
Normal file
107
internal/structcode/decode.go
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package structcode
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decodeRecursive(r io.Reader, reflectValue reflect.Value) error {
|
||||||
|
switch reflectValue.Type().Kind() {
|
||||||
|
case reflect.Interface:
|
||||||
|
case reflect.String:
|
||||||
|
size := int64(0)
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &size); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
buff := make([]byte, size)
|
||||||
|
if _, err := r.Read(buff); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reflectValue.SetString(string(buff))
|
||||||
|
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
data := reflect.New(reflectValue.Type()).Interface()
|
||||||
|
if err := binary.Read(r, binary.BigEndian, data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reflectValue.Set(reflect.ValueOf(data).Elem())
|
||||||
|
case reflect.Struct:
|
||||||
|
if reflectValue.Type().ConvertibleTo(typeofTimer) || reflectValue.Type().Implements(typeofBinUnmarshal) || reflectValue.Type().Implements(typeofTextUnmarshal) {
|
||||||
|
size := int64(0)
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &size); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
buff := make([]byte, size)
|
||||||
|
if _, err := r.Read(buff); err != nil {
|
||||||
|
return err
|
||||||
|
} else if reflectValue.Type().ConvertibleTo(typeofTimer) {
|
||||||
|
ttime := reflectValue.Interface().(time.Time)
|
||||||
|
if err := ttime.UnmarshalBinary(buff); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reflectValue.Set(reflect.ValueOf(ttime))
|
||||||
|
return nil
|
||||||
|
} else if reflectValue.Type().Implements(typeofBinUnmarshal) {
|
||||||
|
data := reflectValue.Interface().(encoding.BinaryUnmarshaler)
|
||||||
|
if err := data.UnmarshalBinary(buff); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reflectValue.Set(reflect.ValueOf(data))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
data := reflectValue.Interface().(encoding.TextUnmarshaler)
|
||||||
|
if err := data.UnmarshalText(buff); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reflectValue.Set(reflect.ValueOf(data))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
typeof := reflectValue.Type()
|
||||||
|
for fieldIndex := range typeof.NumField() {
|
||||||
|
if typeof.Field(fieldIndex).Tag.Get(selectorTagName) == "-" || !typeof.Field(fieldIndex).IsExported() {
|
||||||
|
continue
|
||||||
|
} else if err := decodeRecursive(r, reflectValue.Field(fieldIndex)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Pointer:
|
||||||
|
read := int8(0)
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &read); err != nil {
|
||||||
|
return err
|
||||||
|
} else if read == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
reflectValue.Set(reflect.New(reflectValue.Type().Elem()))
|
||||||
|
return decodeRecursive(r, reflectValue.Elem())
|
||||||
|
case reflect.Array:
|
||||||
|
for arrIndex := range reflectValue.Len() {
|
||||||
|
if err := decodeRecursive(r, reflectValue.Index(arrIndex)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
size := int64(0)
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &size); err != nil {
|
||||||
|
return err
|
||||||
|
} else if reflectValue.Type().Elem().Kind() == typeofByte.Kind() {
|
||||||
|
buff := make([]byte, size)
|
||||||
|
if _, err = r.Read(buff); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reflectValue.SetBytes(buff)
|
||||||
|
} else {
|
||||||
|
typeof := reflectValue.Type().Elem()
|
||||||
|
for range size {
|
||||||
|
newData := reflect.New(typeof)
|
||||||
|
if err := decodeRecursive(r, newData); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reflectValue.Set(reflect.AppendSlice(reflectValue, newData.Elem()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
73
internal/structcode/encode.go
Normal file
73
internal/structcode/encode.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package structcode
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func encodeRecursive(w io.Writer, reflectValue reflect.Value) error {
|
||||||
|
switch reflectValue.Type().Kind() {
|
||||||
|
case reflect.Interface:
|
||||||
|
case reflect.String:
|
||||||
|
str := reflectValue.String()
|
||||||
|
if err := binary.Write(w, binary.BigEndian, int64(len(str))); err != nil {
|
||||||
|
return err
|
||||||
|
} else if _, err := w.Write([]byte(str)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return binary.Write(w, binary.BigEndian, reflectValue.Interface())
|
||||||
|
case reflect.Struct:
|
||||||
|
if reflectValue.Type().Implements(typeofBinMarshal) || reflectValue.Type().Implements(typeofTextMarshal) {
|
||||||
|
var err error
|
||||||
|
var data []byte
|
||||||
|
if reflectValue.Type().Implements(typeofBinMarshal) {
|
||||||
|
data, err = reflectValue.Interface().(encoding.BinaryMarshaler).MarshalBinary()
|
||||||
|
} else {
|
||||||
|
data, err = reflectValue.Interface().(encoding.TextMarshaler).MarshalText()
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
if err = binary.Write(w, binary.BigEndian, int64(len(data))); err == nil {
|
||||||
|
_, err = w.Write(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
typeof := reflectValue.Type()
|
||||||
|
for fieldIndex := range typeof.NumField() {
|
||||||
|
if typeof.Field(fieldIndex).Tag.Get(selectorTagName) == "-" || !typeof.Field(fieldIndex).IsExported() {
|
||||||
|
continue
|
||||||
|
} else if err := encodeRecursive(w, reflectValue.Field(fieldIndex)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Pointer:
|
||||||
|
if reflectValue.IsNil() || reflectValue.IsZero() {
|
||||||
|
return binary.Write(w, binary.BigEndian, int8(0))
|
||||||
|
} else if err := binary.Write(w, binary.BigEndian, int8(1)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return encodeRecursive(w, reflectValue.Elem())
|
||||||
|
case reflect.Array:
|
||||||
|
for arrIndex := range reflectValue.Len() {
|
||||||
|
if err := encodeRecursive(w, reflectValue.Index(arrIndex)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
if err := binary.Write(w, binary.BigEndian, int64(reflectValue.Len())); err != nil {
|
||||||
|
return err
|
||||||
|
} else if reflectValue.Type().Elem().Kind() == typeofByte.Kind() {
|
||||||
|
_, err = w.Write(reflectValue.Bytes())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for sliceIndex := range reflectValue.Len() {
|
||||||
|
if err := encodeRecursive(w, reflectValue.Index(sliceIndex)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,13 +1,3 @@
|
|||||||
package structcode
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Este bloco de codigo server apenas para facilitar minha vida no mundo do go
|
Este bloco de codigo server apenas para facilitar minha vida no mundo do go
|
||||||
Definindo a estrutura de seguinte maneira, os dados estão fortemente ligado as structs go então qualquer merda aqui pode ferra com qualquer versão anterior, então isso não será recomendado para algumas coisa
|
Definindo a estrutura de seguinte maneira, os dados estão fortemente ligado as structs go então qualquer merda aqui pode ferra com qualquer versão anterior, então isso não será recomendado para algumas coisa
|
||||||
@ -16,227 +6,54 @@ Os pointers serão verificados se são nil's para idicar para a sereliazação e
|
|||||||
|
|
||||||
*any -> int8(0|1) + data...
|
*any -> int8(0|1) + data...
|
||||||
[]any -> int64 (Size) + data...
|
[]any -> int64 (Size) + data...
|
||||||
map[any]any -> int64 (Size) + (key + data)...
|
|
||||||
[]bytes Or String -> Int64 (Size) + []bytes
|
[]bytes Or String -> Int64 (Size) + []bytes
|
||||||
|
map[any]any -> int64 (Size) + (key + data)...
|
||||||
int64, uint64 -> int64
|
int64, uint64 -> int64
|
||||||
int32, uint32 -> int32
|
int32, uint32 -> int32
|
||||||
int16, uint16 -> int16
|
int16, uint16 -> int16
|
||||||
int8, uint8 -> int8
|
int8, uint8 -> int8
|
||||||
bool -> int8(0|1)
|
bool -> int8(0|1)
|
||||||
*/
|
*/
|
||||||
|
package structcode
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
const selectorTagName = "ser"
|
const selectorTagName = "ser"
|
||||||
|
|
||||||
var typeofBytes = reflect.TypeOf([]byte{})
|
var (
|
||||||
|
typeofTimer = reflect.TypeFor[time.Time]()
|
||||||
|
typeofBytes = reflect.TypeOf([]byte{})
|
||||||
|
typeofByte = typeofBytes.Elem()
|
||||||
|
|
||||||
|
typeofBinMarshal = reflect.TypeFor[encoding.BinaryMarshaler]()
|
||||||
|
typeofTextMarshal = reflect.TypeFor[encoding.TextMarshaler]()
|
||||||
|
typeofBinUnmarshal = reflect.TypeFor[encoding.BinaryUnmarshaler]()
|
||||||
|
typeofTextUnmarshal = reflect.TypeFor[encoding.TextUnmarshaler]()
|
||||||
|
)
|
||||||
|
|
||||||
func NewEncode(w io.Writer, target any) error {
|
func NewEncode(w io.Writer, target any) error {
|
||||||
if target == nil {
|
if target == nil {
|
||||||
return binary.Write(w, binary.BigEndian, int8(0))
|
return nil
|
||||||
}
|
|
||||||
targetReflect := reflect.ValueOf(target)
|
|
||||||
switch targetReflect.Type().Kind() {
|
|
||||||
case reflect.Array, reflect.Slice:
|
|
||||||
if err := binary.Write(w, binary.BigEndian, int64(targetReflect.Len())); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch targetReflect.Type().Elem().Kind() {
|
|
||||||
case typeofBytes.Elem().Kind(): // Check if the element is a byte type
|
|
||||||
buff := make([]byte, targetReflect.Len())
|
|
||||||
for i := range targetReflect.Len() {
|
|
||||||
buff[i] = targetReflect.Index(i).Interface().(byte)
|
|
||||||
}
|
|
||||||
_, err := w.Write(buff)
|
|
||||||
return err
|
|
||||||
default:
|
|
||||||
for i := range targetReflect.Len() {
|
|
||||||
if err := NewEncode(w, targetReflect.Index(i).Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Pointer:
|
|
||||||
return NewEncode(w, targetReflect.Elem().Interface()) // Ignore point and reencode
|
|
||||||
case reflect.Struct:
|
|
||||||
BinaryMarshaler, isBinaryMarshaler := targetReflect.Interface().(encoding.BinaryMarshaler)
|
|
||||||
TextMarshaler, isTextMarshaler := targetReflect.Interface().(encoding.TextMarshaler)
|
|
||||||
if isBinaryMarshaler || isTextMarshaler {
|
|
||||||
var data []byte
|
|
||||||
var err error
|
|
||||||
if isBinaryMarshaler {
|
|
||||||
data, err = BinaryMarshaler.MarshalBinary()
|
|
||||||
} else {
|
|
||||||
data, err = TextMarshaler.MarshalText()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return NewEncode(w, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
typeof := targetReflect.Type()
|
|
||||||
for i := range targetReflect.NumField() {
|
|
||||||
if tag := typeof.Field(i).Tag.Get(selectorTagName); tag == "-" || !targetReflect.Field(i).IsValid() {
|
|
||||||
continue
|
|
||||||
} else if targetReflect.Field(i).Type().Kind() == reflect.Pointer {
|
|
||||||
if targetReflect.IsZero() || !targetReflect.CanInterface() || targetReflect.Field(i).IsNil() {
|
|
||||||
return binary.Write(w, binary.BigEndian, int8(0))
|
|
||||||
} else if err := binary.Write(w, binary.BigEndian, int8(1)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if err := NewEncode(w, targetReflect.Field(i).Elem().Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := NewEncode(w, targetReflect.Field(i).Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.String:
|
|
||||||
if err := binary.Write(w, binary.BigEndian, int64(targetReflect.Len())); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err := w.Write([]byte(targetReflect.String()))
|
|
||||||
return err
|
|
||||||
case reflect.Bool:
|
|
||||||
if targetReflect.Bool() {
|
|
||||||
return binary.Write(w, binary.BigEndian, int8(1))
|
|
||||||
}
|
|
||||||
return binary.Write(w, binary.BigEndian, int8(0))
|
|
||||||
case reflect.Uint8, reflect.Int8, reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64, reflect.Float32, reflect.Float64:
|
|
||||||
return binary.Write(w, binary.BigEndian, target)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("set valid struct or array/slice, or any primary values")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
reflectValue := reflect.ValueOf(target)
|
||||||
|
if reflectValue.Type().Kind() == reflect.Pointer {
|
||||||
|
reflectValue = reflectValue.Elem()
|
||||||
|
}
|
||||||
|
return encodeRecursive(w, reflectValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDecode(r io.Reader, target any) error {
|
func NewDecode(r io.Reader, target any) error {
|
||||||
if target == nil {
|
if target == nil {
|
||||||
return binary.Read(r, binary.BigEndian, int8(0))
|
return fmt.Errorf("set target, not nil")
|
||||||
|
} else if reflect.TypeOf(target).Kind() != reflect.Pointer {
|
||||||
|
return fmt.Errorf("set pointer to struct")
|
||||||
}
|
}
|
||||||
targetReflect := reflect.ValueOf(target).Elem()
|
return decodeRecursive(r, reflect.ValueOf(target).Elem())
|
||||||
switch targetReflect.Type().Kind() {
|
|
||||||
case reflect.Slice:
|
|
||||||
var size int64
|
|
||||||
if err := binary.Read(r, binary.BigEndian, &size); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch targetReflect.Type().Elem().Kind() {
|
|
||||||
case typeofBytes.Elem().Kind():
|
|
||||||
buff := make([]byte, size)
|
|
||||||
if _, err := r.Read(buff); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
targetReflect.SetBytes(buff)
|
|
||||||
default:
|
|
||||||
for i := range int(size) {
|
|
||||||
data := reflect.New(targetReflect.Field(i).Type().Elem()).Interface()
|
|
||||||
if err := NewDecode(r, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
targetReflect.Set(reflect.AppendSlice(targetReflect, reflect.ValueOf(data)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
case reflect.Array:
|
|
||||||
var size int64
|
|
||||||
if err := binary.Read(r, binary.BigEndian, &size); err != nil {
|
|
||||||
return err
|
|
||||||
} else if size != int64(targetReflect.Len()) {
|
|
||||||
return fmt.Errorf("size mismatch: expected %d, got %d", targetReflect.Len(), size)
|
|
||||||
}
|
|
||||||
switch targetReflect.Type().Elem().Kind() {
|
|
||||||
case typeofBytes.Elem().Kind(): // Check if the element is a byte type
|
|
||||||
buff := make([]byte, size)
|
|
||||||
if _, err := r.Read(buff); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for i, data := range buff {
|
|
||||||
targetReflect.Index(i).Set(reflect.ValueOf(data))
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
for i := 0; i < int(size); i++ {
|
|
||||||
elem := reflect.New(targetReflect.Type().Elem()).Interface()
|
|
||||||
if err := NewDecode(r, elem); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
targetReflect.Index(i).Set(reflect.ValueOf(elem).Elem())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
case reflect.String:
|
|
||||||
var err error
|
|
||||||
var size int64
|
|
||||||
if err = binary.Read(r, binary.BigEndian, &size); err == nil {
|
|
||||||
buff := make([]byte, size)
|
|
||||||
if _, err = r.Read(buff); err == nil {
|
|
||||||
targetReflect.SetString(string(buff))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
case reflect.Bool:
|
|
||||||
var boolInt int8
|
|
||||||
if err := binary.Read(r, binary.BigEndian, &boolInt); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
targetReflect.SetBool(boolInt == 1)
|
|
||||||
case reflect.Uint8, reflect.Int8, reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64, reflect.Float32, reflect.Float64:
|
|
||||||
return binary.Read(r, binary.BigEndian, target)
|
|
||||||
case reflect.Struct:
|
|
||||||
BinaryMarshaler, isBinaryMarshaler := target.(encoding.BinaryUnmarshaler)
|
|
||||||
TextMarshaler, isTextMarshaler := target.(encoding.TextUnmarshaler)
|
|
||||||
if isBinaryMarshaler || isTextMarshaler {
|
|
||||||
var data []byte
|
|
||||||
var err error
|
|
||||||
if err = NewDecode(r, &data); err != nil {
|
|
||||||
return err
|
|
||||||
} else if isBinaryMarshaler {
|
|
||||||
return BinaryMarshaler.UnmarshalBinary(data)
|
|
||||||
}
|
|
||||||
return TextMarshaler.UnmarshalText(data)
|
|
||||||
}
|
|
||||||
for i := range targetReflect.NumField() {
|
|
||||||
if tag := targetReflect.Type().Field(i).Tag.Get(selectorTagName); tag == "-" || !targetReflect.Field(i).CanSet() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if targetReflect.Field(i).Type().Kind() == reflect.Pointer {
|
|
||||||
var ok bool
|
|
||||||
if err := NewDecode(r, &ok); err != nil {
|
|
||||||
return err
|
|
||||||
} else if ok {
|
|
||||||
data := reflect.New(targetReflect.Field(i).Type().Elem()).Interface()
|
|
||||||
if err := NewDecode(r, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
targetReflect.Field(i).Set(reflect.ValueOf(data))
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
data := reflect.New(targetReflect.Field(i).Type()).Interface()
|
|
||||||
if err := NewDecode(r, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
targetReflect.Field(i).Set(reflect.ValueOf(data).Elem())
|
|
||||||
}
|
|
||||||
case reflect.Interface:
|
|
||||||
BinaryMarshaler, isBinaryMarshaler := target.(encoding.BinaryUnmarshaler)
|
|
||||||
TextMarshaler, isTextMarshaler := target.(encoding.TextUnmarshaler)
|
|
||||||
if isBinaryMarshaler || isTextMarshaler {
|
|
||||||
var data []byte
|
|
||||||
var err error
|
|
||||||
if err = NewDecode(r, &data); err != nil {
|
|
||||||
return err
|
|
||||||
} else if isBinaryMarshaler {
|
|
||||||
return BinaryMarshaler.UnmarshalBinary(data)
|
|
||||||
}
|
|
||||||
return TextMarshaler.UnmarshalText(data)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("set valid struct or array/slice, or any primary values, kind %s", targetReflect.Type().Kind())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package structcode
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -12,58 +13,40 @@ type structTest struct {
|
|||||||
Int16 int16
|
Int16 int16
|
||||||
Int32 int32
|
Int32 int32
|
||||||
Int64 int64
|
Int64 int64
|
||||||
|
Date time.Time
|
||||||
|
|
||||||
Bytes []byte
|
Bytes []byte
|
||||||
ArrayBytes [4]byte
|
ArrayBytes [4]byte
|
||||||
|
|
||||||
Date time.Time
|
|
||||||
Pointer *structTest
|
Pointer *structTest
|
||||||
Pointer2 any
|
Pointer2 any
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSerelelize(t *testing.T) {
|
func TestDeSerelelize(t *testing.T) {
|
||||||
var testData structTest
|
|
||||||
testData.Text = "Golang is best"
|
|
||||||
testData.Int8 = 2
|
|
||||||
testData.Int16 = 200
|
|
||||||
testData.Int32 = 1_000_000
|
|
||||||
testData.Int64 = 1024 * 12 * 12
|
|
||||||
testData.Bytes = []byte("google maintener go")
|
|
||||||
testData.ArrayBytes = [4]byte{0, 1, 1, 1}
|
|
||||||
testData.Date = time.Now()
|
|
||||||
testData.Pointer = &structTest{
|
|
||||||
Text: "Golang",
|
|
||||||
}
|
|
||||||
|
|
||||||
buff := new(bytes.Buffer)
|
|
||||||
if err := NewEncode(buff, &testData); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeserelelize(t *testing.T) {
|
|
||||||
var testData structTest
|
|
||||||
testData.Text = "Golang is best"
|
|
||||||
testData.Int8 = 2
|
|
||||||
testData.Int16 = 200
|
|
||||||
testData.Int32 = 1_000_000
|
|
||||||
testData.Int64 = 1024 * 12 * 12
|
|
||||||
testData.Bytes = []byte("google maintener go")
|
|
||||||
testData.ArrayBytes = [4]byte{0, 1, 1, 1}
|
|
||||||
testData.Date = time.Now()
|
|
||||||
testData.Pointer = &structTest{
|
|
||||||
Text: "Golang",
|
|
||||||
}
|
|
||||||
|
|
||||||
buff := new(bytes.Buffer)
|
|
||||||
if err := NewEncode(buff, &testData); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var decodeTest structTest
|
var decodeTest structTest
|
||||||
|
var testData structTest
|
||||||
|
testData.Text = "Golang is best"
|
||||||
|
testData.Int8 = 2
|
||||||
|
testData.Int16 = 200
|
||||||
|
testData.Int32 = 1_000_000
|
||||||
|
testData.Int64 = 1024 * 12 * 12
|
||||||
|
testData.Bytes = []byte("google maintener go")
|
||||||
|
testData.ArrayBytes = [4]byte{0, 1, 1, 1}
|
||||||
|
testData.Date = time.Now()
|
||||||
|
testData.Pointer = &structTest{
|
||||||
|
Text: "Golang",
|
||||||
|
}
|
||||||
|
|
||||||
|
buff := new(bytes.Buffer)
|
||||||
|
if err := NewEncode(buff, testData); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Log(buff.Bytes())
|
||||||
if err := NewDecode(buff, &decodeTest); err != nil {
|
if err := NewDecode(buff, &decodeTest); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
d, _ := json.MarshalIndent(decodeTest, "", " ")
|
||||||
|
t.Log(string(d))
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ProtoBoth uint8 = iota // TCP+UDP Protocol
|
ProtoBoth uint8 = iota // TCP+UDP Protocol
|
||||||
ProtoTCP uint8 = iota // TCP Protocol
|
ProtoTCP // TCP Protocol
|
||||||
ProtoUDP uint8 = iota // UDP Protocol
|
ProtoUDP // UDP Protocol
|
||||||
|
|
||||||
DataSize uint64 = 10_000 // Default listener data recive and send
|
DataSize uint64 = 10_000 // Default listener data recive and send
|
||||||
PacketSize uint64 = 800 // Packet to without data only requests and response headers
|
PacketSize uint64 = 800 // Packet to without data only requests and response headers
|
||||||
|
@ -5,22 +5,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
var ErrProtoBothNoSupported error = errors.New("protocol UDP+TCP not supported currently")
|
||||||
ReqAuth uint64 = iota // Request Agent Auth
|
|
||||||
ReqPing uint64 = iota // Time ping
|
|
||||||
ReqCloseClient uint64 = iota // Close client
|
|
||||||
ReqClientData uint64 = iota // Send data
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrProtoBothNoSupported error = errors.New("protocol UDP+TCP not supported currently")
|
|
||||||
)
|
|
||||||
|
|
||||||
type AgentAuth [36]byte
|
|
||||||
|
|
||||||
// Send request to agent and wait response
|
// Send request to agent and wait response
|
||||||
type Request struct {
|
type Request struct {
|
||||||
AgentAuth *AgentAuth `json:",omitempty"` // Send agent authentication to controller
|
AgentAuth *[]byte `json:",omitempty"` // Send agent authentication to controller
|
||||||
Ping *time.Time `json:",omitempty"` // Send ping time to controller in unix milliseconds
|
Ping *time.Time `json:",omitempty"` // Send ping time to controller in unix milliseconds
|
||||||
ClientClose *Client `json:",omitempty"` // Close client in controller
|
ClientClose *Client `json:",omitempty"` // Close client in controller
|
||||||
DataTX *ClientData `json:",omitempty"` // Recive data from agent
|
DataTX *ClientData `json:",omitempty"` // Recive data from agent
|
||||||
|
@ -5,17 +5,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
ResUnauthorized uint64 = iota // Request not processed and ignored
|
|
||||||
ResBadRequest uint64 = iota // Request cannot process and ignored
|
|
||||||
ResCloseClient uint64 = iota // Controller closed connection
|
|
||||||
ResClientData uint64 = iota // Controller accepted data
|
|
||||||
ResSendAuth uint64 = iota // Send token to controller
|
|
||||||
ResAgentInfo uint64 = iota // Agent info
|
|
||||||
ResPong uint64 = iota // Ping response
|
|
||||||
ResNotListening uint64 = iota // Resize buffer size
|
|
||||||
)
|
|
||||||
|
|
||||||
type AgentInfo struct {
|
type AgentInfo struct {
|
||||||
Protocol uint8 // Proto supported (proto.ProtoTCP, proto.ProtoUDP or proto.ProtoBoth)
|
Protocol uint8 // Proto supported (proto.ProtoTCP, proto.ProtoUDP or proto.ProtoBoth)
|
||||||
UDPPort, TCPPort uint16 // Controller port listened
|
UDPPort, TCPPort uint16 // Controller port listened
|
||||||
|
@ -3,9 +3,10 @@ package server
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"github.com/sandertv/go-raknet"
|
"os"
|
||||||
|
|
||||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/structcode"
|
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/structcode"
|
||||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
|
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
|
||||||
@ -17,18 +18,18 @@ var (
|
|||||||
|
|
||||||
type ServerCall interface {
|
type ServerCall interface {
|
||||||
// Authenticate agents
|
// Authenticate agents
|
||||||
AgentAuthentication(Token [36]byte) (TunnelInfo, error)
|
AgentAuthentication(Token []byte) (TunnelInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
ControllConn *raknet.Listener
|
ControllConn net.Listener
|
||||||
ProcessError chan error
|
ProcessError chan error
|
||||||
ControlCalls ServerCall
|
ControlCalls ServerCall
|
||||||
Agents map[string]*Tunnel
|
Agents map[string]*Tunnel
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewController(calls ServerCall, local string) (*Server, error) {
|
func NewController(calls ServerCall, local string) (*Server, error) {
|
||||||
conn, err := raknet.Listen(local)
|
conn, err := net.ListenTCP("tcp", net.TCPAddrFromAddrPort(netip.MustParseAddrPort(local)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -50,24 +51,26 @@ func (controller *Server) handler() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
fmt.Printf("New Client %q\n", conn.RemoteAddr())
|
||||||
go controller.handlerConn(conn)
|
go controller.handlerConn(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (controller *Server) handlerConn(conn net.Conn) {
|
func (controller *Server) handlerConn(conn net.Conn) {
|
||||||
defer conn.Close() // End agent accepted
|
defer conn.Close()
|
||||||
|
var tunnelInfo TunnelInfo
|
||||||
|
var err error
|
||||||
|
var req proto.Request
|
||||||
for {
|
for {
|
||||||
var tunnelInfo TunnelInfo
|
|
||||||
var err error
|
|
||||||
var req proto.Request
|
|
||||||
if err = structcode.NewDecode(conn, &req); err != nil {
|
if err = structcode.NewDecode(conn, &req); err != nil {
|
||||||
|
if err != io.EOF {
|
||||||
|
fmt.Fprintf(os.Stderr, "Auth decode error: %s\n", err.Error())
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
} else if req.AgentAuth == nil {
|
||||||
|
|
||||||
if req.AgentAuth == nil {
|
|
||||||
structcode.NewEncode(conn, proto.Response{SendAuth: true})
|
structcode.NewEncode(conn, proto.Response{SendAuth: true})
|
||||||
continue
|
continue
|
||||||
} else if tunnelInfo, err = controller.ControlCalls.AgentAuthentication([36]byte(req.AgentAuth[:])); err != nil {
|
} else if tunnelInfo, err = controller.ControlCalls.AgentAuthentication(*req.AgentAuth); err != nil {
|
||||||
if err == ErrAuthAgentFail {
|
if err == ErrAuthAgentFail {
|
||||||
structcode.NewEncode(conn, proto.Response{Unauthorized: true})
|
structcode.NewEncode(conn, proto.Response{Unauthorized: true})
|
||||||
return
|
return
|
||||||
@ -75,17 +78,17 @@ func (controller *Server) handlerConn(conn net.Conn) {
|
|||||||
structcode.NewEncode(conn, proto.Response{BadRequest: true})
|
structcode.NewEncode(conn, proto.Response{BadRequest: true})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close current tunnel
|
|
||||||
if tun, ok := controller.Agents[string(req.AgentAuth[:])]; ok {
|
|
||||||
fmt.Println("closing old tunnel")
|
|
||||||
tun.Close() // Close connection
|
|
||||||
}
|
|
||||||
|
|
||||||
var tun = &Tunnel{RootConn: conn, TunInfo: tunnelInfo, UDPClients: make(map[string]net.Conn), TCPClients: make(map[string]net.Conn)}
|
|
||||||
controller.Agents[string(req.AgentAuth[:])] = tun
|
|
||||||
tun.Setup()
|
|
||||||
delete(controller.Agents, string(req.AgentAuth[:]))
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close current tunnel
|
||||||
|
if tun, ok := controller.Agents[string(*req.AgentAuth)]; ok {
|
||||||
|
fmt.Println("closing old tunnel")
|
||||||
|
tun.Close() // Close connection
|
||||||
|
}
|
||||||
|
|
||||||
|
var tun = &Tunnel{RootConn: conn, TunInfo: tunnelInfo, UDPClients: make(map[string]net.Conn), TCPClients: make(map[string]net.Conn)}
|
||||||
|
controller.Agents[string(*req.AgentAuth)] = tun
|
||||||
|
tun.Setup()
|
||||||
|
delete(controller.Agents, string(*req.AgentAuth))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
@ -62,12 +61,7 @@ func (tun *Tunnel) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tun *Tunnel) send(res proto.Response) error {
|
func (tun *Tunnel) send(res proto.Response) error {
|
||||||
buff := new(bytes.Buffer)
|
return structcode.NewEncode(tun.RootConn, res)
|
||||||
if err := structcode.NewEncode(buff, res); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err := tun.RootConn.Write(buff.Bytes())
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type toWr struct {
|
type toWr struct {
|
||||||
|
Reference in New Issue
Block a user