diff --git a/.gitignore b/.gitignore index f128556..5b53202 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -hyprspace \ No newline at end of file +hyprspace +.DS_Store \ No newline at end of file diff --git a/cli/init.go b/cli/init.go index a8901e4..6ccf9e7 100644 --- a/cli/init.go +++ b/cli/init.go @@ -55,6 +55,7 @@ func InitRun(r *cmd.Root, c *cmd.Sub) { new := config.Config{ Interface: config.Interface{ Name: args.InterfaceName, + ListenPort: 8001, Address: "10.1.1.1/24", ID: host.ID().Pretty(), PrivateKey: string(keyBytes), diff --git a/cli/root.go b/cli/root.go index 434741b..7c9b02c 100644 --- a/cli/root.go +++ b/cli/root.go @@ -9,6 +9,8 @@ import ( "github.com/DataDrake/cli-ng/v2/cmd" ) +var appVersion string = "develop" + //GlobalFlags contains the flags for commands. type GlobalFlags struct { Config string `short:"c" long:"config" desc:"Specify a custom config path."` @@ -19,15 +21,18 @@ var Root *cmd.Root func init() { Root = &cmd.Root{ - Name: "hyprspace", - Short: "Hyprspace Distributed Network", - Flags: &GlobalFlags{}, + Name: "hyprspace", + Short: "Hyprspace Distributed Network", + Version: appVersion, + Flags: &GlobalFlags{}, } + cmd.Register(&cmd.Help) cmd.Register(&Init) cmd.Register(&Up) cmd.Register(&Down) cmd.Register(&Update) + cmd.Register(&cmd.Version) } func checkErr(err error) { diff --git a/cli/up.go b/cli/up.go index dcbac36..8b0f16c 100644 --- a/cli/up.go +++ b/cli/up.go @@ -3,11 +3,14 @@ package cli import ( "bufio" "context" + "errors" "fmt" "io" "log" + "net" "os" "os/signal" + "strconv" "strings" "syscall" "time" @@ -75,15 +78,18 @@ func UpRun(r *cmd.Root, c *cmd.Sub) { if !flags.Foreground { // Make results chan - out := make(chan bool) + out := make(chan error) go createDaemon(out) select { - case <-out: + case err = <-out: case <-time.After(30 * time.Second): } - checkErr(err) - fmt.Println("[+] Successfully Created Hyprspace Daemon") + if err != nil { + fmt.Println("[+] Failed to Create Hyprspace Daemon") + } else { + fmt.Println("[+] Successfully Created Hyprspace Daemon") + } return } @@ -96,7 +102,9 @@ func UpRun(r *cmd.Root, c *cmd.Sub) { fmt.Println("[+] Creating TUN Device") // Create new TUN device iface, err = tun.New(Global.Interface.Name) - checkErr(err) + if err != nil { + checkErr(errors.New("interface already in use")) + } // Set TUN MTU tun.SetMTU(Global.Interface.Name, 1420) // Add Address to Interface @@ -106,8 +114,35 @@ func UpRun(r *cmd.Root, c *cmd.Sub) { ctx := context.Background() fmt.Println("[+] Creating LibP2P Node") + + // Check that the listener port is available. + var ln net.Listener + port := Global.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() + } // Create P2P Node - host, dht, err := p2p.CreateNode(ctx, Global.Interface.PrivateKey, streamHandler) + host, dht, err := p2p.CreateNode(ctx, + Global.Interface.PrivateKey, + port, + streamHandler) checkErr(err) // Setup Peer Table for Quick Packet --> Dest ID lookup @@ -162,7 +197,7 @@ func UpRun(r *cmd.Root, c *cmd.Sub) { } } -func createDaemon(out chan<- bool) { +func createDaemon(out chan<- error) { path, err := os.Executable() checkErr(err) // Create Pipe to monitor for daemon output. @@ -173,7 +208,7 @@ func createDaemon(out chan<- bool) { path, append(os.Args, "--foreground"), &os.ProcAttr{ - Files: []*os.File{nil, w, nil}, + Files: []*os.File{nil, w, w}, }, ) checkErr(err) @@ -186,7 +221,10 @@ func createDaemon(out chan<- bool) { fmt.Println(scanner.Text()) err = process.Release() checkErr(err) - out <- true + if count < 4 { + out <- errors.New("failed to create daemon") + } + out <- nil } func streamHandler(stream network.Stream) { diff --git a/cli/update.go b/cli/update.go index 88191a7..accb37b 100644 --- a/cli/update.go +++ b/cli/update.go @@ -14,8 +14,6 @@ import ( "github.com/tcnksm/go-latest" ) -var appVersion string - // Update checks for a new version of the Hyprspace program and updates itself // if a newer version is found and the user agrees to update. var Update = cmd.Sub{ diff --git a/config/config.go b/config/config.go index a03236c..97dd21b 100644 --- a/config/config.go +++ b/config/config.go @@ -15,8 +15,9 @@ type Config struct { // Interface defines all of the fields that a local node needs to know about itself! type Interface struct { Name string `yaml:"name"` - Address string `yaml:"address"` ID string `yaml:"id"` + ListenPort int `yaml:"listen_port"` + Address string `yaml:"address"` DiscoverKey string `yaml:"discover_key"` PrivateKey string `yaml:"private_key"` } @@ -32,6 +33,16 @@ func Read(path string) (result Config, err error) { if err != nil { return } + result = Config{ + Interface: Interface{ + Name: "hs0", + ListenPort: 8001, + Address: "10.1.1.1", + ID: "", + DiscoverKey: "", + PrivateKey: "", + }, + } err = yaml.Unmarshal(in, &result) return } diff --git a/p2p/discover.go b/p2p/discover.go index 6d5f069..c653714 100644 --- a/p2p/discover.go +++ b/p2p/discover.go @@ -18,7 +18,7 @@ func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT, rendezvous str var routingDiscovery = discovery.NewRoutingDiscovery(dht) discovery.Advertise(ctx, routingDiscovery, rendezvous) - ticker := time.NewTicker(time.Second * 1) + ticker := time.NewTicker(time.Second * 5) defer ticker.Stop() for { diff --git a/p2p/node.go b/p2p/node.go index 2178a63..76ae64f 100644 --- a/p2p/node.go +++ b/p2p/node.go @@ -18,7 +18,7 @@ import ( const Protocol = "/hyprspace/0.0.1" // CreateNode creates an internal Libp2p nodes and returns it and it's DHT Discovery service. -func CreateNode(ctx context.Context, inputKey string, handler network.StreamHandler) (node host.Host, dhtOut *dht.IpfsDHT, err error) { +func CreateNode(ctx context.Context, inputKey string, port int, handler network.StreamHandler) (node host.Host, dhtOut *dht.IpfsDHT, err error) { // Unmarshal Private Key privateKey, err := crypto.UnmarshalPrivateKey([]byte(inputKey)) if err != nil { @@ -27,7 +27,7 @@ func CreateNode(ctx context.Context, inputKey string, handler network.StreamHand // Create libp2p node node, err = libp2p.New(ctx, - libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", 8001)), + libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port)), libp2p.Identity(privateKey), ) if err != nil {