Skip to content

Commit

Permalink
Merge pull request #54 from anywherelan/unique_peer_alias
Browse files Browse the repository at this point in the history
Unique peers aliases
  • Loading branch information
GrigoryKrasnochub authored Oct 25, 2022
2 parents a27fb42 + 551b79d commit 6b61e94
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 52 deletions.
12 changes: 12 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
http_pprof "net/http/pprof"
"runtime/pprof"
"strings"

"github.com/anywherelan/awl/config"
"github.com/anywherelan/awl/p2p"
Expand Down Expand Up @@ -61,6 +62,11 @@ func (h *Handler) SetupAPI() error {
e.HideBanner = true
e.HidePort = true
val := validator.New()
err := val.RegisterValidation("trimmed_str_not_empty", validateTrimmedStringNotEmpty, false)
if err != nil {
return err
}

e.Validator = &customValidator{validator: val}

// Middleware
Expand Down Expand Up @@ -163,3 +169,9 @@ func (e Error) Error() string {
func ErrorMessage(message string) Error {
return Error{Message: message}
}

func validateTrimmedStringNotEmpty(fl validator.FieldLevel) bool {
str := fl.Field().String()
str = strings.TrimSpace(str)
return len(str) > 0
}
18 changes: 18 additions & 0 deletions api/peers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package api
import (
"net/http"
"sort"
"strings"

"github.com/anywherelan/awl/awldns"
"github.com/anywherelan/awl/config"
Expand All @@ -11,6 +12,8 @@ import (
"github.com/libp2p/go-libp2p-core/peer"
)

const ErrorPeerAliasIsNotUniq = "peer name is not unique"

// @Tags Peers
// @Summary Get known peers info
// @Accept json
Expand Down Expand Up @@ -112,7 +115,12 @@ func (h *Handler) UpdatePeerSettings(c echo.Context) (err error) {
}
peerID := knownPeer.PeerId()

req.Alias = strings.TrimSpace(req.Alias)
if !h.conf.IsUniqPeerAlias(req.Alias) {
return c.JSON(http.StatusBadRequest, ErrorMessage(ErrorPeerAliasIsNotUniq))
}
knownPeer.Alias = req.Alias

knownPeer.DomainName = req.DomainName
h.conf.UpsertPeer(knownPeer)

Expand Down Expand Up @@ -158,6 +166,11 @@ func (h *Handler) SendFriendRequest(c echo.Context) (err error) {
return c.JSON(http.StatusBadRequest, ErrorMessage("Peer has already been added"))
}

req.Alias = strings.TrimSpace(req.Alias)
if !h.conf.IsUniqPeerAlias(req.Alias) {
return c.JSON(http.StatusBadRequest, ErrorMessage(ErrorPeerAliasIsNotUniq))
}

h.authStatus.AddPeer(h.ctx, peerId, "", req.Alias, false)

return c.NoContent(http.StatusOK)
Expand Down Expand Up @@ -208,6 +221,11 @@ func (h *Handler) AcceptFriend(c echo.Context) (err error) {
return c.NoContent(http.StatusOK)
}

req.Alias = strings.TrimSpace(req.Alias)
if !h.conf.IsUniqPeerAlias(req.Alias) {
return c.JSON(http.StatusBadRequest, ErrorMessage(ErrorPeerAliasIsNotUniq))
}

h.authStatus.AddPeer(h.ctx, peerId, auth.Name, req.Alias, true)

return c.NoContent(http.StatusOK)
Expand Down
35 changes: 29 additions & 6 deletions application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"testing"
"time"

"github.com/anywherelan/awl/api"
"github.com/anywherelan/awl/api/apiclient"
"github.com/anywherelan/awl/config"
"github.com/anywherelan/awl/entity"
Expand Down Expand Up @@ -80,7 +81,7 @@ func TestRemovePeer(t *testing.T) {
a.Len(peer2.app.AuthStatus.GetIngoingAuthRequests(), 0)

// Add peer2 from peer1 - should succeed
err = peer1.api.SendFriendRequest(peer2.PeerID(), "")
err = peer1.api.SendFriendRequest(peer2.PeerID(), "peer_2")
a.NoError(err)
time.Sleep(500 * time.Millisecond)

Expand Down Expand Up @@ -113,7 +114,7 @@ func TestDeclinePeerFriendRequest(t *testing.T) {
defer peer2.Close()
ensurePeersAvailableInDHT(a, peer1, peer2)

err := peer1.api.SendFriendRequest(peer2.PeerID(), "")
err := peer1.api.SendFriendRequest(peer2.PeerID(), "peer_2")
a.NoError(err)

var authRequests []entity.AuthRequest
Expand All @@ -122,7 +123,7 @@ func TestDeclinePeerFriendRequest(t *testing.T) {
a.NoError(err)
return len(authRequests) == 1
}, 15*time.Second, 50*time.Millisecond)
err = peer2.api.ReplyFriendRequest(authRequests[0].PeerID, "", true)
err = peer2.api.ReplyFriendRequest(authRequests[0].PeerID, "peer_1", true)
a.NoError(err)

time.Sleep(500 * time.Millisecond)
Expand Down Expand Up @@ -151,7 +152,7 @@ func TestAutoAcceptFriendRequest(t *testing.T) {
peer2.app.Conf.P2pNode.AutoAcceptAuthRequests = true
peer2.app.Conf.Unlock()

err := peer1.api.SendFriendRequest(peer2.PeerID(), "")
err := peer1.api.SendFriendRequest(peer2.PeerID(), "peer_2")
a.NoError(err)

a.Eventually(func() bool {
Expand All @@ -172,6 +173,28 @@ func TestAutoAcceptFriendRequest(t *testing.T) {
a.False(knownPeer.Declined)
}

func TestUniquePeerAlias(t *testing.T) {
a := require.New(t)
closeBootstrapNode := initBootstrapNode(t)
defer closeBootstrapNode()

peer1 := newTestPeer(t, false)
defer peer1.Close()
peer2 := newTestPeer(t, false)
defer peer2.Close()
peer3 := newTestPeer(t, false)
defer peer3.Close()
ensurePeersAvailableInDHT(a, peer1, peer3)

err := peer1.api.SendFriendRequest(peer2.PeerID(), "peer")
a.NoError(err)

time.Sleep(200 * time.Millisecond)

err = peer1.api.SendFriendRequest(peer3.PeerID(), "peer")
a.EqualError(err, api.ErrorPeerAliasIsNotUniq)
}

func BenchmarkTunnelPackets(b *testing.B) {
a := require.New(b)
closeBootstrapNode := initBootstrapNode(b)
Expand Down Expand Up @@ -330,7 +353,7 @@ func ensurePeersAvailableInDHT(a *require.Assertions, peer1, peer2 testPeer) {

func makeFriends(a *require.Assertions, peer1, peer2 testPeer) {
ensurePeersAvailableInDHT(a, peer1, peer2)
err := peer1.api.SendFriendRequest(peer2.PeerID(), "")
err := peer1.api.SendFriendRequest(peer2.PeerID(), "peer_2")
a.NoError(err)

var authRequests []entity.AuthRequest
Expand All @@ -339,7 +362,7 @@ func makeFriends(a *require.Assertions, peer1, peer2 testPeer) {
a.NoError(err)
return len(authRequests) == 1
}, 15*time.Second, 50*time.Millisecond)
err = peer2.api.ReplyFriendRequest(authRequests[0].PeerID, "", false)
err = peer2.api.ReplyFriendRequest(authRequests[0].PeerID, "peer_1", false)
a.NoError(err)

time.Sleep(500 * time.Millisecond)
Expand Down
2 changes: 1 addition & 1 deletion cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (a *Application) init() {
&cli.StringFlag{
Name: "name",
Usage: "peer name",
Required: false,
Required: true,
},
},
Before: a.initApiConnection,
Expand Down
47 changes: 47 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"path/filepath"
Expand All @@ -25,6 +26,8 @@ const (
// TODO 8989 maybe?
DefaultHTTPPort = 8639
HttpServerDomainName = "admin"

DefaultPeerAlias = "peer"
)

type (
Expand Down Expand Up @@ -97,6 +100,24 @@ func (c *Config) Save() {
c.RUnlock()
}

func (c *Config) IsUniqPeerAlias(alias string) bool {
c.RLock()
defer c.RUnlock()
for _, kPeer := range c.KnownPeers {
if kPeer.Alias == alias {
return false
}
}
return true
}

func (c *Config) GenUniqPeerAlias(name, alias string) string {
c.RLock()
alias = c.genUniqPeerAlias(name, alias, nil)
c.RUnlock()
return alias
}

func (c *Config) KnownPeersIds() []peer.ID {
c.RLock()
ids := make([]peer.ID, 0, len(c.KnownPeers))
Expand Down Expand Up @@ -332,6 +353,32 @@ func (c *Config) path() string {
return path
}

func (c *Config) genUniqPeerAlias(name, alias string, uniqAliases map[string]struct{}) string {
if alias == "" {
if name == "" {
alias = DefaultPeerAlias
} else {
alias = name
}
}
if uniqAliases == nil {
uniqAliases = make(map[string]struct{}, len(c.KnownPeers)+1)
for _, kPeer := range c.KnownPeers {
uniqAliases[kPeer.Alias] = struct{}{}
}
}
if _, ok := uniqAliases[alias]; ok {
newAlias := ""
for i := 0; ok; i++ {
newAlias = fmt.Sprintf("%s_%d", alias, i)
_, ok = uniqAliases[newAlias]
}
alias = newAlias
}
uniqAliases[alias] = struct{}{}
return alias
}

func (kp KnownPeer) PeerId() peer.ID {
peerID, err := peer.Decode(kp.PeerID)
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions config/other.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,17 @@ func setDefaults(conf *Config, bus awlevent.Bus) {
conf.VPNConfig.InterfaceName = defaultInterfaceName
}

uniqAliases := make(map[string]struct{}, len(conf.KnownPeers))
if conf.KnownPeers == nil {
conf.KnownPeers = make(map[string]KnownPeer)
}
for peerID := range conf.KnownPeers {
peer := conf.KnownPeers[peerID]
newAlias := conf.genUniqPeerAlias(peer.Name, peer.Alias, uniqAliases)
if newAlias != peer.Alias {
logger.Warnf("incorrect config: peer (id: %s) alias %s is not unique, updated automaticaly to %s", peerID, peer.Alias, newAlias)
peer.Alias = newAlias
}
if peer.IPAddr == "" {
peer.IPAddr = conf.GenerateNextIpAddr()
}
Expand Down
Loading

0 comments on commit 6b61e94

Please sign in to comment.