88 "fmt"
99 "net"
1010 "strconv"
11+ "strings"
1112 "sync"
1213 "sync/atomic"
1314 "time"
@@ -164,7 +165,7 @@ type ServerPeer struct {
164165 connReq * connmgr.ConnReq
165166 server * ChainService
166167 persistent bool
167- knownAddresses map [ string ] struct {}
168+ knownAddresses * lru. Cache
168169 quit chan struct {}
169170
170171 // The following map of subcribers is used to subscribe to messages
@@ -186,7 +187,7 @@ func newServerPeer(s *ChainService, isPersistent bool) *ServerPeer {
186187 return & ServerPeer {
187188 server : s ,
188189 persistent : isPersistent ,
189- knownAddresses : make ( map [ string ] struct {} ),
190+ knownAddresses : lru . NewCache ( 5000 ),
190191 quit : make (chan struct {}),
191192 recvSubscribers : make (map [spMsgSubscription ]struct {}),
192193 recvSubscribers2 : make (map [msgSubscription ]struct {}),
@@ -206,9 +207,14 @@ func (sp *ServerPeer) newestBlock() (*chainhash.Hash, int32, error) {
206207
207208// addKnownAddresses adds the given addresses to the set of known addresses to
208209// the peer to prevent sending duplicate addresses.
209- func (sp * ServerPeer ) addKnownAddresses (addresses []* wire.NetAddress ) {
210+ func (sp * ServerPeer ) addKnownAddresses (addresses []* wire.NetAddressV2 ) {
210211 for _ , na := range addresses {
211- sp .knownAddresses [addrmgr .NetAddressKey (na )] = struct {}{}
212+ _ , err := sp .knownAddresses .Put (
213+ addrmgr .NetAddressKey (na ), & cachedAddr {},
214+ )
215+ if err != nil {
216+ log .Debugf ("Could not store known addresses: %v" , err )
217+ }
212218 }
213219}
214220
@@ -344,7 +350,7 @@ func (sp *ServerPeer) OnAddr(_ *peer.Peer, msg *wire.MsgAddr) {
344350 return
345351 }
346352
347- addrsSupportingServices := make ([]* wire.NetAddress , 0 , len (msg .AddrList ))
353+ addrs := make ([]* wire.NetAddressV2 , 0 , len (msg .AddrList ))
348354 for _ , na := range msg .AddrList {
349355 // Don't add more address if we're disconnecting.
350356 if ! sp .Connected () {
@@ -356,32 +362,88 @@ func (sp *ServerPeer) OnAddr(_ *peer.Peer, msg *wire.MsgAddr) {
356362 continue
357363 }
358364
359- // Set the timestamp to 5 days ago if it's more than 24 hours
365+ // Set the timestamp to 5 days ago if it's more than 10 minutes
360366 // in the future so this address is one of the first to be
361367 // removed when space is needed.
362368 now := time .Now ()
363369 if na .Timestamp .After (now .Add (time .Minute * 10 )) {
364370 na .Timestamp = now .Add (- 1 * time .Hour * 24 * 5 )
365371 }
366372
367- addrsSupportingServices = append (addrsSupportingServices , na )
373+ // Convert the wire.NetAddress to wire.NetAddressV2 since that
374+ // is what is used by the addrmgr.
375+ currentNa := wire .NetAddressV2FromBytes (
376+ na .Timestamp , na .Services , na .IP , na .Port ,
377+ )
378+ addrs = append (addrs , currentNa )
368379 }
369380
370381 // Ignore any addr messages if none of them contained our required
371382 // services.
372- if len (addrsSupportingServices ) == 0 {
383+ if len (addrs ) == 0 {
373384 return
374385 }
375386
376- // Add address to known addresses for this peer.
377- sp .addKnownAddresses (addrsSupportingServices )
387+ // Add addresses to the set of known addresses for this peer.
388+ sp .addKnownAddresses (addrs )
378389
379390 // Add addresses to server address manager. The address manager handles
380391 // the details of things such as preventing duplicate addresses, max
381392 // addresses, and last seen updates.
382393 // XXX bitcoind gives a 2 hour time penalty here, do we want to do the
383394 // same?
384- sp .server .addrManager .AddAddresses (addrsSupportingServices , sp .NA ())
395+ sp .server .addrManager .AddAddresses (addrs , sp .NA ())
396+ }
397+
398+ // OnAddrV2 is called when a peer receives an AddrV2 message from its peer.
399+ func (sp * ServerPeer ) OnAddrV2 (_ * peer.Peer , msg * wire.MsgAddrV2 ) {
400+ // Ignore addresses when running on a private development network for
401+ // the same reason that OnAddr does.
402+ if isDevNetwork (sp .server .chainParams .Net ) {
403+ return
404+ }
405+
406+ // An empty AddrV2 message is invalid.
407+ if len (msg .AddrList ) == 0 {
408+ log .Errorf ("Command [%s] from %s does not contain any " +
409+ "addresses" , msg .Command (), sp .Addr ())
410+ sp .Disconnect ()
411+ return
412+ }
413+
414+ addrs := make ([]* wire.NetAddressV2 , 0 , len (msg .AddrList ))
415+ for _ , na := range msg .AddrList {
416+ // Don't add more addresses if we're disconnecting.
417+ if ! sp .Connected () {
418+ return
419+ }
420+
421+ // Skip any that don't advertise our required services.
422+ if na .Services & RequiredServices != RequiredServices {
423+ continue
424+ }
425+
426+ // Set the timestamp to 5 days ago if it's more than 10 minutes
427+ // in the future so this address is one of the first to be
428+ // removed when space is needed.
429+ now := time .Now ()
430+ if na .Timestamp .After (now .Add (time .Minute * 10 )) {
431+ na .Timestamp = now .Add (- 1 * time .Hour * 24 * 5 )
432+ }
433+ addrs = append (addrs , na )
434+ }
435+
436+ // Ignore addrv2 message if no addresses contained our required
437+ // services.
438+ if len (addrs ) == 0 {
439+ return
440+ }
441+
442+ // Add the addresses to the set of known addresses for this peer.
443+ sp .addKnownAddresses (addrs )
444+
445+ // Add addresses to the address manager.
446+ sp .server .addrManager .AddAddresses (addrs , sp .NA ())
385447}
386448
387449// OnRead is invoked when a peer receives a message and it is used to update
@@ -1077,8 +1139,8 @@ func (s *ChainService) peerHandler() {
10771139 if ! DisableDNSSeed {
10781140 // Add peers discovered through DNS to the address manager.
10791141 connmgr .SeedFromDNS (& s .chainParams , RequiredServices ,
1080- s .nameResolver , func (addrs []* wire.NetAddress ) {
1081- var validAddrs []* wire.NetAddress
1142+ s .nameResolver , func (addrs []* wire.NetAddressV2 ) {
1143+ var validAddrs []* wire.NetAddressV2
10821144 for _ , addr := range addrs {
10831145 addr .Services = RequiredServices
10841146
@@ -1162,6 +1224,12 @@ func (s *ChainService) addrStringToNetAddr(addr string) (net.Addr, error) {
11621224 }
11631225 }
11641226
1227+ // Tor addresses cannot be resolved to an IP, so just return onionAddr
1228+ // instead.
1229+ if strings .HasSuffix (host , ".onion" ) {
1230+ return & onionAddr {addr : addr }, nil
1231+ }
1232+
11651233 // Attempt to look up an IP address associated with the parsed host.
11661234 ips , err := s .nameResolver (host )
11671235 if err != nil {
@@ -1283,7 +1351,7 @@ func (s *ChainService) handleAddPeerMsg(state *peerState, sp *ServerPeer) bool {
12831351
12841352 // Add the address to the addr manager anew, and also mark it as
12851353 // a good address.
1286- s .addrManager .AddAddresses ([]* wire.NetAddress {sp .NA ()}, sp .NA ())
1354+ s .addrManager .AddAddresses ([]* wire.NetAddressV2 {sp .NA ()}, sp .NA ())
12871355 s .addrManager .Good (sp .NA ())
12881356 }
12891357
@@ -1411,6 +1479,7 @@ func newPeerConfig(sp *ServerPeer) *peer.Config {
14111479 OnReject : sp .OnReject ,
14121480 OnFeeFilter : sp .OnFeeFilter ,
14131481 OnAddr : sp .OnAddr ,
1482+ OnAddrV2 : sp .OnAddrV2 ,
14141483 OnRead : sp .OnRead ,
14151484 OnWrite : sp .OnWrite ,
14161485
@@ -1426,7 +1495,7 @@ func newPeerConfig(sp *ServerPeer) *peer.Config {
14261495 UserAgentVersion : sp .server .userAgentVersion ,
14271496 ChainParams : & sp .server .chainParams ,
14281497 Services : sp .server .services ,
1429- ProtocolVersion : wire .FeeFilterVersion ,
1498+ ProtocolVersion : wire .AddrV2Version ,
14301499 DisableRelayTx : true ,
14311500 }
14321501}
@@ -1650,3 +1719,32 @@ func (s *RescanChainSource) Subscribe(
16501719
16511720 return s .blockSubscriptionMgr .NewSubscription (bestHeight )
16521721}
1722+
1723+ // cachedAddr is an empty struct used to satisfy the cache.Value interface.
1724+ type cachedAddr struct {}
1725+
1726+ // Size returns the size of cachedAddr, which is 1.
1727+ func (c * cachedAddr ) Size () (uint64 , error ) {
1728+ return 1 , nil
1729+ }
1730+
1731+ // onionAddr implements the net.Addr interface and represents a tor address.
1732+ // This code is identical to btcd's unexported onionAddr. It is used so that
1733+ // neutrino can connect to v2 addresses without relying on the OnionCat
1734+ // encoding. It also enables connecting to v3 addresses.
1735+ type onionAddr struct {
1736+ addr string
1737+ }
1738+
1739+ // String returns the onion address.
1740+ func (o * onionAddr ) String () string {
1741+ return o .addr
1742+ }
1743+
1744+ // Network returns "onion".
1745+ func (o * onionAddr ) Network () string {
1746+ return "onion"
1747+ }
1748+
1749+ // Ensure onionAddr implements the net.Addr interface.
1750+ var _ net.Addr = (* onionAddr )(nil )
0 commit comments