chaincfg: Introduce new type DNSSeed

DNSSeed defines a DNS Seed with a hostname and whether it supports
filtering by service flag bits.
This commit is contained in:
David Hill 2016-10-21 20:36:38 -04:00 committed by Dave Collins
parent 0d508e6522
commit f161d6b69e
3 changed files with 61 additions and 30 deletions

View file

@ -50,6 +50,16 @@ type Checkpoint struct {
Hash *chainhash.Hash
}
// DNSSeed identifies a DNS seed.
type DNSSeed struct {
// Host defines the hostname of the seed.
Host string
// HasFiltering defines whether the seed supports filtering
// by service flags (wire.ServiceFlag).
HasFiltering bool
}
// Params defines a Bitcoin network by its parameters. These parameters may be
// used by Bitcoin applications to differentiate networks as well as addresses
// and keys for one network from those intended for use on another network.
@ -65,7 +75,7 @@ type Params struct {
// DNSSeeds defines a list of DNS seeds for the network that are used
// as one method to discover peers.
DNSSeeds []string
DNSSeeds []DNSSeed
// GenesisBlock defines the first block of the chain.
GenesisBlock *wire.MsgBlock
@ -155,14 +165,14 @@ var MainNetParams = Params{
Name: "mainnet",
Net: wire.MainNet,
DefaultPort: "8333",
DNSSeeds: []string{
"seed.bitcoin.sipa.be",
"dnsseed.bluematt.me",
"dnsseed.bitcoin.dashjr.org",
"seed.bitcoinstats.com",
"seed.bitnodes.io",
"bitseed.xf2.org",
"seed.bitcoin.jonasschnelli.ch",
DNSSeeds: []DNSSeed{
{"seed.bitcoin.sipa.be", true},
{"dnsseed.bluematt.me", true},
{"dnsseed.bitcoin.dashjr.org", false},
{"seed.bitcoinstats.com", true},
{"seed.bitnodes.io", false},
{"bitseed.xf2.org", false},
{"seed.bitcoin.jonasschnelli.ch", true},
},
// Chain parameters
@ -235,7 +245,7 @@ var RegressionNetParams = Params{
Name: "regtest",
Net: wire.TestNet,
DefaultPort: "18444",
DNSSeeds: []string{},
DNSSeeds: []DNSSeed{},
// Chain parameters
GenesisBlock: &regTestGenesisBlock,
@ -288,10 +298,11 @@ var TestNet3Params = Params{
Name: "testnet3",
Net: wire.TestNet3,
DefaultPort: "18333",
DNSSeeds: []string{
"testnet-seed.bitcoin.schildbach.de",
"testnet-seed.bitcoin.petertodd.org",
"testnet-seed.bluematt.me",
DNSSeeds: []DNSSeed{
{"testnet-seed.bitcoin.jonasschnelli.ch", true},
{"testnet-seed.bitcoin.schildbach.de", false},
{"seed.tbtc.petertodd.org", true},
{"testnet-seed.bluematt.me", false},
},
// Chain parameters
@ -351,7 +362,7 @@ var SimNetParams = Params{
Name: "simnet",
Net: wire.SimNet,
DefaultPort: "18555",
DNSSeeds: []string{}, // NOTE: There must NOT be any seeds.
DNSSeeds: []DNSSeed{}, // NOTE: There must NOT be any seeds.
// Chain parameters
GenesisBlock: &simNetGenesisBlock,
@ -416,6 +427,11 @@ var (
hdPrivToPubKeyIDs = make(map[[4]byte][]byte)
)
// String returns the hostname of the DNS seed in human-readable form.
func (d DNSSeed) String() string {
return d.Host
}
// Register registers the network parameters for a Bitcoin network. This may
// error with ErrDuplicateNet if the network is already registered (either
// due to a previous Register call, or the network being one of the default

View file

@ -5,6 +5,7 @@
package connmgr
import (
"fmt"
mrand "math/rand"
"net"
"strconv"
@ -29,19 +30,28 @@ type OnSeed func(addrs []*wire.NetAddress)
type LookupFunc func(string) ([]net.IP, error)
// SeedFromDNS uses DNS seeding to populate the address manager with peers.
func SeedFromDNS(chainParams *chaincfg.Params, lookupFn LookupFunc, seedFn OnSeed) {
for _, seeder := range chainParams.DNSSeeds {
go func(seeder string) {
func SeedFromDNS(chainParams *chaincfg.Params, reqServices wire.ServiceFlag,
lookupFn LookupFunc, seedFn OnSeed) {
for _, dnsseed := range chainParams.DNSSeeds {
var host string
if !dnsseed.HasFiltering || reqServices == wire.SFNodeNetwork {
host = dnsseed.Host
} else {
host = fmt.Sprintf("x%x.%s", uint64(reqServices), dnsseed.Host)
}
go func(host string) {
randSource := mrand.New(mrand.NewSource(time.Now().UnixNano()))
seedpeers, err := lookupFn(seeder)
seedpeers, err := lookupFn(host)
if err != nil {
log.Infof("DNS discovery failed on seed %s: %v", seeder, err)
log.Infof("DNS discovery failed on seed %s: %v", host, err)
return
}
numPeers := len(seedpeers)
log.Infof("%d addresses found from DNS seed %s", numPeers, seeder)
log.Infof("%d addresses found from DNS seed %s", numPeers, host)
if numPeers == 0 {
return
@ -61,6 +71,6 @@ func SeedFromDNS(chainParams *chaincfg.Params, lookupFn LookupFunc, seedFn OnSee
}
seedFn(addresses)
}(seeder)
}(host)
}
}

View file

@ -40,6 +40,10 @@ const (
// the server.
defaultServices = wire.SFNodeNetwork | wire.SFNodeBloom
// defaultRequiredServices describes the default services that are
// required to be supported by outbound peers.
defaultRequiredServices = wire.SFNodeNetwork
// defaultMaxOutbound is the default number of max outbound peers.
defaultMaxOutbound = 8
@ -1627,14 +1631,15 @@ func (s *server) peerHandler() {
if !cfg.DisableDNSSeed {
// Add peers discovered through DNS to the address manager.
connmgr.SeedFromDNS(activeNetParams.Params, btcdLookup, func(addrs []*wire.NetAddress) {
// Bitcoind uses a lookup of the dns seeder here. This
// is rather strange since the values looked up by the
// DNS seed lookups will vary quite a lot.
// to replicate this behaviour we put all addresses as
// having come from the first one.
s.addrManager.AddAddresses(addrs, addrs[0])
})
connmgr.SeedFromDNS(activeNetParams.Params, defaultRequiredServices,
btcdLookup, func(addrs []*wire.NetAddress) {
// Bitcoind uses a lookup of the dns seeder here. This
// is rather strange since the values looked up by the
// DNS seed lookups will vary quite a lot.
// to replicate this behaviour we put all addresses as
// having come from the first one.
s.addrManager.AddAddresses(addrs, addrs[0])
})
}
go s.connManager.Start()