mirror of
https://github.com/hyprspace/hyprspace.git
synced 2026-09-12 19:51:07 +05:00
fix(config): error on ambiguous peer ID prefix (#113)
FindPeerByIDPrefix previously returned the first peer whose ID started with the given prefix, silently ignoring further matches. With Ed25519 peer IDs all sharing the leading "12D3KooW" (8 chars), short prefixes can match multiple peers; the chosen peer then depends on slice order, which is effectively undefined from the user's perspective. Change FindPeerByIDPrefix and its wrapper FindPeerByCLIRef to return (*Peer, error): - 0 matches -> (nil, nil) - 1 match -> (&peer, nil) - 2+ match -> (nil, error) describing the ambiguity Call sites in config.Read and rpc/server.go updated accordingly: ambiguity surfaces as a config-load / CLI error instead of a silent wrong-peer resolution. Not a wire-protocol or config-format change. Only behavior visible at CLI invocation and config load. Users relying on short prefixes that happened to match multiple peers will now see a clear error and must lengthen the prefix.
This commit is contained in:
parent
71eeca5801
commit
3f573ef293
@ -166,15 +166,21 @@ func Read(path string) (*Config, error) {
|
||||
whitelist := make(map[peer.ID]struct{})
|
||||
blacklist := make(map[peer.ID]struct{})
|
||||
for _, p := range service.Acl.Whitelist {
|
||||
cfgPeer, found := FindPeerByCLIRef(result.Peers, p)
|
||||
if !found {
|
||||
cfgPeer, err := FindPeerByCLIRef(result.Peers, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cfgPeer == nil {
|
||||
return nil, errors.New("unknown peer: " + p)
|
||||
}
|
||||
whitelist[cfgPeer.ID] = struct{}{}
|
||||
}
|
||||
for _, peerStr := range service.Acl.Blacklist {
|
||||
cfgPeer, found := FindPeerByCLIRef(result.Peers, peerStr)
|
||||
if !found {
|
||||
cfgPeer, err := FindPeerByCLIRef(result.Peers, peerStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cfgPeer == nil {
|
||||
return nil, errors.New("unknown peer: " + peerStr)
|
||||
}
|
||||
blacklist[cfgPeer.ID] = struct{}{}
|
||||
@ -212,22 +218,34 @@ func FindPeerByName(peers []Peer, needle string) (*Peer, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func FindPeerByIDPrefix(peers []Peer, needle string) (*Peer, bool) {
|
||||
for _, p := range peers {
|
||||
if strings.HasPrefix(p.ID.String(), needle) {
|
||||
return &p, true
|
||||
// FindPeerByIDPrefix returns the unique peer whose ID starts with needle.
|
||||
// Returns (nil, nil) if no peer matches.
|
||||
// Returns (nil, error) if more than one peer matches (ambiguous prefix).
|
||||
func FindPeerByIDPrefix(peers []Peer, needle string) (*Peer, error) {
|
||||
var match *Peer
|
||||
count := 0
|
||||
for i := range peers {
|
||||
if strings.HasPrefix(peers[i].ID.String(), needle) {
|
||||
match = &peers[i]
|
||||
count++
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
if count > 1 {
|
||||
return nil, fmt.Errorf("ambiguous peer prefix %q matches %d peers", needle, count)
|
||||
}
|
||||
return match, nil
|
||||
}
|
||||
|
||||
func FindPeerByCLIRef(peers []Peer, needle string) (*Peer, bool) {
|
||||
// FindPeerByCLIRef resolves a CLI peer reference: "@name" for name lookup,
|
||||
// otherwise a peer ID prefix. Returns (nil, nil) on no match,
|
||||
// (nil, error) only on ambiguous ID prefix.
|
||||
func FindPeerByCLIRef(peers []Peer, needle string) (*Peer, error) {
|
||||
if strings.HasPrefix(needle, "@") {
|
||||
name := strings.TrimPrefix(needle, "@")
|
||||
return FindPeerByName(peers, name)
|
||||
} else {
|
||||
return FindPeerByIDPrefix(peers, needle)
|
||||
p, _ := FindPeerByName(peers, name)
|
||||
return p, nil
|
||||
}
|
||||
return FindPeerByIDPrefix(peers, needle)
|
||||
}
|
||||
|
||||
func (cfg Config) FindRoute(needle net.IPNet) (*RouteTableEntry, bool) {
|
||||
|
||||
@ -120,8 +120,11 @@ func (hsr *HyprspaceRPC) Route(args *RouteArgs, reply *RouteReply) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target, found := config.FindPeerByCLIRef(hsr.config.Peers, args.Args[1])
|
||||
if !found {
|
||||
target, err := config.FindPeerByCLIRef(hsr.config.Peers, args.Args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if target == nil {
|
||||
return errors.New("no such peer")
|
||||
}
|
||||
err = hsr.tunDev.Apply(tun.Route(*network))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user