diff --git a/.gitignore b/.gitignore index 5fe29db..140675b 100644 --- a/.gitignore +++ b/.gitignore @@ -242,5 +242,9 @@ punchr.gz dist/ +**/*api-key.txt + +gui/client/**.app + # Nix build result symlink result \ No newline at end of file diff --git a/cmd/server/grpc.go b/cmd/server/grpc.go index f144043..d35ff4e 100644 --- a/cmd/server/grpc.go +++ b/cmd/server/grpc.go @@ -99,6 +99,10 @@ func (s Server) GetAddrInfo(ctx context.Context, req *pb.GetAddrInfoRequest) (*p return nil, errors.Wrap(err, "get client peer from db") } + if len(dbHosts) == 0 { + return nil, errors.Wrap(err, "please restart the client") + } + dbHostIDs := make([]string, len(dbHosts)) for i, dbHost := range dbHosts { dbHostIDs[i] = strconv.FormatInt(dbHost.ID, 10) @@ -181,7 +185,7 @@ LIMIT 1 } remoteID, err := peer.Decode(remoteMultiHash) if err != nil { - return nil, errors.Wrap(err, "query addr infos") + return nil, errors.Wrap(err, "decode remote multi hash") } remoteIDBytes, err := remoteID.Marshal() @@ -266,7 +270,7 @@ LIMIT 1 remoteID, err := peer.Decode(remoteMultiHash) if err != nil { - return nil, errors.Wrap(err, "query addr infos") + return nil, errors.Wrap(err, "decode remote multi hash") } remoteIDBytes, err := remoteID.Marshal() diff --git a/go.mod b/go.mod index 71730c1..379e592 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.18 require ( fyne.io/fyne/v2 v2.2.3 + github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/friendsofgo/errors v0.9.2 github.com/golang-migrate/migrate/v4 v4.15.2 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 diff --git a/go.sum b/go.sum index 5a5e6f8..ad96dd6 100644 --- a/go.sum +++ b/go.sum @@ -431,6 +431,8 @@ github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0 github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:M88ob4TyDnEqNuL3PgsE/p3bDujfspnulR+0dQWNYZs= +github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:buzQsO8HHkZX2Q45fdfGH1xejPjuDQaXH8btcYMFzPM= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= diff --git a/gui/client/client.go b/gui/client/client.go index 2bb35a9..14b7ba5 100644 --- a/gui/client/client.go +++ b/gui/client/client.go @@ -3,6 +3,7 @@ package main import ( "context" "io" + "os" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" @@ -11,6 +12,7 @@ import ( "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/widget" + "github.com/emersion/go-autostart" "github.com/friendsofgo/errors" log "github.com/sirupsen/logrus" @@ -26,9 +28,22 @@ var ( menuItemStatus = fyne.NewMenuItem("", nil) menuItemToggle = fyne.NewMenuItem("", nil) menuItemApiKey = fyne.NewMenuItem("Set API Key", nil) + menuItemLogin = fyne.NewMenuItem("", nil) ) func main() { + execPath, err := os.Executable() + if err != nil { + log.WithError(err).Errorln("Could not determine executable path") + os.Exit(1) + } + + autostartApp := &autostart.App{ + Name: "com.protocol.ai.punchr", + DisplayName: "Punchr Client", + Exec: []string{execPath}, + } + a := app.New() a.SetIcon(gloveInactiveEmoji) @@ -52,16 +67,36 @@ func main() { menuItemApiKey.Action = func() { p.ShowApiKeyDialog() } + menuItemLogin.Action = func() { + if autostartApp.IsEnabled() { + if err := autostartApp.Disable(); err != nil { + log.WithError(err).Warnln("error") + } + menuItemLogin.Label = "🔴 Launch on Login: Disabled" + } else { + log.Println("Enabling app...") + if err := autostartApp.Enable(); err != nil { + log.WithError(err).Warnln("error") + } + menuItemLogin.Label = "🟢 Launch on Login: Enabled" + } + sysTrayMenu.Refresh() + } - sysTrayMenu = fyne.NewMenu("Punchr", menuItemStatus, fyne.NewMenuItemSeparator(), menuItemToggle, menuItemApiKey) + sysTrayMenu = fyne.NewMenu("Punchr", menuItemStatus, fyne.NewMenuItemSeparator(), menuItemToggle, menuItemApiKey, menuItemLogin) desk.SetSystemTrayMenu(sysTrayMenu) if p.apiKey == "" { menuItemStatus.Label = "No API-Key" menuItemToggle.Disabled = true } else { - menuItemStatus.Label = "API-Key: " + p.apiKey - menuItemToggle.Label = "Start Hole Punching" + go p.StartHolePunching() + } + + if autostartApp.IsEnabled() { + menuItemLogin.Label = "🟢 Launch on Login: Enabled" + } else { + menuItemLogin.Label = "🔴 Launch on Login: Disabled" } sysTrayMenu.Refresh() @@ -138,7 +173,7 @@ func (p *Punchr) StartHolePunching() { p.isHolePunching = true desk.SetSystemTrayIcon(gloveActiveEmoji) - menuItemStatus.Label = "Running..." + menuItemStatus.Label = "🟢 Running..." menuItemToggle.Label = "Stop Hole Punching" sysTrayMenu.Refresh() diff --git a/pkg/client/host.go b/pkg/client/host.go index 77d8f64..a8933ec 100644 --- a/pkg/client/host.go +++ b/pkg/client/host.go @@ -36,7 +36,7 @@ type Host struct { holePunchEventsPeers sync.Map bpAddrInfos []peer.AddrInfo rcmgr *ResourceManager - maddrs map[multiaddr.Multiaddr]struct{} + maddrs map[string]struct{} } func InitHost(c *cli.Context, privKey crypto.PrivKey) (*Host, error) { @@ -71,7 +71,7 @@ func InitHost(c *cli.Context, privKey crypto.PrivKey) (*Host, error) { holePunchEventsPeers: sync.Map{}, bpAddrInfos: bpAddrInfos, rcmgr: rcmgr, - maddrs: map[multiaddr.Multiaddr]struct{}{}, + maddrs: map[string]struct{}{}, } // Configure new libp2p host @@ -159,7 +159,7 @@ func (h *Host) WaitForPublicAddr(ctx context.Context) error { logEntry.Debug("Found >= 1 public addresses!") for _, maddr := range h.Host.Addrs() { if manet.IsPublicAddr(maddr) { - h.maddrs[maddr] = struct{}{} + h.maddrs[maddr.String()] = struct{}{} } } @@ -224,9 +224,15 @@ func (h *Host) HolePunch(ctx context.Context, addrInfo peer.AddrInfo) *HolePunch // Track open connections after the hole punch defer func() { + deduplicate := map[string]struct{}{} for _, conn := range h.Network().ConnsToPeer(addrInfo.ID) { + if _, found := deduplicate[conn.RemoteMultiaddr().String()]; found { + continue + } hpState.OpenMaddrs = append(hpState.OpenMaddrs, conn.RemoteMultiaddr()) + deduplicate[conn.RemoteMultiaddr().String()] = struct{}{} } + fmt.Println("hpState.OpenMaddrs", hpState.OpenMaddrs) hpState.HasDirectConns = h.hasDirectConnToPeer(addrInfo.ID) }() diff --git a/pkg/client/punchr.go b/pkg/client/punchr.go index 8be51d2..53af4d5 100644 --- a/pkg/client/punchr.go +++ b/pkg/client/punchr.go @@ -228,7 +228,7 @@ func (p Punchr) StartHolePunching(ctx context.Context) error { if !p.disableRouterCheck { // Check if the multi addresses have changed - if that's the case we have switched networks for _, maddr := range h.Addrs() { - if _, found := h.maddrs[maddr]; found { + if _, found := h.maddrs[maddr.String()]; found { continue } @@ -240,9 +240,9 @@ func (p Punchr) StartHolePunching(ctx context.Context) error { } // Update list of multi addresses - h.maddrs = map[multiaddr.Multiaddr]struct{}{} + h.maddrs = map[string]struct{}{} for _, newMaddr := range h.Addrs() { - h.maddrs[newMaddr] = struct{}{} + h.maddrs[newMaddr.String()] = struct{}{} } break