packages/hyprspace: update config file format, 0.4.1 -> 0.5.0
This commit is contained in:
parent
2e00712037
commit
2809d3d1e1
7 changed files with 125 additions and 155 deletions
|
@ -53,7 +53,7 @@ func InitRun(r *cmd.Root, c *cmd.Sub) {
|
|||
Name: args.InterfaceName,
|
||||
ListenPort: 8001,
|
||||
Address: "10.1.1.1/24",
|
||||
ID: host.ID().Pretty(),
|
||||
ID: host.ID(),
|
||||
PrivateKey: multibase.MustNewEncoder(multibase.Base58BTC).Encode(keyBytes),
|
||||
},
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
@ -30,14 +29,12 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
cfg *config.Config
|
||||
// iface is the tun device used to pass packets between
|
||||
// Hyprspace and the user's machine.
|
||||
tunDev *tun.TUN
|
||||
// RevLookup allow quick lookups of an incoming stream
|
||||
// for security before accepting or responding to any data.
|
||||
RevLookup map[string]string
|
||||
// activeStreams is a map of active streams to a peer
|
||||
activeStreams map[string]network.Stream
|
||||
activeStreams map[peer.ID]network.Stream
|
||||
// context
|
||||
ctx context.Context
|
||||
// context cancel function
|
||||
|
@ -76,43 +73,18 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
|||
}
|
||||
|
||||
// Read in configuration from file.
|
||||
cfg, err := config.Read(configPath)
|
||||
cfg2, err := config.Read(configPath)
|
||||
cfg = cfg2
|
||||
checkErr(err)
|
||||
|
||||
// Setup reverse lookup hash map for authentication.
|
||||
RevLookup = make(map[string]string, len(cfg.Peers))
|
||||
for ip, id := range cfg.Peers {
|
||||
RevLookup[id.ID] = ip
|
||||
}
|
||||
|
||||
fmt.Println("[+] Creating TUN Device")
|
||||
|
||||
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),
|
||||
)
|
||||
}
|
||||
// Create new TUN device
|
||||
tunDev, err = tun.New(
|
||||
cfg.Interface.Name,
|
||||
tun.Address(cfg.Interface.Address),
|
||||
tun.MTU(1420),
|
||||
)
|
||||
if err != nil {
|
||||
checkErr(err)
|
||||
}
|
||||
|
@ -137,23 +109,14 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
|||
checkErr(err)
|
||||
host.SetStreamHandler(p2p.PeXProtocol, p2p.NewPeXStreamHandler(host, cfg))
|
||||
|
||||
for _, id := range cfg.Peers {
|
||||
p, err := peer.Decode(id.ID)
|
||||
checkErr(err)
|
||||
host.ConnManager().Protect(p, "/hyprspace/peer")
|
||||
}
|
||||
|
||||
// Setup Peer Table for Quick Packet --> Dest ID lookup
|
||||
peerTable := make(map[string]peer.ID)
|
||||
for ip, id := range cfg.Peers {
|
||||
peerTable[ip], err = peer.Decode(id.ID)
|
||||
checkErr(err)
|
||||
for _, p := range cfg.Peers {
|
||||
host.ConnManager().Protect(p.ID, "/hyprspace/peer")
|
||||
}
|
||||
|
||||
fmt.Println("[+] Setting Up Node Discovery via DHT")
|
||||
|
||||
// Setup P2P Discovery
|
||||
go p2p.Discover(ctx, host, dht, peerTable)
|
||||
go p2p.Discover(ctx, host, dht, cfg.Peers)
|
||||
|
||||
// Configure path for lock
|
||||
lockPath := filepath.Join(filepath.Dir(cfg.Path), cfg.Interface.Name+".lock")
|
||||
|
@ -165,7 +128,7 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
|||
go signalHandler(ctx, host, lockPath, dht)
|
||||
|
||||
// Log about various events
|
||||
go eventLogger(ctx, host, cfg)
|
||||
go eventLogger(ctx, host)
|
||||
|
||||
// RPC server
|
||||
go hsrpc.RpcServer(ctx, multiaddr.StringCast(fmt.Sprintf("/unix/run/hyprspace-rpc.%s.sock", cfg.Interface.Name)), host, *cfg)
|
||||
|
@ -187,7 +150,7 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
|||
// + ----------------------------------------+
|
||||
|
||||
// Initialize active streams map and packet byte array.
|
||||
activeStreams = make(map[string]network.Stream)
|
||||
activeStreams = make(map[peer.ID]network.Stream)
|
||||
var packet = make([]byte, 1420)
|
||||
ip, _, err := net.ParseCIDR(cfg.Interface.Address)
|
||||
if err != nil {
|
||||
|
@ -207,23 +170,24 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
|||
}
|
||||
|
||||
dstIP := net.IPv4(packet[16], packet[17], packet[18], packet[19])
|
||||
dst := dstIP.String()
|
||||
if ip.Equal(dstIP) {
|
||||
continue
|
||||
}
|
||||
var dst *config.Peer
|
||||
|
||||
// Check route table for destination address.
|
||||
for route, _ := range cfg.Routes {
|
||||
_, network, _ := net.ParseCIDR(route)
|
||||
if network.Contains(dstIP) {
|
||||
src := net.IPv4(packet[12], packet[13], packet[14], packet[15])
|
||||
_, ok := peerTable[dst]
|
||||
// Only rewrite if initiator is us or receiver is not a known peer
|
||||
if src.Equal(ip) && !ok {
|
||||
dst = cfg.Routes[route].IP
|
||||
}
|
||||
for _, route := range cfg.Routes {
|
||||
if route.Network.Contains(dstIP) {
|
||||
dst = &route.Target
|
||||
break
|
||||
}
|
||||
}
|
||||
if dst == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if we already have an open connection to the destination peer.
|
||||
stream, ok := activeStreams[dst]
|
||||
stream, ok := activeStreams[dst.ID]
|
||||
if ok {
|
||||
// Write out the packet's length to the libp2p stream to ensure
|
||||
// we know the full size of the packet at the other end.
|
||||
|
@ -240,36 +204,32 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
|||
// If we encounter an error when writing to a stream we should
|
||||
// close that stream and delete it from the active stream map.
|
||||
stream.Close()
|
||||
delete(activeStreams, dst)
|
||||
delete(activeStreams, dst.ID)
|
||||
}
|
||||
|
||||
// Check if the destination of the packet is a known peer to
|
||||
// the interface.
|
||||
if peer, ok := peerTable[dst]; ok {
|
||||
stream, err = host.NewStream(ctx, peer, p2p.Protocol)
|
||||
if err != nil {
|
||||
fmt.Println("[!] Failed to open stream to " + dst)
|
||||
go p2p.Rediscover()
|
||||
continue
|
||||
}
|
||||
stream.SetWriteDeadline(time.Now().Add(25 * time.Second))
|
||||
// Write packet length
|
||||
err = binary.Write(stream, binary.LittleEndian, uint16(plen))
|
||||
if err != nil {
|
||||
stream.Close()
|
||||
continue
|
||||
}
|
||||
// Write the packet
|
||||
_, err = stream.Write(packet[:plen])
|
||||
if err != nil {
|
||||
stream.Close()
|
||||
continue
|
||||
}
|
||||
|
||||
// If all succeeds when writing the packet to the stream
|
||||
// we should reuse this stream by adding it active streams map.
|
||||
activeStreams[dst] = stream
|
||||
stream, err = host.NewStream(ctx, dst.ID, p2p.Protocol)
|
||||
if err != nil {
|
||||
fmt.Println("[!] Failed to open stream to " + dst.ID.String())
|
||||
go p2p.Rediscover()
|
||||
continue
|
||||
}
|
||||
stream.SetWriteDeadline(time.Now().Add(25 * time.Second))
|
||||
// Write packet length
|
||||
err = binary.Write(stream, binary.LittleEndian, uint16(plen))
|
||||
if err != nil {
|
||||
stream.Close()
|
||||
continue
|
||||
}
|
||||
// Write the packet
|
||||
_, err = stream.Write(packet[:plen])
|
||||
if err != nil {
|
||||
stream.Close()
|
||||
continue
|
||||
}
|
||||
|
||||
// If all succeeds when writing the packet to the stream
|
||||
// we should reuse this stream by adding it active streams map.
|
||||
activeStreams[dst.ID] = stream
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,7 +266,7 @@ func signalHandler(ctx context.Context, host host.Host, lockPath string, dht *dh
|
|||
}
|
||||
}
|
||||
|
||||
func eventLogger(ctx context.Context, host host.Host, cfg *config.Config) {
|
||||
func eventLogger(ctx context.Context, host host.Host) {
|
||||
subCon, err := host.EventBus().Subscribe(new(event.EvtPeerConnectednessChanged))
|
||||
checkErr(err)
|
||||
for {
|
||||
|
@ -315,14 +275,14 @@ func eventLogger(ctx context.Context, host host.Host, cfg *config.Config) {
|
|||
return
|
||||
case ev := <-subCon.Out():
|
||||
evt := ev.(event.EvtPeerConnectednessChanged)
|
||||
for vpnIp, vpnPeer := range cfg.Peers {
|
||||
if vpnPeer.ID == evt.Peer.Pretty() {
|
||||
for _, vpnPeer := range cfg.Peers {
|
||||
if vpnPeer.ID == evt.Peer {
|
||||
if evt.Connectedness == network.Connected {
|
||||
for _, c := range host.Network().ConnsToPeer(evt.Peer) {
|
||||
fmt.Printf("[+] Connected to %s at %s/p2p/%s\n", vpnIp, c.RemoteMultiaddr().String(), evt.Peer.Pretty())
|
||||
fmt.Printf("[+] Connected to %s/p2p/%s\n", c.RemoteMultiaddr().String(), evt.Peer.String())
|
||||
}
|
||||
} else if evt.Connectedness == network.NotConnected {
|
||||
fmt.Printf("[!] Disconnected from %s\n", vpnIp)
|
||||
fmt.Printf("[!] Disconnected from %s\n", evt.Peer.String())
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -333,7 +293,7 @@ func eventLogger(ctx context.Context, host host.Host, cfg *config.Config) {
|
|||
|
||||
func streamHandler(stream network.Stream) {
|
||||
// If the remote node ID isn't in the list of known nodes don't respond.
|
||||
if _, ok := RevLookup[stream.Conn().RemotePeer().Pretty()]; !ok {
|
||||
if _, ok := config.FindPeer(cfg.Peers, stream.Conn().RemotePeer()); !ok {
|
||||
stream.Reset()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,36 +2,41 @@ package config
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Config is the main Configuration Struct for Hyprspace.
|
||||
type Config struct {
|
||||
Path string `yaml:"path,omitempty"`
|
||||
Interface Interface `yaml:"interface"`
|
||||
Peers map[string]Peer `yaml:"peers"`
|
||||
Routes map[string]Route `yaml:"routes"`
|
||||
Path string `yaml:"path,omitempty"`
|
||||
Interface Interface `yaml:"interface"`
|
||||
Peers []Peer `yaml:"peers"`
|
||||
Routes []Route
|
||||
}
|
||||
|
||||
// Interface defines all of the fields that a local node needs to know about itself!
|
||||
type Interface struct {
|
||||
Name string `yaml:"name"`
|
||||
ID string `yaml:"id"`
|
||||
ListenPort int `yaml:"listen_port"`
|
||||
Address string `yaml:"address"`
|
||||
PrivateKey string `yaml:"private_key"`
|
||||
Name string `yaml:"name"`
|
||||
ID peer.ID `yaml:"id"`
|
||||
ListenPort int `yaml:"listen_port"`
|
||||
Address string `yaml:"address"`
|
||||
PrivateKey string `yaml:"private_key"`
|
||||
}
|
||||
|
||||
// Peer defines a peer in the configuration. We might add more to this later.
|
||||
type Peer struct {
|
||||
ID string `yaml:"id"`
|
||||
ID peer.ID `yaml:"id"`
|
||||
Routes []Route `yaml:"routes"`
|
||||
}
|
||||
|
||||
type Route struct {
|
||||
IP string `yaml:"ip"`
|
||||
Target Peer
|
||||
NetworkStr string `yaml:"net"`
|
||||
Network net.IPNet
|
||||
}
|
||||
|
||||
// Read initializes a config from a file.
|
||||
|
@ -56,21 +61,16 @@ func Read(path string) (*Config, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Check peers have valid ip addresses
|
||||
for ip := range result.Peers {
|
||||
if net.ParseIP(ip).String() == "<nil>" {
|
||||
return nil, fmt.Errorf("%s is not a valid ip address", ip)
|
||||
} else {
|
||||
fmt.Printf("[+] Assign this ip: %s to node: %s.\n", ip, result.Peers[ip].ID)
|
||||
}
|
||||
}
|
||||
|
||||
for route := range result.Routes {
|
||||
_, _, err := net.ParseCIDR(route)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s is not a valid route", route)
|
||||
} else {
|
||||
fmt.Printf("[+] Assign route %s via %s.\n", route, result.Routes[route].IP)
|
||||
for _, p := range result.Peers {
|
||||
for _, r := range p.Routes {
|
||||
r.Target = p
|
||||
_, n, err := net.ParseCIDR(r.NetworkStr)
|
||||
if err != nil {
|
||||
log.Fatal("[!] Invalid network:", r.NetworkStr)
|
||||
}
|
||||
r.Network = *n
|
||||
result.Routes = append(result.Routes, r)
|
||||
fmt.Printf("[+] Route %s via %s\n", r.Network.String(), p.ID.String())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,3 +78,23 @@ func Read(path string) (*Config, error) {
|
|||
result.Path = path
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func FindPeer(peers []Peer, needle peer.ID) (*Peer, bool) {
|
||||
for _, p := range peers {
|
||||
if p.ID == needle {
|
||||
return &p, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func FindRoute(routes []Route, needle net.IPNet) (*Route, bool) {
|
||||
for _, r := range routes {
|
||||
bits1, _ := r.Network.Mask.Size()
|
||||
bits2, _ := needle.Mask.Size()
|
||||
if r.Network.IP.Equal(needle.IP) && bits1 == bits2 {
|
||||
return &r, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
|
|
@ -5,16 +5,16 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hyprspace/hyprspace/config"
|
||||
dht "github.com/libp2p/go-libp2p-kad-dht"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
var discoverNow = make(chan bool)
|
||||
|
||||
// Discover starts up a DHT based discovery system finding and adding nodes with the same rendezvous string.
|
||||
func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT, peerTable map[string]peer.ID) {
|
||||
func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT, peers []config.Peer) {
|
||||
dur := time.Second * 1
|
||||
ticker := time.NewTicker(dur)
|
||||
defer ticker.Stop()
|
||||
|
@ -29,9 +29,9 @@ func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT, peerTable map[
|
|||
ticker.Reset(time.Millisecond * 1)
|
||||
case <-ticker.C:
|
||||
connectedToAny := false
|
||||
for _, id := range peerTable {
|
||||
if h.Network().Connectedness(id) != network.Connected {
|
||||
addrs, err := dht.FindPeer(ctx, id)
|
||||
for _, p := range peers {
|
||||
if h.Network().Connectedness(p.ID) != network.Connected {
|
||||
addrs, err := dht.FindPeer(ctx, p.ID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -29,12 +29,15 @@ func checkErrPeX(err error, stream network.Stream) bool {
|
|||
}
|
||||
|
||||
func NewPeXStreamHandler(host host.Host, cfg *config.Config) func(network.Stream) {
|
||||
revLookup := make(map[string]string, len(cfg.Peers))
|
||||
for ip, id := range cfg.Peers {
|
||||
revLookup[id.ID] = ip
|
||||
}
|
||||
return func(stream network.Stream) {
|
||||
if _, ok := revLookup[stream.Conn().RemotePeer().String()]; !ok {
|
||||
found := false
|
||||
for _, p := range cfg.Peers {
|
||||
if p.ID == stream.Conn().RemotePeer() {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
stream.Reset()
|
||||
return
|
||||
}
|
||||
|
@ -47,12 +50,8 @@ func NewPeXStreamHandler(host host.Host, cfg *config.Config) func(network.Stream
|
|||
if str == "r" {
|
||||
// peer requests addresses
|
||||
for _, p := range cfg.Peers {
|
||||
peerId, err := peer.Decode(p.ID)
|
||||
if checkErrPeX(err, stream) {
|
||||
return
|
||||
}
|
||||
if peerId != stream.Conn().RemotePeer() {
|
||||
for _, c := range host.Network().ConnsToPeer(peerId) {
|
||||
if p.ID != stream.Conn().RemotePeer() {
|
||||
for _, c := range host.Network().ConnsToPeer(p.ID) {
|
||||
_, err := stream.Write([]byte(fmt.Sprintf("%s|%s\n", c.RemotePeer().String(), c.RemoteMultiaddr().String())))
|
||||
if checkErrPeX(err, stream) {
|
||||
return
|
||||
|
@ -114,17 +113,13 @@ func PeXService(ctx context.Context, host host.Host, cfg *config.Config) {
|
|||
case ev := <-subCon.Out():
|
||||
evt := ev.(event.EvtPeerConnectednessChanged)
|
||||
for _, vpnPeer := range cfg.Peers {
|
||||
if vpnPeer.ID == evt.Peer.String() {
|
||||
if vpnPeer.ID == evt.Peer {
|
||||
if evt.Connectedness == network.Connected {
|
||||
go RequestPeX(ctx, host, []peer.ID{evt.Peer})
|
||||
} else if evt.Connectedness == network.NotConnected {
|
||||
peers := []peer.ID{}
|
||||
for _, p := range cfg.Peers {
|
||||
peerId, err := peer.Decode(p.ID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
peers = append(peers, peerId)
|
||||
peers = append(peers, p.ID)
|
||||
}
|
||||
go RequestPeX(ctx, host, peers)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
};
|
||||
packages.hyprspace = with pkgs; buildGo118Module {
|
||||
pname = "hyprspace";
|
||||
version = "0.4.1";
|
||||
version = "0.5.0";
|
||||
|
||||
src = with inputs.nix-filter.lib; let
|
||||
dirs = map inDirectory;
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/hyprspace/hyprspace/config"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
|
@ -23,15 +22,11 @@ type HyprspaceRPC struct {
|
|||
func (hsr *HyprspaceRPC) Status(args *Args, reply *StatusReply) error {
|
||||
netPeersCurrent := 0
|
||||
var netPeerAddrsCurrent []string
|
||||
for _, id := range hsr.config.Peers {
|
||||
peerId, err := peer.Decode(id.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hsr.host.Network().Connectedness(peerId) == network.Connected {
|
||||
for _, p := range hsr.config.Peers {
|
||||
if hsr.host.Network().Connectedness(p.ID) == network.Connected {
|
||||
netPeersCurrent = netPeersCurrent + 1
|
||||
for _, c := range hsr.host.Network().ConnsToPeer(peerId) {
|
||||
netPeerAddrsCurrent = append(netPeerAddrsCurrent, fmt.Sprintf("%s/p2p/%s", c.RemoteMultiaddr().String(), peerId.String()))
|
||||
for _, c := range hsr.host.Network().ConnsToPeer(p.ID) {
|
||||
netPeerAddrsCurrent = append(netPeerAddrsCurrent, fmt.Sprintf("%s/p2p/%s", c.RemoteMultiaddr().String(), p.ID.String()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue