2019-12-30 17:54:38 -08:00
|
|
|
package zcash
|
|
|
|
|
|
|
|
import (
|
2020-05-20 15:08:34 -07:00
|
|
|
"runtime"
|
2019-12-30 17:54:38 -08:00
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/btcsuite/btcd/addrmgr"
|
|
|
|
"github.com/btcsuite/btcd/peer"
|
|
|
|
"github.com/btcsuite/btcd/wire"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (s *Seeder) onVerAck(p *peer.Peer, msg *wire.MsgVerAck) {
|
2020-05-20 15:08:34 -07:00
|
|
|
pk := peerKeyFromPeer(p)
|
|
|
|
|
2019-12-30 17:54:38 -08:00
|
|
|
// Check if we're expecting to hear from this peer
|
2020-05-20 15:08:34 -07:00
|
|
|
_, ok := s.pendingPeers.Load(pk)
|
2019-12-30 17:54:38 -08:00
|
|
|
|
|
|
|
if !ok {
|
|
|
|
s.logger.Printf("Got verack from unexpected peer %s", p.Addr())
|
2020-05-20 15:08:34 -07:00
|
|
|
// TODO: probably want to disconnect from the peer sending us out-of-order veracks
|
2019-12-30 17:54:38 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add to set of live peers
|
2020-05-20 15:08:34 -07:00
|
|
|
s.livePeers.Store(pk, p)
|
2019-12-30 17:54:38 -08:00
|
|
|
|
|
|
|
// Remove from set of pending peers
|
2020-05-20 15:08:34 -07:00
|
|
|
s.pendingPeers.Delete(pk)
|
2019-12-30 17:54:38 -08:00
|
|
|
|
|
|
|
// Signal successful connection
|
2020-05-20 15:08:34 -07:00
|
|
|
if signal, ok := s.handshakeSignals.Load(pk); ok {
|
2019-12-30 17:54:38 -08:00
|
|
|
signal.(chan struct{}) <- struct{}{}
|
|
|
|
} else {
|
|
|
|
s.logger.Printf("Got verack from peer without a callback channel: %s", p.Addr())
|
2020-05-20 15:08:34 -07:00
|
|
|
s.DisconnectPeer(pk)
|
2019-12-30 17:54:38 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-05-20 15:40:43 -07:00
|
|
|
// If we've already connected to this peer, update the last-valid time.
|
2020-05-20 15:08:34 -07:00
|
|
|
if s.addrBook.IsKnown(pk) {
|
|
|
|
s.addrBook.Touch(pk)
|
2019-12-30 17:54:38 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Seeder) onAddr(p *peer.Peer, msg *wire.MsgAddr) {
|
|
|
|
if len(msg.AddrList) == 0 {
|
|
|
|
s.logger.Printf("Got empty addr message from peer %s. Disconnecting.", p.Addr())
|
|
|
|
s.DisconnectPeer(peerKeyFromPeer(p))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
s.logger.Printf("Got %d addrs from peer %s", len(msg.AddrList), p.Addr())
|
|
|
|
|
|
|
|
queue := make(chan *wire.NetAddress, len(msg.AddrList))
|
|
|
|
|
|
|
|
for _, na := range msg.AddrList {
|
|
|
|
queue <- na
|
|
|
|
}
|
|
|
|
|
2020-05-20 15:08:34 -07:00
|
|
|
for i := 0; i < runtime.NumCPU()*2; i++ {
|
2019-12-30 17:54:38 -08:00
|
|
|
go func() {
|
|
|
|
var na *wire.NetAddress
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case next := <-queue:
|
2020-05-20 15:08:34 -07:00
|
|
|
// Pull the next address off the queue
|
2019-12-30 17:54:38 -08:00
|
|
|
na = next
|
|
|
|
case <-time.After(1 * time.Second):
|
2020-05-20 15:08:34 -07:00
|
|
|
// Or die if there wasn't one
|
2019-12-30 17:54:38 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-05-20 15:08:34 -07:00
|
|
|
// Note that AllowSelfConns is only exposed in a fork of btcd
|
|
|
|
// pending https://github.com/btcsuite/btcd/pull/1481, which
|
|
|
|
// is why the module `replace`s btcd.
|
2019-12-30 17:54:38 -08:00
|
|
|
if !addrmgr.IsRoutable(na) && !s.config.AllowSelfConns {
|
|
|
|
s.logger.Printf("Got bad addr %s:%d from peer %s", na.IP, na.Port, p.Addr())
|
2020-05-20 15:08:34 -07:00
|
|
|
s.DisconnectAndBlacklist(peerKeyFromPeer(p))
|
2019-12-30 17:54:38 -08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-05-20 15:08:34 -07:00
|
|
|
potentialPeer := peerKeyFromNA(na)
|
|
|
|
|
|
|
|
if s.addrBook.IsKnown(potentialPeer) {
|
|
|
|
s.logger.Printf("Already knew about %s:%d", na.IP, na.Port)
|
2019-12-30 17:54:38 -08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-05-20 15:08:34 -07:00
|
|
|
if s.addrBook.IsBlacklisted(potentialPeer) {
|
|
|
|
s.logger.Printf("Previously blacklisted %s:%d", na.IP, na.Port)
|
2019-12-30 17:54:38 -08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
portString := strconv.Itoa(int(na.Port))
|
|
|
|
err := s.Connect(na.IP.String(), portString)
|
|
|
|
|
|
|
|
if err != nil {
|
2020-05-20 15:40:43 -07:00
|
|
|
if err == ErrRepeatConnection {
|
|
|
|
s.logger.Printf("Got duplicate peer %s:%d from peer %s. Error: %s", na.IP, na.Port, p.Addr(), err)
|
|
|
|
continue
|
|
|
|
}
|
2019-12-30 17:54:38 -08:00
|
|
|
|
2020-05-20 15:08:34 -07:00
|
|
|
// Blacklist the potential peer. We might try to connect again later,
|
|
|
|
// since we assume IsRoutable filtered out the truly wrong ones.
|
2020-05-20 15:40:43 -07:00
|
|
|
s.logger.Printf("Got unusable peer %s:%d from peer %s. Error: %s", na.IP, na.Port, p.Addr(), err)
|
2020-05-20 15:08:34 -07:00
|
|
|
s.addrBook.Blacklist(potentialPeer)
|
2019-12-30 17:54:38 -08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-05-20 15:08:34 -07:00
|
|
|
s.DisconnectPeer(potentialPeer)
|
2020-05-20 15:40:43 -07:00
|
|
|
|
|
|
|
s.logger.Printf("Successfully learned about %s:%d from %s.", na.IP, na.Port, p.Addr())
|
2020-05-20 15:08:34 -07:00
|
|
|
s.addrBook.Add(potentialPeer)
|
2019-12-30 17:54:38 -08:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
}
|