Add cli
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
*.exe
|
||||
*.db
|
||||
*.log
|
@ -2,8 +2,10 @@ package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/netip"
|
||||
"time"
|
||||
@ -72,6 +74,8 @@ func (client Client) Recive() (res *proto.Response, err error) {
|
||||
if err = res.Reader(bytes.NewBuffer(recBuff[:n])); err != nil {
|
||||
return
|
||||
}
|
||||
d,_:=json.Marshal(res)
|
||||
log.Println(string(d))
|
||||
return
|
||||
}
|
||||
|
||||
|
85
cmd/client/client.go
Normal file
85
cmd/client/client.go
Normal file
@ -0,0 +1,85 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/urfave/cli/v2"
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/client"
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
|
||||
)
|
||||
|
||||
var CmdClient = cli.Command{
|
||||
Name: "client",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "connect to controller server and bind new requests to local port",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "url",
|
||||
Required: true,
|
||||
Aliases: []string{"host", "u"},
|
||||
Usage: `host string to connect to controller, example: "example.com:5522"`,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "token",
|
||||
Required: true,
|
||||
Usage: "agent token",
|
||||
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{
|
||||
Name: "dial",
|
||||
Required: true,
|
||||
Usage: `dial connection, default is "localhost:80"`,
|
||||
Aliases: []string{"d"},
|
||||
},
|
||||
},
|
||||
Action: func(ctx *cli.Context) (err error) {
|
||||
var addr netip.AddrPort
|
||||
if addr, err = netip.ParseAddrPort(ctx.String("url")); err != nil {
|
||||
return
|
||||
}
|
||||
client := client.NewClient(addr, [36]byte([]byte(ctx.String("token"))))
|
||||
var info *proto.AgentInfo
|
||||
if info, err = client.Dial(); err != nil {
|
||||
return err
|
||||
}
|
||||
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 {
|
||||
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)
|
||||
}()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
73
cmd/main.go
73
cmd/main.go
@ -2,65 +2,26 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/client"
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/server"
|
||||
"github.com/urfave/cli/v2"
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/cmd/client"
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/cmd/server"
|
||||
)
|
||||
|
||||
var description string = `pproxit is a proxy that allows anyone to host a server without port forwarding. We use tunneling. Only the server needs to run the program, not every player!`
|
||||
func main() {
|
||||
cctrl := make(chan os.Signal, 1)
|
||||
signal.Notify(cctrl, os.Interrupt)
|
||||
|
||||
var port uint16 = 5522
|
||||
server := server.NewServer(nil)
|
||||
go server.Listen(port)
|
||||
time.Sleep(time.Second)
|
||||
fmt.Printf("Server listen on :%d\n", port)
|
||||
|
||||
go func() {
|
||||
client := client.NewClient(netip.AddrPortFrom(netip.IPv6Loopback(), port), [36]byte{})
|
||||
info, err := client.Dial()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go client.Backgroud() // Recive data
|
||||
fmt.Printf("Client remote: %s\n", client.Conn.RemoteAddr().String())
|
||||
fmt.Printf("Client Listened on %d\n", info.LitenerPort)
|
||||
|
||||
localConnect := "127.0.0.1:5201"
|
||||
for {
|
||||
select {
|
||||
case tcp := <-client.NewTCPClient:
|
||||
go func() {
|
||||
conn, err := net.Dial("tcp", localConnect)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
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 {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
go io.Copy(conn, udp)
|
||||
go io.Copy(udp, conn)
|
||||
}()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
<-cctrl
|
||||
fmt.Println("Closing controller")
|
||||
app := cli.NewApp()
|
||||
app.Name = "pproxit"
|
||||
app.Description = description
|
||||
app.EnableBashCompletion = true
|
||||
app.HideHelpCommand = true
|
||||
app.Commands = []*cli.Command{
|
||||
&server.CmdServer,
|
||||
&client.CmdClient,
|
||||
}
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
fmt.Fprintf(app.ErrWriter, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
42
cmd/server/server.go
Normal file
42
cmd/server/server.go
Normal file
@ -0,0 +1,42 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/server"
|
||||
)
|
||||
|
||||
var CmdServer = cli.Command{
|
||||
Name: "server",
|
||||
Usage: "Create local server and open controller ports",
|
||||
Aliases: []string{"s"},
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{
|
||||
Name: "port",
|
||||
Value: 5522,
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Set controller port to watcher UDP requests",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "log",
|
||||
Value: "silence",
|
||||
Aliases: []string{"l"},
|
||||
Usage: "set server log: silence, 0 or verbose, 2",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "db",
|
||||
Value: "./pproxit.db",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "sqlite file path",
|
||||
},
|
||||
},
|
||||
Action: func(ctx *cli.Context) error {
|
||||
calls, err := NewCall(ctx.String("db"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pproxitServer := server.NewServer(calls)
|
||||
pproxitServer.RequestBuffer = proto.PacketDataSize * 2 // More initial buffer request
|
||||
return pproxitServer.Listen(uint16(ctx.Int("port")))
|
||||
},
|
||||
}
|
57
cmd/server/servercall.go
Normal file
57
cmd/server/servercall.go
Normal file
@ -0,0 +1,57 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/server"
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/names"
|
||||
)
|
||||
|
||||
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
|
||||
FullName string `xorm:"text notnull notnull 'name'"` // Real name for user
|
||||
AccountStatus int8 `xorm:"BIT notnull 'status'"` // Account Status
|
||||
CreateAt time.Time `xorm:"created"` // Create date
|
||||
UpdateAt time.Time `xorm:"updated"` // Update date
|
||||
}
|
||||
|
||||
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{})
|
||||
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 {
|
||||
if !ok {
|
||||
return server.TunnelInfo{}, server.ErrNoAgent
|
||||
}
|
||||
return server.TunnelInfo{}, err
|
||||
}
|
||||
return server.TunnelInfo{
|
||||
PortListen: tun.PortListen,
|
||||
Proto: tun.Proto,
|
||||
}, nil
|
||||
}
|
32
go.mod
32
go.mod
@ -1,3 +1,35 @@
|
||||
module sirherobrine23.org/Minecraft-Server/go-pproxit
|
||||
|
||||
go 1.22.3
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/urfave/cli/v2 v2.27.2
|
||||
modernc.org/sqlite v1.30.0
|
||||
xorm.io/xorm v1.3.9
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/goccy/go-json v0.8.1 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
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/sys v0.19.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||
modernc.org/libc v1.50.9 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
|
||||
)
|
||||
|
113
go.sum
113
go.sum
@ -0,0 +1,113 @@
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/goccy/go-json v0.8.1 h1:4/Wjm0JIJaTDm8K1KcGrLHJoa8EsJ13YWeX+6Kfq6uI=
|
||||
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
|
||||
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
|
||||
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/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=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
modernc.org/cc/v4 v4.21.2 h1:dycHFB/jDc3IyacKipCNSDrjIC0Lm1hyoWOZTRR20Lk=
|
||||
modernc.org/cc/v4 v4.21.2/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v4 v4.17.8 h1:yyWBf2ipA0Y9GGz/MmCmi3EFpKgeS7ICrAFes+suEbs=
|
||||
modernc.org/ccgo/v4 v4.17.8/go.mod h1:buJnJ6Fn0tyAdP/dqePbrrvLyr6qslFfTbFrCuaYvtA=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
||||
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.50.9 h1:hIWf1uz55lorXQhfoEoezdUHjxzuO6ceshET/yWjSjk=
|
||||
modernc.org/libc v1.50.9/go.mod h1:15P6ublJ9FJR8YQCGy8DeQ2Uwur7iW9Hserr/T3OFZE=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.30.0 h1:8YhPUs/HTnlEgErn/jSYQTwHN/ex8CjHHjg+K9iG7LM=
|
||||
modernc.org/sqlite v1.30.0/go.mod h1:cgkTARJ9ugeXSNaLBPK3CqbOe7Ec7ZhWPoMFGldEYEw=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 h1:bvLlAPW1ZMTWA32LuZMBEGHAUOcATZjzHcotf3SWweM=
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/xorm v1.3.9 h1:TUovzS0ko+IQ1XnNLfs5dqK1cJl1H5uHpWbWqAQ04nU=
|
||||
xorm.io/xorm v1.3.9/go.mod h1:LsCCffeeYp63ssk0pKumP6l96WZcHix7ChpurcLNuMw=
|
||||
|
@ -1,91 +1,140 @@
|
||||
package udplisterner
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sync"
|
||||
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/internal/pipe"
|
||||
)
|
||||
|
||||
type clientInfo struct {
|
||||
WriteSize int // Size to Write
|
||||
Conn net.Conn // Client Pipe
|
||||
}
|
||||
|
||||
type UdpListerner struct {
|
||||
MTU func() uint64
|
||||
udpConn *net.UDPConn
|
||||
clients map[string]net.Conn
|
||||
newClient chan any
|
||||
readSize int // UDPConn size to reader
|
||||
udpConn *net.UDPConn // UDPConn root
|
||||
clientInfo *sync.Map // Storage *clientInfo
|
||||
newClient chan any // Accept connection channel or error
|
||||
}
|
||||
|
||||
func (udpConn UdpListerner) Close() error {
|
||||
for addr, cli := range udpConn.clients {
|
||||
cli.Close()
|
||||
delete(udpConn.clients, addr)
|
||||
func ListenUDPAddr(network string, address *net.UDPAddr) (UdpListen *UdpListerner, err error) {
|
||||
UdpListen = new(UdpListerner)
|
||||
if UdpListen.udpConn, err = net.ListenUDP(network, address); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
close(udpConn.newClient)
|
||||
return udpConn.udpConn.Close()
|
||||
UdpListen.readSize = 1024 // Initial buffer reader
|
||||
UdpListen.newClient = make(chan any)
|
||||
UdpListen.clientInfo = new(sync.Map)
|
||||
go UdpListen.backgroud() // Recive new requests
|
||||
return UdpListen, nil
|
||||
}
|
||||
|
||||
func (udpConn UdpListerner) Addr() net.Addr {
|
||||
return udpConn.udpConn.LocalAddr()
|
||||
func ListenAddrPort(network string, address netip.AddrPort) (*UdpListerner, error) {
|
||||
return ListenUDPAddr(network, net.UDPAddrFromAddrPort(address))
|
||||
}
|
||||
|
||||
func (udpConn UdpListerner) Accept() (net.Conn, error) {
|
||||
if data, ok := <-udpConn.newClient; ok {
|
||||
if err, isErr := data.(error); isErr {
|
||||
func Listen(network, address string) (*UdpListerner, error) {
|
||||
local, err := net.ResolveUDPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ListenUDPAddr(network, local)
|
||||
}
|
||||
|
||||
// Close clients and close client channel
|
||||
func (udp *UdpListerner) Close() error {
|
||||
close(udp.newClient) // Close channel to new accepts
|
||||
var toDelete map[string]*clientInfo
|
||||
udp.clientInfo.Range(func(key, value any) bool {
|
||||
toDelete[key.(string)] = value.(*clientInfo)
|
||||
return true
|
||||
})
|
||||
for key, info := range toDelete {
|
||||
info.Conn.Close()
|
||||
udp.clientInfo.Delete(key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (udp *UdpListerner) CloseClient(clientAddrPort string) {
|
||||
client, ok := udp.clientInfo.LoadAndDelete(clientAddrPort)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
agent := client.(clientInfo)
|
||||
agent.Conn.Close()
|
||||
}
|
||||
|
||||
func (udp UdpListerner) Addr() net.Addr {
|
||||
if udp.udpConn == nil {
|
||||
return &net.UDPAddr{}
|
||||
}
|
||||
return udp.udpConn.LocalAddr()
|
||||
}
|
||||
|
||||
func (udp UdpListerner) Accept() (net.Conn, error) {
|
||||
if conn, ok := <-udp.newClient; ok {
|
||||
if err, isErr := conn.(error); isErr {
|
||||
return nil, err
|
||||
}
|
||||
return data.(net.Conn), nil
|
||||
return conn.(*clientInfo).Conn, nil
|
||||
}
|
||||
return nil, net.ErrClosed
|
||||
}
|
||||
|
||||
func (udp *UdpListerner) backgroud() {
|
||||
for {
|
||||
buffer := make([]byte, udp.MTU())
|
||||
n, from, err := udp.udpConn.ReadFromUDP(buffer)
|
||||
readBuffer := make([]byte, udp.readSize) // Make reader size
|
||||
n, from, err := udp.udpConn.ReadFromUDP(readBuffer)
|
||||
if err != nil {
|
||||
udp.newClient <- err // Send to accept error
|
||||
return
|
||||
} else if toListener, exist := udp.clients[from.String()]; exist {
|
||||
// Send in backgroud
|
||||
go func() {
|
||||
if _, err := toListener.Write(buffer[:n]); err != nil {
|
||||
toListener.Close()
|
||||
delete(udp.clients, from.String()) // Remove from clients
|
||||
}
|
||||
}()
|
||||
continue // Call next request
|
||||
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
||||
udp.Close() // Close clients
|
||||
break
|
||||
}
|
||||
continue
|
||||
} else if n-udp.readSize == 0 {
|
||||
udp.readSize += 500 // Add 500 Bytes to reader
|
||||
}
|
||||
|
||||
// Create new connection and send to accept
|
||||
toClinet, toListener := pipe.CreatePipe(udp.udpConn.LocalAddr(), from)
|
||||
udp.clients[from.String()] = toListener // Set listerner clients
|
||||
udp.newClient <- toClinet // return to accept
|
||||
|
||||
// Check if exists current connection
|
||||
if client, ok := udp.clientInfo.Load(from.String()); ok {
|
||||
toListener := client.(*clientInfo)
|
||||
toListener.Conn.Write(readBuffer[:n]) // n size from Buffer to client
|
||||
continue // Contine loop
|
||||
}
|
||||
go func() {
|
||||
toListener.Write(buffer[:n]) // Write buffer to new pipe
|
||||
for {
|
||||
buffer := make([]byte, udp.MTU())
|
||||
n, err := toListener.Read(buffer)
|
||||
if err != nil {
|
||||
toListener.Close()
|
||||
delete(udp.clients, from.String()) // Remove from clients
|
||||
return
|
||||
// Create new client
|
||||
newClient := new(clientInfo)
|
||||
newClient.WriteSize = n // Same Size from reader buffer
|
||||
var agentPipe net.Conn
|
||||
newClient.Conn, agentPipe = pipe.CreatePipe(udp.udpConn.LocalAddr(), from)
|
||||
|
||||
udp.newClient <- newClient // Send to accept
|
||||
udp.clientInfo.Store(from.String(), newClient)
|
||||
go agentPipe.Write(readBuffer[:n]) // n size from Buffer to client
|
||||
go func() {
|
||||
for {
|
||||
client, ok := udp.clientInfo.Load(from.String())
|
||||
if !ok {
|
||||
udp.clientInfo.Delete(from.String())
|
||||
agentPipe.Close()
|
||||
break // bye-bye
|
||||
}
|
||||
newClient := client.(*clientInfo)
|
||||
writeBuffer := make([]byte, newClient.WriteSize)
|
||||
n, err := agentPipe.Read(writeBuffer)
|
||||
if err != nil {
|
||||
udp.clientInfo.Delete(from.String())
|
||||
agentPipe.Close()
|
||||
break
|
||||
}
|
||||
go udp.udpConn.WriteToUDP(writeBuffer[:n], from)
|
||||
}
|
||||
udp.udpConn.WriteToUDP(buffer[:n], from)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func Listen(UdpProto string, Address netip.AddrPort, MTU func() uint64) (net.Listener, error) {
|
||||
conn, err := net.ListenUDP(UdpProto, net.UDPAddrFromAddrPort(Address))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
udp := new(UdpListerner)
|
||||
udp.udpConn = conn
|
||||
udp.newClient = make(chan any)
|
||||
udp.clients = make(map[string]net.Conn)
|
||||
udp.MTU = MTU
|
||||
go udp.backgroud()
|
||||
return udp, nil
|
||||
}
|
||||
|
36
server/call.go
Normal file
36
server/call.go
Normal file
@ -0,0 +1,36 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"sirherobrine23.org/Minecraft-Server/go-pproxit/proto"
|
||||
)
|
||||
|
||||
func getFreePort() (int, error) {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
l, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer l.Close()
|
||||
return l.Addr().(*net.TCPAddr).Port, nil
|
||||
}
|
||||
|
||||
// Accept any agent in ramdom port
|
||||
type DefaultCall struct{}
|
||||
|
||||
func (DefaultCall) AgentShutdown(Token [36]byte) error { return nil }
|
||||
func (d DefaultCall) AgentInfo(Token [36]byte) (TunnelInfo, error) {
|
||||
port, err := getFreePort()
|
||||
if err == nil {
|
||||
return TunnelInfo{
|
||||
PortListen: uint16(port),
|
||||
Proto: proto.ProtoBoth,
|
||||
}, nil
|
||||
}
|
||||
return TunnelInfo{}, err
|
||||
}
|
@ -3,6 +3,7 @@ package server
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
@ -39,35 +40,6 @@ type ServerCalls interface {
|
||||
AgentShutdown(Token [36]byte) error
|
||||
}
|
||||
|
||||
// Accept any agent in ramdom port
|
||||
type DefaultCall struct{}
|
||||
|
||||
func (DefaultCall) getFreePort() (int, error) {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
l, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer l.Close()
|
||||
return l.Addr().(*net.TCPAddr).Port, nil
|
||||
}
|
||||
|
||||
func (DefaultCall) AgentShutdown(Token [36]byte) error { return nil }
|
||||
func (d DefaultCall) AgentInfo(Token [36]byte) (TunnelInfo, error) {
|
||||
port, err := d.getFreePort()
|
||||
if err == nil {
|
||||
return TunnelInfo{
|
||||
PortListen: uint16(port),
|
||||
Proto: proto.ProtoBoth,
|
||||
}, nil
|
||||
}
|
||||
return TunnelInfo{}, err
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
RequestBuffer uint64 // Request Buffer
|
||||
Tunnels map[string]Tunnel // Tunnels listened
|
||||
@ -322,7 +294,7 @@ func (server *Server) Listen(ControllerPort uint16) (err error) {
|
||||
if err != nil {
|
||||
if err == ErrNoAgent {
|
||||
// Client not found
|
||||
res.BadRequest = true
|
||||
res.Unauthorized = true
|
||||
} else {
|
||||
// Cannot process request resend
|
||||
res.SendAuth = true
|
||||
@ -344,7 +316,7 @@ func (server *Server) Listen(ControllerPort uint16) (err error) {
|
||||
go tun.TCPAccepts() // Make accepts new requests
|
||||
}
|
||||
if info.Proto == 3 || info.Proto == 2 {
|
||||
tun.UDPListener, err = udplisterner.Listen("udp", netip.AddrPortFrom(netip.IPv4Unspecified(), info.PortListen), func() uint64 {return server.RequestBuffer})
|
||||
tun.UDPListener, err = udplisterner.Listen("udp", fmt.Sprintf("0.0.0.0:%d", info.PortListen))
|
||||
if err != nil {
|
||||
if tun.TCPListener != nil {
|
||||
tun.TCPListener.Close()
|
||||
|
Reference in New Issue
Block a user