@ -1,69 +0,0 @@ | |||
package mock | |||
import ( | |||
"net" | |||
"github.com/tendermint/tendermint/internal/p2p" | |||
"github.com/tendermint/tendermint/libs/service" | |||
"github.com/tendermint/tendermint/types" | |||
) | |||
type Peer struct { | |||
*service.BaseService | |||
ip net.IP | |||
id types.NodeID | |||
addr *p2p.NetAddress | |||
kv map[string]interface{} | |||
Outbound, Persistent bool | |||
} | |||
// NewPeer creates and starts a new mock peer. If the ip | |||
// is nil, random routable address is used. | |||
func NewPeer(ip net.IP) *Peer { | |||
var netAddr *p2p.NetAddress | |||
if ip == nil { | |||
_, netAddr = p2p.CreateRoutableAddr() | |||
} else { | |||
netAddr = types.NewNetAddressIPPort(ip, 26656) | |||
} | |||
nodeKey := types.GenNodeKey() | |||
netAddr.ID = nodeKey.ID | |||
mp := &Peer{ | |||
ip: ip, | |||
id: nodeKey.ID, | |||
addr: netAddr, | |||
kv: make(map[string]interface{}), | |||
} | |||
mp.BaseService = service.NewBaseService(nil, "MockPeer", mp) | |||
if err := mp.Start(); err != nil { | |||
panic(err) | |||
} | |||
return mp | |||
} | |||
func (mp *Peer) FlushStop() { mp.Stop() } //nolint:errcheck //ignore error | |||
func (mp *Peer) TrySend(chID byte, msgBytes []byte) bool { return true } | |||
func (mp *Peer) Send(chID byte, msgBytes []byte) bool { return true } | |||
func (mp *Peer) NodeInfo() types.NodeInfo { | |||
return types.NodeInfo{ | |||
NodeID: mp.addr.ID, | |||
ListenAddr: mp.addr.DialString(), | |||
} | |||
} | |||
func (mp *Peer) ID() types.NodeID { return mp.id } | |||
func (mp *Peer) IsOutbound() bool { return mp.Outbound } | |||
func (mp *Peer) IsPersistent() bool { return mp.Persistent } | |||
func (mp *Peer) Get(key string) interface{} { | |||
if value, ok := mp.kv[key]; ok { | |||
return value | |||
} | |||
return nil | |||
} | |||
func (mp *Peer) Set(key string, value interface{}) { | |||
mp.kv[key] = value | |||
} | |||
func (mp *Peer) RemoteIP() net.IP { return mp.ip } | |||
func (mp *Peer) SocketAddr() *p2p.NetAddress { return mp.addr } | |||
func (mp *Peer) RemoteAddr() net.Addr { return &net.TCPAddr{IP: mp.ip, Port: 8800} } | |||
func (mp *Peer) CloseConn() error { return nil } |
@ -1,319 +0,0 @@ | |||
// Code generated by mockery. DO NOT EDIT. | |||
package mocks | |||
import ( | |||
log "github.com/tendermint/tendermint/libs/log" | |||
mock "github.com/stretchr/testify/mock" | |||
net "net" | |||
types "github.com/tendermint/tendermint/types" | |||
) | |||
// Peer is an autogenerated mock type for the Peer type | |||
type Peer struct { | |||
mock.Mock | |||
} | |||
// CloseConn provides a mock function with given fields: | |||
func (_m *Peer) CloseConn() error { | |||
ret := _m.Called() | |||
var r0 error | |||
if rf, ok := ret.Get(0).(func() error); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Error(0) | |||
} | |||
return r0 | |||
} | |||
// FlushStop provides a mock function with given fields: | |||
func (_m *Peer) FlushStop() { | |||
_m.Called() | |||
} | |||
// Get provides a mock function with given fields: _a0 | |||
func (_m *Peer) Get(_a0 string) interface{} { | |||
ret := _m.Called(_a0) | |||
var r0 interface{} | |||
if rf, ok := ret.Get(0).(func(string) interface{}); ok { | |||
r0 = rf(_a0) | |||
} else { | |||
if ret.Get(0) != nil { | |||
r0 = ret.Get(0).(interface{}) | |||
} | |||
} | |||
return r0 | |||
} | |||
// ID provides a mock function with given fields: | |||
func (_m *Peer) ID() types.NodeID { | |||
ret := _m.Called() | |||
var r0 types.NodeID | |||
if rf, ok := ret.Get(0).(func() types.NodeID); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Get(0).(types.NodeID) | |||
} | |||
return r0 | |||
} | |||
// IsOutbound provides a mock function with given fields: | |||
func (_m *Peer) IsOutbound() bool { | |||
ret := _m.Called() | |||
var r0 bool | |||
if rf, ok := ret.Get(0).(func() bool); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Get(0).(bool) | |||
} | |||
return r0 | |||
} | |||
// IsPersistent provides a mock function with given fields: | |||
func (_m *Peer) IsPersistent() bool { | |||
ret := _m.Called() | |||
var r0 bool | |||
if rf, ok := ret.Get(0).(func() bool); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Get(0).(bool) | |||
} | |||
return r0 | |||
} | |||
// IsRunning provides a mock function with given fields: | |||
func (_m *Peer) IsRunning() bool { | |||
ret := _m.Called() | |||
var r0 bool | |||
if rf, ok := ret.Get(0).(func() bool); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Get(0).(bool) | |||
} | |||
return r0 | |||
} | |||
// NodeInfo provides a mock function with given fields: | |||
func (_m *Peer) NodeInfo() types.NodeInfo { | |||
ret := _m.Called() | |||
var r0 types.NodeInfo | |||
if rf, ok := ret.Get(0).(func() types.NodeInfo); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Get(0).(types.NodeInfo) | |||
} | |||
return r0 | |||
} | |||
// OnReset provides a mock function with given fields: | |||
func (_m *Peer) OnReset() error { | |||
ret := _m.Called() | |||
var r0 error | |||
if rf, ok := ret.Get(0).(func() error); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Error(0) | |||
} | |||
return r0 | |||
} | |||
// OnStart provides a mock function with given fields: | |||
func (_m *Peer) OnStart() error { | |||
ret := _m.Called() | |||
var r0 error | |||
if rf, ok := ret.Get(0).(func() error); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Error(0) | |||
} | |||
return r0 | |||
} | |||
// OnStop provides a mock function with given fields: | |||
func (_m *Peer) OnStop() { | |||
_m.Called() | |||
} | |||
// Quit provides a mock function with given fields: | |||
func (_m *Peer) Quit() <-chan struct{} { | |||
ret := _m.Called() | |||
var r0 <-chan struct{} | |||
if rf, ok := ret.Get(0).(func() <-chan struct{}); ok { | |||
r0 = rf() | |||
} else { | |||
if ret.Get(0) != nil { | |||
r0 = ret.Get(0).(<-chan struct{}) | |||
} | |||
} | |||
return r0 | |||
} | |||
// RemoteAddr provides a mock function with given fields: | |||
func (_m *Peer) RemoteAddr() net.Addr { | |||
ret := _m.Called() | |||
var r0 net.Addr | |||
if rf, ok := ret.Get(0).(func() net.Addr); ok { | |||
r0 = rf() | |||
} else { | |||
if ret.Get(0) != nil { | |||
r0 = ret.Get(0).(net.Addr) | |||
} | |||
} | |||
return r0 | |||
} | |||
// RemoteIP provides a mock function with given fields: | |||
func (_m *Peer) RemoteIP() net.IP { | |||
ret := _m.Called() | |||
var r0 net.IP | |||
if rf, ok := ret.Get(0).(func() net.IP); ok { | |||
r0 = rf() | |||
} else { | |||
if ret.Get(0) != nil { | |||
r0 = ret.Get(0).(net.IP) | |||
} | |||
} | |||
return r0 | |||
} | |||
// Reset provides a mock function with given fields: | |||
func (_m *Peer) Reset() error { | |||
ret := _m.Called() | |||
var r0 error | |||
if rf, ok := ret.Get(0).(func() error); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Error(0) | |||
} | |||
return r0 | |||
} | |||
// Send provides a mock function with given fields: _a0, _a1 | |||
func (_m *Peer) Send(_a0 byte, _a1 []byte) bool { | |||
ret := _m.Called(_a0, _a1) | |||
var r0 bool | |||
if rf, ok := ret.Get(0).(func(byte, []byte) bool); ok { | |||
r0 = rf(_a0, _a1) | |||
} else { | |||
r0 = ret.Get(0).(bool) | |||
} | |||
return r0 | |||
} | |||
// Set provides a mock function with given fields: _a0, _a1 | |||
func (_m *Peer) Set(_a0 string, _a1 interface{}) { | |||
_m.Called(_a0, _a1) | |||
} | |||
// SetLogger provides a mock function with given fields: _a0 | |||
func (_m *Peer) SetLogger(_a0 log.Logger) { | |||
_m.Called(_a0) | |||
} | |||
// SocketAddr provides a mock function with given fields: | |||
func (_m *Peer) SocketAddr() *types.NetAddress { | |||
ret := _m.Called() | |||
var r0 *types.NetAddress | |||
if rf, ok := ret.Get(0).(func() *types.NetAddress); ok { | |||
r0 = rf() | |||
} else { | |||
if ret.Get(0) != nil { | |||
r0 = ret.Get(0).(*types.NetAddress) | |||
} | |||
} | |||
return r0 | |||
} | |||
// Start provides a mock function with given fields: | |||
func (_m *Peer) Start() error { | |||
ret := _m.Called() | |||
var r0 error | |||
if rf, ok := ret.Get(0).(func() error); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Error(0) | |||
} | |||
return r0 | |||
} | |||
// Stop provides a mock function with given fields: | |||
func (_m *Peer) Stop() error { | |||
ret := _m.Called() | |||
var r0 error | |||
if rf, ok := ret.Get(0).(func() error); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Error(0) | |||
} | |||
return r0 | |||
} | |||
// String provides a mock function with given fields: | |||
func (_m *Peer) String() string { | |||
ret := _m.Called() | |||
var r0 string | |||
if rf, ok := ret.Get(0).(func() string); ok { | |||
r0 = rf() | |||
} else { | |||
r0 = ret.Get(0).(string) | |||
} | |||
return r0 | |||
} | |||
// TrySend provides a mock function with given fields: _a0, _a1 | |||
func (_m *Peer) TrySend(_a0 byte, _a1 []byte) bool { | |||
ret := _m.Called(_a0, _a1) | |||
var r0 bool | |||
if rf, ok := ret.Get(0).(func(byte, []byte) bool); ok { | |||
r0 = rf(_a0, _a1) | |||
} else { | |||
r0 = ret.Get(0).(bool) | |||
} | |||
return r0 | |||
} | |||
// Wait provides a mock function with given fields: | |||
func (_m *Peer) Wait() { | |||
_m.Called() | |||
} |
@ -1,11 +0,0 @@ | |||
// Modified for Tendermint | |||
// Originally Copyright (c) 2013-2014 Conformal Systems LLC. | |||
// https://github.com/conformal/btcd/blob/master/LICENSE | |||
package p2p | |||
import ( | |||
"github.com/tendermint/tendermint/types" | |||
) | |||
type NetAddress = types.NetAddress |
@ -1,78 +0,0 @@ | |||
package pex | |||
import ( | |||
"errors" | |||
"fmt" | |||
"github.com/tendermint/tendermint/internal/p2p" | |||
) | |||
type ErrAddrBookNonRoutable struct { | |||
Addr *p2p.NetAddress | |||
} | |||
func (err ErrAddrBookNonRoutable) Error() string { | |||
return fmt.Sprintf("Cannot add non-routable address %v", err.Addr) | |||
} | |||
type ErrAddrBookSelf struct { | |||
Addr *p2p.NetAddress | |||
} | |||
func (err ErrAddrBookSelf) Error() string { | |||
return fmt.Sprintf("Cannot add ourselves with address %v", err.Addr) | |||
} | |||
type ErrAddrBookPrivate struct { | |||
Addr *p2p.NetAddress | |||
} | |||
func (err ErrAddrBookPrivate) Error() string { | |||
return fmt.Sprintf("Cannot add private peer with address %v", err.Addr) | |||
} | |||
func (err ErrAddrBookPrivate) PrivateAddr() bool { | |||
return true | |||
} | |||
type ErrAddrBookPrivateSrc struct { | |||
Src *p2p.NetAddress | |||
} | |||
func (err ErrAddrBookPrivateSrc) Error() string { | |||
return fmt.Sprintf("Cannot add peer coming from private peer with address %v", err.Src) | |||
} | |||
func (err ErrAddrBookPrivateSrc) PrivateAddr() bool { | |||
return true | |||
} | |||
type ErrAddrBookNilAddr struct { | |||
Addr *p2p.NetAddress | |||
Src *p2p.NetAddress | |||
} | |||
func (err ErrAddrBookNilAddr) Error() string { | |||
return fmt.Sprintf("Cannot add a nil address. Got (addr, src) = (%v, %v)", err.Addr, err.Src) | |||
} | |||
type ErrAddrBookInvalidAddr struct { | |||
Addr *p2p.NetAddress | |||
AddrErr error | |||
} | |||
func (err ErrAddrBookInvalidAddr) Error() string { | |||
return fmt.Sprintf("Cannot add invalid address %v: %v", err.Addr, err.AddrErr) | |||
} | |||
// ErrAddressBanned is thrown when the address has been banned and therefore cannot be used | |||
type ErrAddressBanned struct { | |||
Addr *p2p.NetAddress | |||
} | |||
func (err ErrAddressBanned) Error() string { | |||
return fmt.Sprintf("Address: %v is currently banned", err.Addr) | |||
} | |||
// ErrUnsolicitedList is thrown when a peer provides a list of addresses that have not been asked for. | |||
var ErrUnsolicitedList = errors.New("unsolicited pexAddrsMessage") |
@ -1,32 +0,0 @@ | |||
package p2p | |||
import ( | |||
"fmt" | |||
mrand "math/rand" | |||
tmrand "github.com/tendermint/tendermint/libs/rand" | |||
"github.com/tendermint/tendermint/types" | |||
) | |||
//------------------------------------------------ | |||
// nolint:gosec // G404: Use of weak random number generator | |||
func CreateRoutableAddr() (addr string, netAddr *NetAddress) { | |||
for { | |||
var err error | |||
addr = fmt.Sprintf("%X@%v.%v.%v.%v:26656", | |||
tmrand.Bytes(20), | |||
mrand.Int()%256, | |||
mrand.Int()%256, | |||
mrand.Int()%256, | |||
mrand.Int()%256) | |||
netAddr, err = types.NewNetAddressString(addr) | |||
if err != nil { | |||
panic(err) | |||
} | |||
if netAddr.Routable() { | |||
break | |||
} | |||
} | |||
return | |||
} |
@ -1,329 +0,0 @@ | |||
// Modified for Tendermint | |||
// Originally Copyright (c) 2013-2014 Conformal Systems LLC. | |||
// https://github.com/conformal/btcd/blob/master/LICENSE | |||
package types | |||
import ( | |||
"errors" | |||
"flag" | |||
"fmt" | |||
"net" | |||
"strconv" | |||
"strings" | |||
"time" | |||
) | |||
// EmptyNetAddress defines the string representation of an empty NetAddress | |||
const EmptyNetAddress = "<nil-NetAddress>" | |||
// NetAddress defines information about a peer on the network | |||
// including its ID, IP address, and port. | |||
type NetAddress struct { | |||
ID NodeID `json:"id"` | |||
IP net.IP `json:"ip"` | |||
Port uint16 `json:"port"` | |||
} | |||
// NewNetAddress returns a new NetAddress using the provided TCP | |||
// address. When testing, other net.Addr (except TCP) will result in | |||
// using 0.0.0.0:0. When normal run, other net.Addr (except TCP) will | |||
// panic. Panics if ID is invalid. | |||
// TODO: socks proxies? | |||
func NewNetAddress(id NodeID, addr net.Addr) *NetAddress { | |||
tcpAddr, ok := addr.(*net.TCPAddr) | |||
if !ok { | |||
if flag.Lookup("test.v") == nil { // normal run | |||
panic(fmt.Sprintf("Only TCPAddrs are supported. Got: %v", addr)) | |||
} else { // in testing | |||
netAddr := NewNetAddressIPPort(net.IP("127.0.0.1"), 0) | |||
netAddr.ID = id | |||
return netAddr | |||
} | |||
} | |||
if err := id.Validate(); err != nil { | |||
panic(fmt.Sprintf("Invalid ID %v: %v (addr: %v)", id, err, addr)) | |||
} | |||
ip := tcpAddr.IP | |||
port := uint16(tcpAddr.Port) | |||
na := NewNetAddressIPPort(ip, port) | |||
na.ID = id | |||
return na | |||
} | |||
// NewNetAddressIPPort returns a new NetAddress using the provided IP | |||
// and port number. | |||
func NewNetAddressIPPort(ip net.IP, port uint16) *NetAddress { | |||
return &NetAddress{ | |||
IP: ip, | |||
Port: port, | |||
} | |||
} | |||
// NewNetAddressString returns a new NetAddress using the provided address in | |||
// the form of "ID@IP:Port". | |||
// Also resolves the host if host is not an IP. | |||
// Errors are of type ErrNetAddressXxx where Xxx is in (NoID, Invalid, Lookup) | |||
func NewNetAddressString(addr string) (*NetAddress, error) { | |||
addrWithoutProtocol := removeProtocolIfDefined(addr) | |||
spl := strings.Split(addrWithoutProtocol, "@") | |||
if len(spl) != 2 { | |||
return nil, ErrNetAddressNoID{addr} | |||
} | |||
id, err := NewNodeID(spl[0]) | |||
if err != nil { | |||
return nil, ErrNetAddressInvalid{addrWithoutProtocol, err} | |||
} | |||
if err := id.Validate(); err != nil { | |||
return nil, ErrNetAddressInvalid{addrWithoutProtocol, err} | |||
} | |||
addrWithoutProtocol = spl[1] | |||
// get host and port | |||
host, portStr, err := net.SplitHostPort(addrWithoutProtocol) | |||
if err != nil { | |||
return nil, ErrNetAddressInvalid{addrWithoutProtocol, err} | |||
} | |||
if len(host) == 0 { | |||
return nil, ErrNetAddressInvalid{ | |||
addrWithoutProtocol, | |||
errors.New("host is empty")} | |||
} | |||
ip := net.ParseIP(host) | |||
if ip == nil { | |||
ips, err := net.LookupIP(host) | |||
if err != nil { | |||
return nil, ErrNetAddressLookup{host, err} | |||
} | |||
ip = ips[0] | |||
} | |||
port, err := strconv.ParseUint(portStr, 10, 16) | |||
if err != nil { | |||
return nil, ErrNetAddressInvalid{portStr, err} | |||
} | |||
na := NewNetAddressIPPort(ip, uint16(port)) | |||
na.ID = id | |||
return na, nil | |||
} | |||
// Equals reports whether na and other are the same addresses, | |||
// including their ID, IP, and Port. | |||
func (na *NetAddress) Equals(other interface{}) bool { | |||
if o, ok := other.(*NetAddress); ok { | |||
return na.String() == o.String() | |||
} | |||
return false | |||
} | |||
// Same returns true is na has the same non-empty ID or DialString as other. | |||
func (na *NetAddress) Same(other interface{}) bool { | |||
if o, ok := other.(*NetAddress); ok { | |||
if na.DialString() == o.DialString() { | |||
return true | |||
} | |||
if na.ID != "" && na.ID == o.ID { | |||
return true | |||
} | |||
} | |||
return false | |||
} | |||
// String representation: <ID>@<IP>:<PORT> | |||
func (na *NetAddress) String() string { | |||
if na == nil { | |||
return EmptyNetAddress | |||
} | |||
addrStr := na.DialString() | |||
if na.ID != "" { | |||
addrStr = na.ID.AddressString(addrStr) | |||
} | |||
return addrStr | |||
} | |||
func (na *NetAddress) DialString() string { | |||
if na == nil { | |||
return "<nil-NetAddress>" | |||
} | |||
return net.JoinHostPort( | |||
na.IP.String(), | |||
strconv.FormatUint(uint64(na.Port), 10), | |||
) | |||
} | |||
// Dial calls net.Dial on the address. | |||
func (na *NetAddress) Dial() (net.Conn, error) { | |||
conn, err := net.Dial("tcp", na.DialString()) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return conn, nil | |||
} | |||
// DialTimeout calls net.DialTimeout on the address. | |||
func (na *NetAddress) DialTimeout(timeout time.Duration) (net.Conn, error) { | |||
conn, err := net.DialTimeout("tcp", na.DialString(), timeout) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return conn, nil | |||
} | |||
// Routable returns true if the address is routable. | |||
func (na *NetAddress) Routable() bool { | |||
if err := na.Valid(); err != nil { | |||
return false | |||
} | |||
// TODO(oga) bitcoind doesn't include RFC3849 here, but should we? | |||
return !(na.RFC1918() || na.RFC3927() || na.RFC4862() || | |||
na.RFC4193() || na.RFC4843() || na.Local()) | |||
} | |||
// For IPv4 these are either a 0 or all bits set address. For IPv6 a zero | |||
// address or one that matches the RFC3849 documentation address format. | |||
func (na *NetAddress) Valid() error { | |||
if err := na.ID.Validate(); err != nil { | |||
return fmt.Errorf("invalid ID: %w", err) | |||
} | |||
if na.IP == nil { | |||
return errors.New("no IP") | |||
} | |||
if na.IP.IsUnspecified() || na.RFC3849() || na.IP.Equal(net.IPv4bcast) { | |||
return errors.New("invalid IP") | |||
} | |||
return nil | |||
} | |||
// Local returns true if it is a local address. | |||
func (na *NetAddress) Local() bool { | |||
return na.IP.IsLoopback() || zero4.Contains(na.IP) | |||
} | |||
// ReachabilityTo checks whenever o can be reached from na. | |||
func (na *NetAddress) ReachabilityTo(o *NetAddress) int { | |||
const ( | |||
Unreachable = 0 | |||
Default = iota | |||
Teredo | |||
Ipv6Weak | |||
Ipv4 | |||
Ipv6Strong | |||
) | |||
switch { | |||
case !na.Routable(): | |||
return Unreachable | |||
case na.RFC4380(): | |||
switch { | |||
case !o.Routable(): | |||
return Default | |||
case o.RFC4380(): | |||
return Teredo | |||
case o.IP.To4() != nil: | |||
return Ipv4 | |||
default: // ipv6 | |||
return Ipv6Weak | |||
} | |||
case na.IP.To4() != nil: | |||
if o.Routable() && o.IP.To4() != nil { | |||
return Ipv4 | |||
} | |||
return Default | |||
default: /* ipv6 */ | |||
var tunneled bool | |||
// Is our v6 is tunneled? | |||
if o.RFC3964() || o.RFC6052() || o.RFC6145() { | |||
tunneled = true | |||
} | |||
switch { | |||
case !o.Routable(): | |||
return Default | |||
case o.RFC4380(): | |||
return Teredo | |||
case o.IP.To4() != nil: | |||
return Ipv4 | |||
case tunneled: | |||
// only prioritize ipv6 if we aren't tunneling it. | |||
return Ipv6Weak | |||
} | |||
return Ipv6Strong | |||
} | |||
} | |||
// RFC1918: IPv4 Private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) | |||
// RFC3849: IPv6 Documentation address (2001:0DB8::/32) | |||
// RFC3927: IPv4 Autoconfig (169.254.0.0/16) | |||
// RFC3964: IPv6 6to4 (2002::/16) | |||
// RFC4193: IPv6 unique local (FC00::/7) | |||
// RFC4380: IPv6 Teredo tunneling (2001::/32) | |||
// RFC4843: IPv6 ORCHID: (2001:10::/28) | |||
// RFC4862: IPv6 Autoconfig (FE80::/64) | |||
// RFC6052: IPv6 well known prefix (64:FF9B::/96) | |||
// RFC6145: IPv6 IPv4 translated address ::FFFF:0:0:0/96 | |||
var rfc1918_10 = net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)} | |||
var rfc1918_192 = net.IPNet{IP: net.ParseIP("192.168.0.0"), Mask: net.CIDRMask(16, 32)} | |||
var rfc1918_172 = net.IPNet{IP: net.ParseIP("172.16.0.0"), Mask: net.CIDRMask(12, 32)} | |||
var rfc3849 = net.IPNet{IP: net.ParseIP("2001:0DB8::"), Mask: net.CIDRMask(32, 128)} | |||
var rfc3927 = net.IPNet{IP: net.ParseIP("169.254.0.0"), Mask: net.CIDRMask(16, 32)} | |||
var rfc3964 = net.IPNet{IP: net.ParseIP("2002::"), Mask: net.CIDRMask(16, 128)} | |||
var rfc4193 = net.IPNet{IP: net.ParseIP("FC00::"), Mask: net.CIDRMask(7, 128)} | |||
var rfc4380 = net.IPNet{IP: net.ParseIP("2001::"), Mask: net.CIDRMask(32, 128)} | |||
var rfc4843 = net.IPNet{IP: net.ParseIP("2001:10::"), Mask: net.CIDRMask(28, 128)} | |||
var rfc4862 = net.IPNet{IP: net.ParseIP("FE80::"), Mask: net.CIDRMask(64, 128)} | |||
var rfc6052 = net.IPNet{IP: net.ParseIP("64:FF9B::"), Mask: net.CIDRMask(96, 128)} | |||
var rfc6145 = net.IPNet{IP: net.ParseIP("::FFFF:0:0:0"), Mask: net.CIDRMask(96, 128)} | |||
var zero4 = net.IPNet{IP: net.ParseIP("0.0.0.0"), Mask: net.CIDRMask(8, 32)} | |||
var ( | |||
// onionCatNet defines the IPv6 address block used to support Tor. | |||
// bitcoind encodes a .onion address as a 16 byte number by decoding the | |||
// address prior to the .onion (i.e. the key hash) base32 into a ten | |||
// byte number. It then stores the first 6 bytes of the address as | |||
// 0xfd, 0x87, 0xd8, 0x7e, 0xeb, 0x43. | |||
// | |||
// This is the same range used by OnionCat, which is part part of the | |||
// RFC4193 unique local IPv6 range. | |||
// | |||
// In summary the format is: | |||
// { magic 6 bytes, 10 bytes base32 decode of key hash } | |||
onionCatNet = ipNet("fd87:d87e:eb43::", 48, 128) | |||
) | |||
func (na *NetAddress) RFC1918() bool { | |||
return rfc1918_10.Contains(na.IP) || | |||
rfc1918_192.Contains(na.IP) || | |||
rfc1918_172.Contains(na.IP) | |||
} | |||
func (na *NetAddress) RFC3849() bool { return rfc3849.Contains(na.IP) } | |||
func (na *NetAddress) RFC3927() bool { return rfc3927.Contains(na.IP) } | |||
func (na *NetAddress) RFC3964() bool { return rfc3964.Contains(na.IP) } | |||
func (na *NetAddress) RFC4193() bool { return rfc4193.Contains(na.IP) } | |||
func (na *NetAddress) RFC4380() bool { return rfc4380.Contains(na.IP) } | |||
func (na *NetAddress) RFC4843() bool { return rfc4843.Contains(na.IP) } | |||
func (na *NetAddress) RFC4862() bool { return rfc4862.Contains(na.IP) } | |||
func (na *NetAddress) RFC6052() bool { return rfc6052.Contains(na.IP) } | |||
func (na *NetAddress) RFC6145() bool { return rfc6145.Contains(na.IP) } | |||
func (na *NetAddress) OnionCatTor() bool { return onionCatNet.Contains(na.IP) } | |||
func removeProtocolIfDefined(addr string) string { | |||
if strings.Contains(addr, "://") { | |||
return strings.Split(addr, "://")[1] | |||
} | |||
return addr | |||
} | |||
// ipNet returns a net.IPNet struct given the passed IP address string, number | |||
// of one bits to include at the start of the mask, and the total number of bits | |||
// for the mask. | |||
func ipNet(ip string, ones, bits int) net.IPNet { | |||
return net.IPNet{IP: net.ParseIP(ip), Mask: net.CIDRMask(ones, bits)} | |||
} |
@ -1,183 +0,0 @@ | |||
package types | |||
import ( | |||
"net" | |||
"sync" | |||
"testing" | |||
"github.com/stretchr/testify/assert" | |||
"github.com/stretchr/testify/require" | |||
) | |||
func TestNetAddress_String(t *testing.T) { | |||
tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080") | |||
require.Nil(t, err) | |||
netAddr := NewNetAddress("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", tcpAddr) | |||
var wg sync.WaitGroup | |||
for i := 0; i < 10; i++ { | |||
wg.Add(1) | |||
go func() { | |||
defer wg.Done() | |||
_ = netAddr.String() | |||
}() | |||
} | |||
wg.Wait() | |||
s := netAddr.String() | |||
require.Equal(t, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", s) | |||
} | |||
func TestNewNetAddress(t *testing.T) { | |||
tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080") | |||
require.Nil(t, err) | |||
assert.Panics(t, func() { | |||
NewNetAddress("", tcpAddr) | |||
}) | |||
addr := NewNetAddress("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", tcpAddr) | |||
assert.Equal(t, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", addr.String()) | |||
assert.NotPanics(t, func() { | |||
NewNetAddress("", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8000}) | |||
}, "Calling NewNetAddress with UDPAddr should not panic in testing") | |||
} | |||
func TestNewNetAddressString(t *testing.T) { | |||
testCases := []struct { | |||
name string | |||
addr string | |||
expected string | |||
correct bool | |||
}{ | |||
{"no node id and no protocol", "127.0.0.1:8080", "", false}, | |||
{"no node id w/ tcp input", "tcp://127.0.0.1:8080", "", false}, | |||
{"no node id w/ udp input", "udp://127.0.0.1:8080", "", false}, | |||
{ | |||
"no protocol", | |||
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
true, | |||
}, | |||
{ | |||
"tcp input", | |||
"tcp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
true, | |||
}, | |||
{ | |||
"udp input", | |||
"udp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
true, | |||
}, | |||
{"malformed tcp input", "tcp//deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false}, | |||
{"malformed udp input", "udp//deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false}, | |||
// {"127.0.0:8080", false}, | |||
{"invalid host", "notahost", "", false}, | |||
{"invalid port", "127.0.0.1:notapath", "", false}, | |||
{"invalid host w/ port", "notahost:8080", "", false}, | |||
{"just a port", "8082", "", false}, | |||
{"non-existent port", "127.0.0:8080000", "", false}, | |||
{"too short nodeId", "deadbeef@127.0.0.1:8080", "", false}, | |||
{"too short, not hex nodeId", "this-isnot-hex@127.0.0.1:8080", "", false}, | |||
{"not hex nodeId", "xxxxbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false}, | |||
{"too short nodeId w/tcp", "tcp://deadbeef@127.0.0.1:8080", "", false}, | |||
{"too short notHex nodeId w/tcp", "tcp://this-isnot-hex@127.0.0.1:8080", "", false}, | |||
{"notHex nodeId w/tcp", "tcp://xxxxbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false}, | |||
{ | |||
"correct nodeId w/tcp", | |||
"tcp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
true, | |||
}, | |||
{"no node id", "tcp://@127.0.0.1:8080", "", false}, | |||
{"no node id or IP", "tcp://@", "", false}, | |||
{"tcp no host, w/ port", "tcp://:26656", "", false}, | |||
{"empty", "", "", false}, | |||
{"node id delimiter 1", "@", "", false}, | |||
{"node id delimiter 2", " @", "", false}, | |||
{"node id delimiter 3", " @ ", "", false}, | |||
} | |||
for _, tc := range testCases { | |||
tc := tc | |||
t.Run(tc.name, func(t *testing.T) { | |||
addr, err := NewNetAddressString(tc.addr) | |||
if tc.correct { | |||
if assert.Nil(t, err, tc.addr) { | |||
assert.Equal(t, tc.expected, addr.String()) | |||
} | |||
} else { | |||
assert.NotNil(t, err, tc.addr) | |||
} | |||
}) | |||
} | |||
} | |||
func TestNewNetAddressIPPort(t *testing.T) { | |||
addr := NewNetAddressIPPort(net.ParseIP("127.0.0.1"), 8080) | |||
assert.Equal(t, "127.0.0.1:8080", addr.String()) | |||
} | |||
func TestNetAddressProperties(t *testing.T) { | |||
// TODO add more test cases | |||
testCases := []struct { | |||
addr string | |||
valid bool | |||
local bool | |||
routable bool | |||
}{ | |||
{"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", true, true, false}, | |||
{"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@ya.ru:80", true, false, true}, | |||
} | |||
for _, tc := range testCases { | |||
addr, err := NewNetAddressString(tc.addr) | |||
require.Nil(t, err) | |||
err = addr.Valid() | |||
if tc.valid { | |||
assert.NoError(t, err) | |||
} else { | |||
assert.Error(t, err) | |||
} | |||
assert.Equal(t, tc.local, addr.Local()) | |||
assert.Equal(t, tc.routable, addr.Routable()) | |||
} | |||
} | |||
func TestNetAddressReachabilityTo(t *testing.T) { | |||
// TODO add more test cases | |||
testCases := []struct { | |||
addr string | |||
other string | |||
reachability int | |||
}{ | |||
{ | |||
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", | |||
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8081", | |||
0, | |||
}, | |||
{"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@ya.ru:80", "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 1}, | |||
} | |||
for _, tc := range testCases { | |||
addr, err := NewNetAddressString(tc.addr) | |||
require.Nil(t, err) | |||
other, err := NewNetAddressString(tc.other) | |||
require.Nil(t, err) | |||
assert.Equal(t, tc.reachability, addr.ReachabilityTo(other)) | |||
} | |||
} |