mirror of
https://github.com/wlynxg/NetHive.git
synced 2025-10-05 23:16:54 +08:00
feature: implement control add address
This commit is contained in:
36
core/control/connect.go
Normal file
36
core/control/connect.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"NetHive/core/info"
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
type ConnectReq struct {
|
||||
Node info.NodeInfo
|
||||
}
|
||||
|
||||
type ConnectRes struct {
|
||||
Nodes []info.NodeInfo
|
||||
}
|
||||
|
||||
func (c *Client) Connect(ctx context.Context, req info.NodeInfo) ([]info.NodeInfo, error) {
|
||||
path, err := url.JoinPath(c.server, ConnectURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var nodes []info.NodeInfo
|
||||
response, err := c.client.Post(ctx, path, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = gconv.Scan(response.ReadAll(), &nodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
22
core/control/control.go
Normal file
22
core/control/control.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/gclient"
|
||||
)
|
||||
|
||||
const (
|
||||
ConnectURL = "/api/v1/connect"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
server string
|
||||
client *gclient.Client
|
||||
}
|
||||
|
||||
func New(server string) *Client {
|
||||
c := &Client{
|
||||
server: server,
|
||||
client: gclient.New(),
|
||||
}
|
||||
return c
|
||||
}
|
@@ -1,8 +1,10 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"NetHive/pkgs/command"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
@@ -72,6 +74,10 @@ func (t *tun) Name() (string, error) {
|
||||
return t.name, nil
|
||||
}
|
||||
|
||||
func (t *tun) AddAddress(addr netip.Addr) error {
|
||||
return command.IPAddr(addr, t.name)
|
||||
}
|
||||
|
||||
func (t *tun) getNameFromSys() (string, error) {
|
||||
t.flock.Lock()
|
||||
defer t.flock.Unlock()
|
||||
|
@@ -2,9 +2,13 @@ package engine
|
||||
|
||||
import (
|
||||
"NetHive/core/conn"
|
||||
"NetHive/core/control"
|
||||
"NetHive/core/device"
|
||||
"NetHive/core/info"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -12,24 +16,36 @@ const (
|
||||
)
|
||||
|
||||
type Engine struct {
|
||||
ctx context.Context
|
||||
option Option
|
||||
// tun device
|
||||
device device.Device
|
||||
// udp conn
|
||||
udpConn *conn.UdpConn
|
||||
// control
|
||||
control *control.Client
|
||||
|
||||
devWriter chan Payload
|
||||
connWriter chan Payload
|
||||
errChan chan error
|
||||
}
|
||||
|
||||
func (e *Engine) Start() error {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
e.ctx = ctx
|
||||
defer cancel()
|
||||
|
||||
opt := e.option
|
||||
|
||||
// create tun
|
||||
tun, err := device.CreateTUN(e.option.Device.TUNName, e.option.Device.MTU)
|
||||
tun, err := device.CreateTUN(opt.Device.TUNName, opt.Device.MTU)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.device = tun
|
||||
|
||||
// create udp connection
|
||||
addr, err := netip.ParseAddrPort(e.option.UDPAddr)
|
||||
addr, err := netip.ParseAddrPort(opt.UDPAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -39,6 +55,8 @@ func (e *Engine) Start() error {
|
||||
}
|
||||
e.udpConn = udpConn
|
||||
|
||||
e.control = control.New(opt.Server)
|
||||
|
||||
e.devWriter = make(chan Payload, 100)
|
||||
e.connWriter = make(chan Payload, 100)
|
||||
|
||||
@@ -46,6 +64,7 @@ func (e *Engine) Start() error {
|
||||
go e.RoutineTUNWriter()
|
||||
go e.RoutineConnReader()
|
||||
go e.RoutineConnWriter()
|
||||
go e.RoutineConnect()
|
||||
|
||||
if err := <-e.errChan; err != nil {
|
||||
return err
|
||||
@@ -121,3 +140,26 @@ func (e *Engine) RoutineConnWriter() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Engine) RoutineConnect() {
|
||||
var (
|
||||
nodes []info.NodeInfo
|
||||
err error
|
||||
)
|
||||
|
||||
interval := e.option.Interval
|
||||
timer := time.NewTimer(interval)
|
||||
for {
|
||||
select {
|
||||
case <-e.ctx.Done():
|
||||
return
|
||||
case <-timer.C:
|
||||
nodes, err = e.control.Connect(e.ctx, *info.New())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Printf("%+v\n", nodes)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,9 +1,13 @@
|
||||
package engine
|
||||
|
||||
import "time"
|
||||
|
||||
type Option struct {
|
||||
Device struct {
|
||||
TUNName string
|
||||
MTU int
|
||||
}
|
||||
UDPAddr string
|
||||
Server string
|
||||
Interval time.Duration
|
||||
}
|
||||
|
2
go.mod
2
go.mod
@@ -3,3 +3,5 @@ module NetHive
|
||||
go 1.20
|
||||
|
||||
require golang.org/x/sys v0.8.0
|
||||
|
||||
require github.com/gogf/gf/v2 v2.4.1 // indirect
|
||||
|
24
pkgs/command/bash_linux.go
Normal file
24
pkgs/command/bash_linux.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func BashCtx(ctx context.Context, cmd string) (int, []byte, error) {
|
||||
comm := exec.CommandContext(ctx, "/bin/bash", "-c", cmd)
|
||||
output, err := comm.Output()
|
||||
if err != nil {
|
||||
return comm.ProcessState.ExitCode(), nil, err
|
||||
}
|
||||
return comm.ProcessState.ExitCode(), output, nil
|
||||
}
|
||||
|
||||
func Bash(cmd string) (int, []byte, error) {
|
||||
comm := exec.Command("/bin/bash", "-c", cmd)
|
||||
output, err := comm.Output()
|
||||
if err != nil {
|
||||
return comm.ProcessState.ExitCode(), nil, err
|
||||
}
|
||||
return comm.ProcessState.ExitCode(), output, nil
|
||||
}
|
12
pkgs/command/ip_linux.go
Normal file
12
pkgs/command/ip_linux.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
func IPAddr(addr netip.Addr, dev string) error {
|
||||
cmd := fmt.Sprintf("ip addr add %s dev %s", addr.String(), dev)
|
||||
_, _, err := Bash(cmd)
|
||||
return err
|
||||
}
|
Reference in New Issue
Block a user