func TestAddLocalAddress(t *testing.T) { var tests = []struct { address btcwire.NetAddress valid bool }{ { btcwire.NetAddress{IP: net.ParseIP("192.168.0.100")}, false, }, { btcwire.NetAddress{IP: net.ParseIP("204.124.1.1")}, true, }, { btcwire.NetAddress{IP: net.ParseIP("::1")}, false, }, { btcwire.NetAddress{IP: net.ParseIP("fe80::1")}, false, }, { btcwire.NetAddress{IP: net.ParseIP("2620:100::1")}, true, }, } amgr := addrmgr.New("", nil) for x, test := range tests { result := amgr.AddLocalAddress(&test.address, addrmgr.InterfacePrio) if result == nil && !test.valid { t.Errorf("TestAddLocalAddress test #%d failed: %s should have "+ "been accepted", x, test.address.IP) continue } if result != nil && test.valid { t.Errorf("TestAddLocalAddress test #%d failed: %s should not have "+ "been accepted", x, test.address.IP) continue } } }
func TestGetBestLocalAddress(t *testing.T) { localAddrs := []btcwire.NetAddress{ {IP: net.ParseIP("192.168.0.100")}, {IP: net.ParseIP("::1")}, {IP: net.ParseIP("fe80::1")}, {IP: net.ParseIP("2001:470::1")}, } var tests = []struct { remoteAddr btcwire.NetAddress want1 btcwire.NetAddress want2 btcwire.NetAddress want3 btcwire.NetAddress }{ { // Remote connection from public IPv4 btcwire.NetAddress{IP: net.ParseIP("204.124.8.1")}, btcwire.NetAddress{IP: net.IPv4zero}, btcwire.NetAddress{IP: net.ParseIP("204.124.8.100")}, btcwire.NetAddress{IP: net.ParseIP("fd87:d87e:eb43:25::1")}, }, { // Remote connection from private IPv4 btcwire.NetAddress{IP: net.ParseIP("172.16.0.254")}, btcwire.NetAddress{IP: net.IPv4zero}, btcwire.NetAddress{IP: net.IPv4zero}, btcwire.NetAddress{IP: net.IPv4zero}, }, { // Remote connection from public IPv6 btcwire.NetAddress{IP: net.ParseIP("2602:100:abcd::102")}, btcwire.NetAddress{IP: net.ParseIP("2001:470::1")}, btcwire.NetAddress{IP: net.ParseIP("2001:470::1")}, btcwire.NetAddress{IP: net.ParseIP("2001:470::1")}, }, /* XXX { // Remote connection from Tor btcwire.NetAddress{IP: net.ParseIP("fd87:d87e:eb43::100")}, btcwire.NetAddress{IP: net.IPv4zero}, btcwire.NetAddress{IP: net.ParseIP("204.124.8.100")}, btcwire.NetAddress{IP: net.ParseIP("fd87:d87e:eb43:25::1")}, }, */ } amgr := addrmgr.New("", nil) for _, localAddr := range localAddrs { amgr.AddLocalAddress(&localAddr, addrmgr.InterfacePrio) } // Test against want1 for x, test := range tests { got := amgr.GetBestLocalAddress(&test.remoteAddr) if !test.want1.IP.Equal(got.IP) { t.Errorf("TestGetBestLocalAddress test1 #%d failed for remote address %s: want %s got %s", x, test.remoteAddr.IP, test.want1.IP, got.IP) continue } } // Add a public IP to the list of local addresses. localAddr := btcwire.NetAddress{IP: net.ParseIP("204.124.8.100")} amgr.AddLocalAddress(&localAddr, addrmgr.InterfacePrio) // Test against want2 for x, test := range tests { got := amgr.GetBestLocalAddress(&test.remoteAddr) if !test.want2.IP.Equal(got.IP) { t.Errorf("TestGetBestLocalAddress test2 #%d failed for remote address %s: want %s got %s", x, test.remoteAddr.IP, test.want2.IP, got.IP) continue } } /* // Add a tor generated IP address localAddr = btcwire.NetAddress{IP: net.ParseIP("fd87:d87e:eb43:25::1")} amgr.AddLocalAddress(&localAddr, addrmgr.ManualPrio) // Test against want3 for x, test := range tests { got := amgr.GetBestLocalAddress(&test.remoteAddr) if !test.want3.IP.Equal(got.IP) { t.Errorf("TestGetBestLocalAddress test3 #%d failed for remote address %s: want %s got %s", x, test.remoteAddr.IP, test.want3.IP, got.IP) continue } } */ }
func TestGetAddress(t *testing.T) { n := addrmgr.New("testdir", lookupFunc) if rv := n.GetAddress("any", 10); rv != nil { t.Errorf("GetAddress failed: got: %v want: %v\n", rv, nil) } }
// newServer returns a new pointcoind server configured to listen on addr for the // bitcoin network type specified by netParams. Use start to begin accepting // connections from peers. func newServer(listenAddrs []string, db database.Db, netParams *btcnet.Params) (*server, error) { nonce, err := btcwire.RandomUint64() if err != nil { return nil, err } amgr := addrmgr.New(cfg.DataDir, pointcoindLookup) var listeners []net.Listener var nat NAT if !cfg.DisableListen { ipv4Addrs, ipv6Addrs, wildcard, err := parseListeners(listenAddrs) if err != nil { return nil, err } listeners = make([]net.Listener, 0, len(ipv4Addrs)+len(ipv6Addrs)) discover := true if len(cfg.ExternalIPs) != 0 { discover = false // if this fails we have real issues. port, _ := strconv.ParseUint( activeNetParams.DefaultPort, 10, 16) for _, sip := range cfg.ExternalIPs { eport := uint16(port) host, portstr, err := net.SplitHostPort(sip) if err != nil { // no port, use default. host = sip } else { port, err := strconv.ParseUint( portstr, 10, 16) if err != nil { srvrLog.Warnf("Can not parse "+ "port from %s for "+ "externalip: %v", sip, err) continue } eport = uint16(port) } na, err := amgr.HostToNetAddress(host, eport, btcwire.SFNodeNetwork) if err != nil { srvrLog.Warnf("Not adding %s as "+ "externalip: %v", sip, err) continue } err = amgr.AddLocalAddress(na, addrmgr.ManualPrio) if err != nil { amgrLog.Warnf("Skipping specified external IP: %v", err) } } } else if discover && cfg.Upnp { nat, err = Discover() if err != nil { srvrLog.Warnf("Can't discover upnp: %v", err) } // nil nat here is fine, just means no upnp on network. } // TODO(oga) nonstandard port... if wildcard { port, err := strconv.ParseUint(activeNetParams.DefaultPort, 10, 16) if err != nil { // I can't think of a cleaner way to do this... goto nowc } addrs, err := net.InterfaceAddrs() for _, a := range addrs { ip, _, err := net.ParseCIDR(a.String()) if err != nil { continue } na := btcwire.NewNetAddressIPPort(ip, uint16(port), btcwire.SFNodeNetwork) if discover { err = amgr.AddLocalAddress(na, addrmgr.InterfacePrio) if err != nil { amgrLog.Debugf("Skipping local address: %v", err) } } } } nowc: for _, addr := range ipv4Addrs { listener, err := net.Listen("tcp4", addr) if err != nil { srvrLog.Warnf("Can't listen on %s: %v", addr, err) continue } listeners = append(listeners, listener) if discover { if na, err := amgr.DeserializeNetAddress(addr); err == nil { err = amgr.AddLocalAddress(na, addrmgr.BoundPrio) if err != nil { amgrLog.Warnf("Skipping bound address: %v", err) } } } } for _, addr := range ipv6Addrs { listener, err := net.Listen("tcp6", addr) if err != nil { srvrLog.Warnf("Can't listen on %s: %v", addr, err) continue } listeners = append(listeners, listener) if discover { if na, err := amgr.DeserializeNetAddress(addr); err == nil { err = amgr.AddLocalAddress(na, addrmgr.BoundPrio) if err != nil { amgrLog.Debugf("Skipping bound address: %v", err) } } } } if len(listeners) == 0 { return nil, errors.New("no valid listen address") } } s := server{ nonce: nonce, listeners: listeners, netParams: netParams, addrManager: amgr, newPeers: make(chan *peer, cfg.MaxPeers), donePeers: make(chan *peer, cfg.MaxPeers), banPeers: make(chan *peer, cfg.MaxPeers), wakeup: make(chan struct{}), query: make(chan interface{}), relayInv: make(chan relayMsg, cfg.MaxPeers), broadcast: make(chan broadcastMsg, cfg.MaxPeers), quit: make(chan struct{}), modifyRebroadcastInv: make(chan interface{}), nat: nat, db: db, timeSource: blockchain.NewMedianTime(), } bm, err := newBlockManager(&s) if err != nil { return nil, err } s.blockManager = bm s.txMemPool = newTxMemPool(&s) if !cfg.DisableRPC { s.rpcServer, err = newRPCServer(cfg.RPCListeners, &s) if err != nil { return nil, err } } return &s, nil }