mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-29 09:34:03 +08:00
spipe + handshake with peerstore
This commit is contained in:
@ -90,23 +90,18 @@ func (s *SecurePipe) handshake() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.remote.PubKey, err = ci.UnmarshalPublicKey(proposeResp.GetPubkey())
|
// get remote identity
|
||||||
|
remotePubKey, err := ci.UnmarshalPublicKey(proposeResp.GetPubkey())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteID, err := IDFromPubKey(s.remote.PubKey)
|
// get or construct peer
|
||||||
|
s.remote, err = getOrConstructPeer(s.peers, remotePubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
u.DOut("[%s] Remote Peer Identified as %s\n", s.local.ID.Pretty(), s.remote.ID.Pretty())
|
||||||
if s.remote.ID != nil && !remoteID.Equal(s.remote.ID) {
|
|
||||||
e := "Expected pubkey does not match sent pubkey: %v - %v"
|
|
||||||
return fmt.Errorf(e, s.remote.ID.Pretty(), remoteID.Pretty())
|
|
||||||
} else if s.remote.ID == nil {
|
|
||||||
s.remote.ID = remoteID
|
|
||||||
}
|
|
||||||
// u.POut("Remote Peer Identified as %s\n", s.remote.ID.Pretty())
|
|
||||||
|
|
||||||
exchange, err := selectBest(SupportedExchanges, proposeResp.GetExchanges())
|
exchange, err := selectBest(SupportedExchanges, proposeResp.GetExchanges())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -340,3 +335,62 @@ func selectBest(myPrefs, theirPrefs string) (string, error) {
|
|||||||
|
|
||||||
return "", errors.New("No algorithms in common!")
|
return "", errors.New("No algorithms in common!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getOrConstructPeer attempts to fetch a peer from a peerstore.
|
||||||
|
// if succeeds, verify ID and PubKey match.
|
||||||
|
// else, construct it.
|
||||||
|
func getOrConstructPeer(peers peer.Peerstore, rpk ci.PubKey) (*peer.Peer, error) {
|
||||||
|
|
||||||
|
rid, err := IDFromPubKey(rpk)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
npeer, err := peers.Get(rid)
|
||||||
|
if err != nil {
|
||||||
|
if err != peer.ErrNotFound {
|
||||||
|
return nil, err // unexpected error happened.
|
||||||
|
}
|
||||||
|
|
||||||
|
// dont have peer, so construct it + add it to peerstore.
|
||||||
|
npeer = &peer.Peer{ID: rid, PubKey: rpk}
|
||||||
|
if err := peers.Put(npeer); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// done, return the newly constructed peer.
|
||||||
|
return npeer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// did have it locally.
|
||||||
|
|
||||||
|
// let's verify ID
|
||||||
|
if !npeer.ID.Equal(rid) {
|
||||||
|
e := "Expected peer.ID does not match sent pubkey's hash: %v - %v"
|
||||||
|
return nil, fmt.Errorf(e, npeer.ID.Pretty(), rid.Pretty())
|
||||||
|
}
|
||||||
|
|
||||||
|
if npeer.PubKey == nil {
|
||||||
|
// didn't have a pubkey, just set it.
|
||||||
|
npeer.PubKey = rpk
|
||||||
|
return npeer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// did have pubkey, let's verify it's really the same.
|
||||||
|
// this shouldn't ever happen, given we hashed, etc, but it could mean
|
||||||
|
// expected code (or protocol) invariants violated.
|
||||||
|
|
||||||
|
lb, err1 := npeer.PubKey.Bytes()
|
||||||
|
if err1 != nil {
|
||||||
|
return nil, err1
|
||||||
|
}
|
||||||
|
rb, err2 := rpk.Bytes()
|
||||||
|
if err2 != nil {
|
||||||
|
return nil, err2
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(lb, rb) {
|
||||||
|
return nil, fmt.Errorf("WARNING: PubKey mismatch: %v", npeer.ID.Pretty())
|
||||||
|
}
|
||||||
|
return npeer, nil
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ type SecurePipe struct {
|
|||||||
|
|
||||||
local *peer.Peer
|
local *peer.Peer
|
||||||
remote *peer.Peer
|
remote *peer.Peer
|
||||||
|
peers peer.Peerstore
|
||||||
|
|
||||||
params params
|
params params
|
||||||
|
|
||||||
@ -32,16 +33,16 @@ type params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewSecurePipe constructs a pipe with channels of a given buffer size.
|
// NewSecurePipe constructs a pipe with channels of a given buffer size.
|
||||||
func NewSecurePipe(ctx context.Context, bufsize int, local,
|
func NewSecurePipe(ctx context.Context, bufsize int, local *peer.Peer,
|
||||||
remote *peer.Peer) (*SecurePipe, error) {
|
peers peer.Peerstore) (*SecurePipe, error) {
|
||||||
|
|
||||||
sp := &SecurePipe{
|
sp := &SecurePipe{
|
||||||
Duplex: Duplex{
|
Duplex: Duplex{
|
||||||
In: make(chan []byte, bufsize),
|
In: make(chan []byte, bufsize),
|
||||||
Out: make(chan []byte, bufsize),
|
Out: make(chan []byte, bufsize),
|
||||||
},
|
},
|
||||||
local: local,
|
local: local,
|
||||||
remote: remote,
|
peers: peers,
|
||||||
}
|
}
|
||||||
return sp, nil
|
return sp, nil
|
||||||
}
|
}
|
||||||
@ -63,6 +64,16 @@ func (s *SecurePipe) Wrap(ctx context.Context, insecure Duplex) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LocalPeer retrieves the local peer.
|
||||||
|
func (s *SecurePipe) LocalPeer() *peer.Peer {
|
||||||
|
return s.local
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemotePeer retrieves the local peer.
|
||||||
|
func (s *SecurePipe) RemotePeer() *peer.Peer {
|
||||||
|
return s.remote
|
||||||
|
}
|
||||||
|
|
||||||
// Close closes the secure pipe
|
// Close closes the secure pipe
|
||||||
func (s *SecurePipe) Close() error {
|
func (s *SecurePipe) Close() error {
|
||||||
if s.cancel == nil {
|
if s.cancel == nil {
|
||||||
|
Reference in New Issue
Block a user