Bugfix for issue #101.
This commit is contained in:
parent
049a545427
commit
a55ea104c7
1 changed files with 18 additions and 7 deletions
25
peer.go
25
peer.go
|
@ -144,6 +144,7 @@ type peer struct {
|
||||||
disconnect int32 // only to be used atomically
|
disconnect int32 // only to be used atomically
|
||||||
persistent bool
|
persistent bool
|
||||||
versionKnown bool
|
versionKnown bool
|
||||||
|
versionMutex sync.Mutex
|
||||||
knownAddresses map[string]bool
|
knownAddresses map[string]bool
|
||||||
knownInventory *MruInventoryMap
|
knownInventory *MruInventoryMap
|
||||||
knownInvMutex sync.Mutex
|
knownInvMutex sync.Mutex
|
||||||
|
@ -199,6 +200,15 @@ func (p *peer) AddKnownInventory(invVect *btcwire.InvVect) {
|
||||||
p.knownInventory.Add(invVect)
|
p.knownInventory.Add(invVect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VersionKnown returns the whether or not the version of a peer is known locally.
|
||||||
|
// It is safe for concurrent access.
|
||||||
|
func (p *peer) VersionKnown() bool {
|
||||||
|
p.versionMutex.Lock()
|
||||||
|
defer p.versionMutex.Unlock()
|
||||||
|
|
||||||
|
return p.versionKnown
|
||||||
|
}
|
||||||
|
|
||||||
// pushVersionMsg sends a version message to the connected peer using the
|
// pushVersionMsg sends a version message to the connected peer using the
|
||||||
// current state.
|
// current state.
|
||||||
func (p *peer) pushVersionMsg() error {
|
func (p *peer) pushVersionMsg() error {
|
||||||
|
@ -265,9 +275,11 @@ func (p *peer) handleVersionMsg(msg *btcwire.MsgVersion) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit to one version message per peer.
|
// Limit to one version message per peer.
|
||||||
|
p.versionMutex.Lock()
|
||||||
if p.versionKnown {
|
if p.versionKnown {
|
||||||
p.logError("Only one version message per peer is allowed %s.",
|
p.logError("Only one version message per peer is allowed %s.",
|
||||||
p)
|
p)
|
||||||
|
p.versionMutex.Unlock()
|
||||||
p.Disconnect()
|
p.Disconnect()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -275,6 +287,7 @@ func (p *peer) handleVersionMsg(msg *btcwire.MsgVersion) {
|
||||||
// Negotiate the protocol version.
|
// Negotiate the protocol version.
|
||||||
p.protocolVersion = minUint32(p.protocolVersion, uint32(msg.ProtocolVersion))
|
p.protocolVersion = minUint32(p.protocolVersion, uint32(msg.ProtocolVersion))
|
||||||
p.versionKnown = true
|
p.versionKnown = true
|
||||||
|
p.versionMutex.Unlock()
|
||||||
peerLog.Debugf("Negotiated protocol version %d for peer %s",
|
peerLog.Debugf("Negotiated protocol version %d for peer %s",
|
||||||
p.protocolVersion, p)
|
p.protocolVersion, p)
|
||||||
p.lastBlock = msg.LastBlock
|
p.lastBlock = msg.LastBlock
|
||||||
|
@ -988,7 +1001,7 @@ func (p *peer) writeMessage(msg btcwire.Message) {
|
||||||
if atomic.LoadInt32(&p.disconnect) != 0 {
|
if atomic.LoadInt32(&p.disconnect) != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !p.versionKnown {
|
if !p.VersionKnown() {
|
||||||
switch msg.(type) {
|
switch msg.(type) {
|
||||||
case *btcwire.MsgVersion:
|
case *btcwire.MsgVersion:
|
||||||
// This is OK.
|
// This is OK.
|
||||||
|
@ -1066,9 +1079,7 @@ func (p *peer) inHandler() {
|
||||||
// timeframe than a general idle timeout. The timer is then reset below
|
// timeframe than a general idle timeout. The timer is then reset below
|
||||||
// to idleTimeoutMinutes for all future messages.
|
// to idleTimeoutMinutes for all future messages.
|
||||||
idleTimer := time.AfterFunc(negotiateTimeoutSeconds*time.Second, func() {
|
idleTimer := time.AfterFunc(negotiateTimeoutSeconds*time.Second, func() {
|
||||||
// XXX technically very very very slightly racy, doesn't really
|
if p.VersionKnown() {
|
||||||
// matter.
|
|
||||||
if p.versionKnown {
|
|
||||||
peerLog.Warnf("Peer %s no answer for %d minutes, "+
|
peerLog.Warnf("Peer %s no answer for %d minutes, "+
|
||||||
"disconnecting", p, idleTimeoutMinutes)
|
"disconnecting", p, idleTimeoutMinutes)
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1112,7 @@ out:
|
||||||
p.lastRecv = time.Now()
|
p.lastRecv = time.Now()
|
||||||
|
|
||||||
// Ensure version message comes first.
|
// Ensure version message comes first.
|
||||||
if _, ok := rmsg.(*btcwire.MsgVersion); !ok && !p.versionKnown {
|
if _, ok := rmsg.(*btcwire.MsgVersion); !ok && !p.VersionKnown() {
|
||||||
p.logError("A version message must precede all others")
|
p.logError("A version message must precede all others")
|
||||||
break out
|
break out
|
||||||
}
|
}
|
||||||
|
@ -1193,7 +1204,7 @@ out:
|
||||||
p.server.donePeers <- p
|
p.server.donePeers <- p
|
||||||
|
|
||||||
// Only tell block manager we are gone if we ever told it we existed.
|
// Only tell block manager we are gone if we ever told it we existed.
|
||||||
if p.versionKnown {
|
if p.VersionKnown() {
|
||||||
p.server.blockManager.DonePeer(p)
|
p.server.blockManager.DonePeer(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,7 +1269,7 @@ out:
|
||||||
|
|
||||||
case iv := <-p.outputInvChan:
|
case iv := <-p.outputInvChan:
|
||||||
// No handshake? They'll find out soon enough.
|
// No handshake? They'll find out soon enough.
|
||||||
if p.versionKnown {
|
if p.VersionKnown() {
|
||||||
invSendQueue.PushBack(iv)
|
invSendQueue.PushBack(iv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue