mirror of
https://github.com/hyprspace/hyprspace.git
synced 2026-09-14 11:06:22 +05:00
Standardize Tun creation and setup process
This commit is contained in:
parent
b1caae2d87
commit
f7664f3263
106
cli/up.go
106
cli/up.go
@ -10,6 +10,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
@ -22,14 +23,13 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/songgao/water"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
var (
|
||||
// iface is the tun device used to pass packets between
|
||||
// Hyprspace and the user's machine.
|
||||
iface *water.Interface
|
||||
tunDev *tun.TUN
|
||||
// RevLookup allow quick lookups of an incoming stream
|
||||
// for security before accepting or responding to any data.
|
||||
RevLookup map[string]bool
|
||||
@ -97,15 +97,36 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
||||
}
|
||||
|
||||
fmt.Println("[+] Creating TUN Device")
|
||||
// Create new TUN device
|
||||
iface, err = tun.New(cfg.Interface.Name, cfg.Interface.Address)
|
||||
if err != nil {
|
||||
checkErr(errors.New("interface already in use"))
|
||||
|
||||
if runtime.GOOS == "darwin" {
|
||||
if len(cfg.Peers) > 1 {
|
||||
checkErr(errors.New("cannot create interface macos does not support more than one peer"))
|
||||
}
|
||||
|
||||
// Grab ip address of only peer in config
|
||||
var destPeer string
|
||||
for ip := range cfg.Peers {
|
||||
destPeer = ip
|
||||
}
|
||||
|
||||
// Create new TUN device
|
||||
tunDev, err = tun.New(
|
||||
cfg.Interface.Name,
|
||||
tun.Address(cfg.Interface.Address),
|
||||
tun.DestAddress(destPeer),
|
||||
tun.MTU(1420),
|
||||
)
|
||||
} else {
|
||||
// Create new TUN device
|
||||
tunDev, err = tun.New(
|
||||
cfg.Interface.Name,
|
||||
tun.Address(cfg.Interface.Address),
|
||||
tun.MTU(1420),
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
checkErr(err)
|
||||
}
|
||||
// Set TUN MTU
|
||||
tun.SetMTU(cfg.Interface.Name, 1420)
|
||||
// Add Address to Interface
|
||||
tun.SetAddress(cfg.Interface.Name, cfg.Interface.Address)
|
||||
|
||||
// Setup System Context
|
||||
ctx := context.Background()
|
||||
@ -113,34 +134,16 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
||||
fmt.Println("[+] Creating LibP2P Node")
|
||||
|
||||
// Check that the listener port is available.
|
||||
var ln net.Listener
|
||||
port := cfg.Interface.ListenPort
|
||||
if port != 8001 {
|
||||
ln, err = net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||
if err != nil {
|
||||
checkErr(errors.New("could not create node, listen port already in use by something else"))
|
||||
}
|
||||
} else {
|
||||
for {
|
||||
ln, err = net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if port >= 65535 {
|
||||
checkErr(errors.New("failed to find open port"))
|
||||
}
|
||||
port++
|
||||
}
|
||||
}
|
||||
if ln != nil {
|
||||
ln.Close()
|
||||
}
|
||||
port, err := verifyPort(cfg.Interface.ListenPort)
|
||||
checkErr(err)
|
||||
|
||||
// Create P2P Node
|
||||
host, dht, err := p2p.CreateNode(ctx,
|
||||
host, dht, err := p2p.CreateNode(
|
||||
ctx,
|
||||
cfg.Interface.PrivateKey,
|
||||
port,
|
||||
streamHandler)
|
||||
streamHandler,
|
||||
)
|
||||
checkErr(err)
|
||||
|
||||
// Setup Peer Table for Quick Packet --> Dest ID lookup
|
||||
@ -170,7 +173,10 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
||||
}()
|
||||
|
||||
// Bring Up TUN Device
|
||||
tun.Up(cfg.Interface.Name)
|
||||
err = tunDev.Up()
|
||||
if err != nil {
|
||||
checkErr(errors.New("unable to bring up tun device"))
|
||||
}
|
||||
|
||||
fmt.Println("[+] Network Setup Complete...Waiting on Node Discovery")
|
||||
// Listen For New Packets on TUN Interface
|
||||
@ -179,7 +185,7 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
||||
var header *ipv4.Header
|
||||
var plen int
|
||||
for {
|
||||
plen, err = iface.Read(packet)
|
||||
plen, err = tunDev.Iface.Read(packet)
|
||||
checkErr(err)
|
||||
header, _ = ipv4.ParseHeader(packet)
|
||||
_, ok := cfg.Peers[header.Dst.String()]
|
||||
@ -231,7 +237,7 @@ func streamHandler(stream network.Stream) {
|
||||
if _, ok := RevLookup[stream.Conn().RemotePeer().Pretty()]; !ok {
|
||||
stream.Reset()
|
||||
}
|
||||
io.Copy(iface.ReadWriteCloser, stream)
|
||||
io.Copy(tunDev.Iface.ReadWriteCloser, stream)
|
||||
stream.Close()
|
||||
}
|
||||
|
||||
@ -256,3 +262,29 @@ func prettyDiscovery(ctx context.Context, node host.Host, peerTable map[string]p
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func verifyPort(port int) (int, error) {
|
||||
var ln net.Listener
|
||||
var err error
|
||||
if port != 8001 {
|
||||
ln, err = net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||
if err != nil {
|
||||
return port, errors.New("could not create node, listen port already in use by something else")
|
||||
}
|
||||
} else {
|
||||
for {
|
||||
ln, err = net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if port >= 65535 {
|
||||
return port, errors.New("failed to find open port")
|
||||
}
|
||||
port++
|
||||
}
|
||||
}
|
||||
if ln != nil {
|
||||
ln.Close()
|
||||
}
|
||||
return port, nil
|
||||
}
|
||||
|
||||
21
tun/options.go
Normal file
21
tun/options.go
Normal file
@ -0,0 +1,21 @@
|
||||
package tun
|
||||
|
||||
type Option func(tun *TUN) error
|
||||
|
||||
func Address(address string) Option {
|
||||
return func(tun *TUN) error {
|
||||
return tun.setAddress(address)
|
||||
}
|
||||
}
|
||||
|
||||
func MTU(mtu int) Option {
|
||||
return func(tun *TUN) error {
|
||||
return tun.setMTU(mtu)
|
||||
}
|
||||
}
|
||||
|
||||
func DestAddress(address string) Option {
|
||||
return func(tun *TUN) error {
|
||||
return tun.setDestAddress(address)
|
||||
}
|
||||
}
|
||||
64
tun/tun.go
64
tun/tun.go
@ -1,55 +1,21 @@
|
||||
//go:build !windows && !linux
|
||||
// +build !windows,!linux
|
||||
|
||||
package tun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
import "github.com/songgao/water"
|
||||
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
type TUN struct {
|
||||
Iface *water.Interface
|
||||
Src string
|
||||
Dst string
|
||||
}
|
||||
|
||||
// New creates and returns a new TUN interface for the application.
|
||||
func New(name, address string) (result *water.Interface, err error) {
|
||||
// Setup TUN Config
|
||||
cfg := water.Config{
|
||||
DeviceType: water.TUN,
|
||||
func (t *TUN) Apply(opts ...Option) error {
|
||||
for _, opt := range opts {
|
||||
if opt == nil {
|
||||
continue
|
||||
}
|
||||
if err := opt(t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
cfg.Name = name
|
||||
// Create TUN Interface
|
||||
result, err = water.New(cfg)
|
||||
return
|
||||
}
|
||||
|
||||
// SetMTU sets the Maximum Tansmission Unit Size for a
|
||||
// Packet on the interface.
|
||||
func SetMTU(name string, mtu int) (err error) {
|
||||
return ip("link", "set", "dev", name, "mtu", fmt.Sprintf("%d", mtu))
|
||||
}
|
||||
|
||||
// SetAddress sets the interface's known address and subnet.
|
||||
func SetAddress(name string, address string) (err error) {
|
||||
return ip("addr", "add", address, "dev", name)
|
||||
}
|
||||
|
||||
// Up brings up an interface to allow it to start accepting connections.
|
||||
func Up(name string) (err error) {
|
||||
return ip("link", "set", "dev", name, "up")
|
||||
}
|
||||
|
||||
// Down brings down an interface stopping active connections.
|
||||
func Down(name string) (err error) {
|
||||
return ip("link", "set", "dev", name, "down")
|
||||
}
|
||||
|
||||
// Delete removes a TUN device from the host.
|
||||
func Delete(name string) (err error) {
|
||||
return ip("link", "delete", "dev", name)
|
||||
}
|
||||
|
||||
func ip(args ...string) (err error) {
|
||||
cmd := exec.Command("ip", args...)
|
||||
err = cmd.Run()
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
72
tun/tun_darwin.go
Normal file
72
tun/tun_darwin.go
Normal file
@ -0,0 +1,72 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
package tun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"github.com/songgao/water"
|
||||
)
|
||||
|
||||
// New creates and returns a new TUN interface for the application.
|
||||
func New(name string, opts ...Option) (*TUN, error) {
|
||||
// Setup TUN Config
|
||||
cfg := water.Config{
|
||||
DeviceType: water.TUN,
|
||||
}
|
||||
|
||||
// Create Water Interface
|
||||
iface, err := water.New(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create TUN result struct
|
||||
result := TUN{
|
||||
Iface: iface,
|
||||
}
|
||||
|
||||
// Apply options to set TUN config values
|
||||
err = result.Apply(opts...)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
// SetMTU sets the Maximum Tansmission Unit Size for a
|
||||
// Packet on the interface.
|
||||
func (t *TUN) setMTU(mtu int) error {
|
||||
return ifconfig(t.Iface.Name(), "mtu", fmt.Sprintf("%d", mtu))
|
||||
}
|
||||
|
||||
// SetDestAddress sets the interface's address.
|
||||
func (t *TUN) setAddress(address string) error {
|
||||
t.Src = address
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetDestAddress sets the interface's address.
|
||||
func (t *TUN) setDestAddress(address string) error {
|
||||
t.Dst = address
|
||||
return nil
|
||||
}
|
||||
|
||||
// Up brings up an interface to allow it to start accepting connections.
|
||||
func (t *TUN) Up() error {
|
||||
return ifconfig(t.Iface.Name(), "inet", t.Src, t.Dst, "up")
|
||||
}
|
||||
|
||||
// Down brings down an interface stopping active connections.
|
||||
func (t *TUN) Down() error {
|
||||
return ifconfig(t.Iface.Name(), "down")
|
||||
}
|
||||
|
||||
// Delete removes a TUN device from the host.
|
||||
func Delete(name string) error {
|
||||
return fmt.Errorf("removing an interface is unsupported under mac")
|
||||
}
|
||||
|
||||
func ifconfig(args ...string) error {
|
||||
cmd := exec.Command("ifconfig", args...)
|
||||
return cmd.Run()
|
||||
}
|
||||
@ -4,48 +4,69 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/songgao/water"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
// New creates and returns a new TUN interface for the application.
|
||||
func New(name, address string) (result *water.Interface, err error) {
|
||||
func New(name string, opts ...Option) (*TUN, error) {
|
||||
// Setup TUN Config
|
||||
cfg := water.Config{
|
||||
DeviceType: water.TUN,
|
||||
}
|
||||
cfg.Name = name
|
||||
// Create TUN Interface
|
||||
result, err = water.New(cfg)
|
||||
return
|
||||
|
||||
// Create Water Interface
|
||||
iface, err := water.New(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create TUN result struct
|
||||
result := TUN{
|
||||
Iface: iface,
|
||||
}
|
||||
|
||||
// Apply options to set TUN config values
|
||||
err = result.Apply(opts...)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
// SetMTU sets the Maximum Tansmission Unit Size for a
|
||||
// setMTU sets the Maximum Tansmission Unit Size for a
|
||||
// Packet on the interface.
|
||||
func SetMTU(name string, mtu int) error {
|
||||
link, err := netlink.LinkByName(name)
|
||||
func (t *TUN) setMTU(mtu int) error {
|
||||
link, err := netlink.LinkByName(t.Iface.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return netlink.LinkSetMTU(link, mtu)
|
||||
}
|
||||
|
||||
// SetAddress sets the interface's known address and subnet.
|
||||
func SetAddress(name string, address string) error {
|
||||
// setDestAddress sets the interface's destination address and subnet.
|
||||
func (t *TUN) setAddress(address string) error {
|
||||
addr, err := netlink.ParseAddr(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
link, err := netlink.LinkByName(name)
|
||||
link, err := netlink.LinkByName(t.Iface.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return netlink.AddrAdd(link, addr)
|
||||
}
|
||||
|
||||
// SetDestAddress isn't supported under Linux.
|
||||
// You should instead use set address to set the interface to handle
|
||||
// all addresses within a subnet.
|
||||
func (t *TUN) setDestAddress(address string) error {
|
||||
return errors.New("destination addresses are not supported under linux")
|
||||
}
|
||||
|
||||
// Up brings up an interface to allow it to start accepting connections.
|
||||
func Up(name string) error {
|
||||
link, err := netlink.LinkByName(name)
|
||||
func (t *TUN) Up() error {
|
||||
link, err := netlink.LinkByName(t.Iface.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -53,8 +74,8 @@ func Up(name string) error {
|
||||
}
|
||||
|
||||
// Down brings down an interface stopping active connections.
|
||||
func Down(name string) error {
|
||||
link, err := netlink.LinkByName(name)
|
||||
func (t *TUN) Down() error {
|
||||
link, err := netlink.LinkByName(t.Iface.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
// New creates and returns a new TUN interface for the application.
|
||||
func New(name, address string) (result *water.Interface, err error) {
|
||||
func New(name string, opts ...Option) (*TUN, error) {
|
||||
// TUN on Windows requires address and network to be set on device creation stage
|
||||
// We also set network to 0.0.0.0/0 so we able to reach networks behind the node
|
||||
// https://github.com/songgao/water/blob/master/params_windows.go
|
||||
@ -21,10 +21,12 @@ func New(name, address string) (result *water.Interface, err error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
network := net.IPNet{
|
||||
IP: ip,
|
||||
Mask: net.IPv4Mask(0, 0, 0, 0),
|
||||
}
|
||||
|
||||
// Setup TUN Config
|
||||
cfg := water.Config{
|
||||
DeviceType: water.TUN,
|
||||
@ -34,35 +36,54 @@ func New(name, address string) (result *water.Interface, err error) {
|
||||
Network: network.String(),
|
||||
},
|
||||
}
|
||||
// Create TUN Interface
|
||||
result, err = water.New(cfg)
|
||||
return
|
||||
|
||||
// Create Water Interface
|
||||
iface, err := water.New(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create TUN result struct
|
||||
result := TUN{
|
||||
Iface: iface,
|
||||
}
|
||||
|
||||
// Apply options to set TUN config values
|
||||
err = result.Apply(opts...)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
// SetMTU sets the Maximum Tansmission Unit Size for a
|
||||
// setMTU sets the Maximum Tansmission Unit Size for a
|
||||
// Packet on the interface.
|
||||
func SetMTU(name string, mtu int) (err error) {
|
||||
return netsh("interface", "ipv4", "set", "subinterface", name, "mtu=", fmt.Sprintf("%d", mtu))
|
||||
func (t *TUN) setMTU(mtu int) error {
|
||||
return netsh("interface", "ipv4", "set", "subinterface", t.Iface.Name(), "mtu=", fmt.Sprintf("%d", mtu))
|
||||
}
|
||||
|
||||
// SetAddress sets the interface's known address and subnet.
|
||||
func SetAddress(name string, address string) (err error) {
|
||||
return netsh("interface", "ip", "set", "address", "name=", name, "static", address)
|
||||
// setAddress sets the interface's destination address and subnet.
|
||||
func (t *TUN) setAddress(address string) error {
|
||||
return netsh("interface", "ip", "set", "address", "name=", t.Iface.Name(), "static", address)
|
||||
}
|
||||
|
||||
// SetDestAddress isn't supported under Windows.
|
||||
// You should instead use set address to set the interface to handle
|
||||
// all addresses within a subnet.
|
||||
func (t *TUN) setDestAddress(address string) error {
|
||||
return errors.New("destination addresses are not supported under windows")
|
||||
}
|
||||
|
||||
// Up brings up an interface to allow it to start accepting connections.
|
||||
func Up(name string) (err error) {
|
||||
return
|
||||
func (t *TUN) Up() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Down brings down an interface stopping active connections.
|
||||
func Down(name string) (err error) {
|
||||
return
|
||||
func (t *TUN) Down() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete removes a TUN device from the host.
|
||||
func Delete(name string) (err error) {
|
||||
return
|
||||
func Delete(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func netsh(args ...string) (err error) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user