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
|
package device
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"NetHive/pkgs/command"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
@@ -72,6 +74,10 @@ func (t *tun) Name() (string, error) {
|
|||||||
return t.name, nil
|
return t.name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *tun) AddAddress(addr netip.Addr) error {
|
||||||
|
return command.IPAddr(addr, t.name)
|
||||||
|
}
|
||||||
|
|
||||||
func (t *tun) getNameFromSys() (string, error) {
|
func (t *tun) getNameFromSys() (string, error) {
|
||||||
t.flock.Lock()
|
t.flock.Lock()
|
||||||
defer t.flock.Unlock()
|
defer t.flock.Unlock()
|
||||||
|
@@ -2,9 +2,13 @@ package engine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"NetHive/core/conn"
|
"NetHive/core/conn"
|
||||||
|
"NetHive/core/control"
|
||||||
"NetHive/core/device"
|
"NetHive/core/device"
|
||||||
|
"NetHive/core/info"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -12,24 +16,36 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
option Option
|
ctx context.Context
|
||||||
device device.Device
|
option Option
|
||||||
udpConn *conn.UdpConn
|
// tun device
|
||||||
|
device device.Device
|
||||||
|
// udp conn
|
||||||
|
udpConn *conn.UdpConn
|
||||||
|
// control
|
||||||
|
control *control.Client
|
||||||
|
|
||||||
devWriter chan Payload
|
devWriter chan Payload
|
||||||
connWriter chan Payload
|
connWriter chan Payload
|
||||||
errChan chan error
|
errChan chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) Start() error {
|
func (e *Engine) Start() error {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
e.ctx = ctx
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
opt := e.option
|
||||||
|
|
||||||
// create tun
|
// 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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.device = tun
|
e.device = tun
|
||||||
|
|
||||||
// create udp connection
|
// create udp connection
|
||||||
addr, err := netip.ParseAddrPort(e.option.UDPAddr)
|
addr, err := netip.ParseAddrPort(opt.UDPAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -39,6 +55,8 @@ func (e *Engine) Start() error {
|
|||||||
}
|
}
|
||||||
e.udpConn = udpConn
|
e.udpConn = udpConn
|
||||||
|
|
||||||
|
e.control = control.New(opt.Server)
|
||||||
|
|
||||||
e.devWriter = make(chan Payload, 100)
|
e.devWriter = make(chan Payload, 100)
|
||||||
e.connWriter = make(chan Payload, 100)
|
e.connWriter = make(chan Payload, 100)
|
||||||
|
|
||||||
@@ -46,6 +64,7 @@ func (e *Engine) Start() error {
|
|||||||
go e.RoutineTUNWriter()
|
go e.RoutineTUNWriter()
|
||||||
go e.RoutineConnReader()
|
go e.RoutineConnReader()
|
||||||
go e.RoutineConnWriter()
|
go e.RoutineConnWriter()
|
||||||
|
go e.RoutineConnect()
|
||||||
|
|
||||||
if err := <-e.errChan; err != nil {
|
if err := <-e.errChan; err != nil {
|
||||||
return err
|
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
|
package engine
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
type Option struct {
|
type Option struct {
|
||||||
Device struct {
|
Device struct {
|
||||||
TUNName string
|
TUNName string
|
||||||
MTU int
|
MTU int
|
||||||
}
|
}
|
||||||
UDPAddr string
|
UDPAddr string
|
||||||
|
Server string
|
||||||
|
Interval time.Duration
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@@ -3,3 +3,5 @@ module NetHive
|
|||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require golang.org/x/sys v0.8.0
|
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