161 lines
3.8 KiB
Go
161 lines
3.8 KiB
Go
package rendezvous
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
db "github.com/waku-org/go-libp2p-rendezvous/db"
|
|
pb "github.com/waku-org/go-libp2p-rendezvous/pb"
|
|
|
|
logging "github.com/ipfs/go-log/v2"
|
|
crypto "github.com/libp2p/go-libp2p/core/crypto"
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
"github.com/libp2p/go-libp2p/core/protocol"
|
|
"github.com/libp2p/go-libp2p/core/record"
|
|
)
|
|
|
|
var log = logging.Logger("rendezvous")
|
|
|
|
const (
|
|
RendezvousProto = protocol.ID("/rendezvous/1.0.0")
|
|
|
|
DefaultTTL = 2 * 3600 // 2hr
|
|
)
|
|
|
|
type RendezvousError struct {
|
|
Status pb.Message_ResponseStatus
|
|
Text string
|
|
}
|
|
|
|
func (e RendezvousError) Error() string {
|
|
return fmt.Sprintf("Rendezvous error: %s (%s)", e.Text, e.Status.String())
|
|
}
|
|
|
|
func NewRegisterMessage(privKey crypto.PrivKey, ns string, pi peer.AddrInfo, ttl int) (*pb.Message, error) {
|
|
return newRegisterMessage(privKey, ns, pi, ttl)
|
|
}
|
|
|
|
func newRegisterMessage(privKey crypto.PrivKey, ns string, pi peer.AddrInfo, ttl int) (*pb.Message, error) {
|
|
msg := new(pb.Message)
|
|
msg.Type = pb.Message_REGISTER.Enum()
|
|
msg.Register = new(pb.Message_Register)
|
|
if ns != "" {
|
|
msg.Register.Ns = &ns
|
|
}
|
|
if ttl > 0 {
|
|
ttlu64 := uint64(ttl)
|
|
msg.Register.Ttl = &ttlu64
|
|
}
|
|
|
|
peerInfo := &peer.PeerRecord{
|
|
PeerID: pi.ID,
|
|
Addrs: pi.Addrs,
|
|
Seq: uint64(time.Now().Unix()),
|
|
}
|
|
|
|
envelope, err := record.Seal(peerInfo, privKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
envPayload, err := envelope.Marshal()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
msg.Register.SignedPeerRecord = envPayload
|
|
|
|
return msg, nil
|
|
}
|
|
|
|
func newUnregisterMessage(ns string, pid peer.ID) *pb.Message {
|
|
msg := new(pb.Message)
|
|
msg.Type = pb.Message_UNREGISTER.Enum()
|
|
msg.Unregister = new(pb.Message_Unregister)
|
|
if ns != "" {
|
|
msg.Unregister.Ns = &ns
|
|
}
|
|
return msg
|
|
}
|
|
|
|
func NewDiscoverMessage(ns string, limit int, cookie []byte) *pb.Message {
|
|
return newDiscoverMessage(ns, limit, cookie)
|
|
}
|
|
|
|
func newDiscoverMessage(ns string, limit int, cookie []byte) *pb.Message {
|
|
msg := new(pb.Message)
|
|
msg.Type = pb.Message_DISCOVER.Enum()
|
|
msg.Discover = new(pb.Message_Discover)
|
|
if ns != "" {
|
|
msg.Discover.Ns = &ns
|
|
}
|
|
if limit > 0 {
|
|
limitu64 := uint64(limit)
|
|
msg.Discover.Limit = &limitu64
|
|
}
|
|
if cookie != nil {
|
|
msg.Discover.Cookie = cookie
|
|
}
|
|
return msg
|
|
}
|
|
func pbToPeerRecord(envelopeBytes []byte) (peer.AddrInfo, error) {
|
|
envelope, rec, err := record.ConsumeEnvelope(envelopeBytes, peer.PeerRecordEnvelopeDomain)
|
|
if err != nil {
|
|
return peer.AddrInfo{}, err
|
|
}
|
|
|
|
peerRec, ok := rec.(*peer.PeerRecord)
|
|
if !ok {
|
|
return peer.AddrInfo{}, errors.New("invalid peer record")
|
|
}
|
|
|
|
if !peerRec.PeerID.MatchesPublicKey(envelope.PublicKey) {
|
|
return peer.AddrInfo{}, errors.New("signing key does not match peer record")
|
|
}
|
|
|
|
return peer.AddrInfo{ID: peerRec.PeerID, Addrs: peerRec.Addrs}, nil
|
|
}
|
|
|
|
func newRegisterResponse(ttl int) *pb.Message_RegisterResponse {
|
|
ttlu64 := uint64(ttl)
|
|
r := new(pb.Message_RegisterResponse)
|
|
r.Status = pb.Message_OK.Enum()
|
|
r.Ttl = &ttlu64
|
|
return r
|
|
}
|
|
|
|
func newRegisterResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_RegisterResponse {
|
|
r := new(pb.Message_RegisterResponse)
|
|
r.Status = status.Enum()
|
|
r.StatusText = &text
|
|
return r
|
|
}
|
|
|
|
func newDiscoverResponse(regs []db.RegistrationRecord, cookie []byte) *pb.Message_DiscoverResponse {
|
|
r := new(pb.Message_DiscoverResponse)
|
|
r.Status = pb.Message_OK.Enum()
|
|
|
|
rregs := make([]*pb.Message_Register, len(regs))
|
|
for i, reg := range regs {
|
|
rreg := new(pb.Message_Register)
|
|
rreg.Ns = ®.Ns
|
|
rreg.SignedPeerRecord = reg.SignedPeerRecord
|
|
rttl := uint64(reg.Ttl)
|
|
rreg.Ttl = &rttl
|
|
rregs[i] = rreg
|
|
}
|
|
|
|
r.Registrations = rregs
|
|
r.Cookie = cookie
|
|
|
|
return r
|
|
}
|
|
|
|
func newDiscoverResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_DiscoverResponse {
|
|
r := new(pb.Message_DiscoverResponse)
|
|
r.Status = status.Enum()
|
|
r.StatusText = &text
|
|
return r
|
|
}
|