cmn "github.com/tendermint/tmlibs/common"
)
+//Reactor is responsible for handling incoming messages of one or more `Channels`
type Reactor interface {
cmn.Service // Start, Stop
Receive(chID byte, peer *Peer, msgBytes []byte)
}
-//--------------------------------------
-
+//BaseReactor base service of a reactor
type BaseReactor struct {
cmn.BaseService // Provides Start, Stop, .Quit
Switch *Switch
}
+//NewBaseReactor create new base Reactor
func NewBaseReactor(name string, impl Reactor) *BaseReactor {
return &BaseReactor{
BaseService: *cmn.NewBaseService(nil, name, impl),
}
}
+//SetSwitch setting a switch for reactor
func (br *BaseReactor) SetSwitch(sw *Switch) {
br.Switch = sw
}
+
+//GetChannels returns the list of channel descriptors
func (*BaseReactor) GetChannels() []*ChannelDescriptor { return nil }
+
+//AddPeer is called by the switch when a new peer is added
func (*BaseReactor) AddPeer(peer *Peer) {}
+
+//RemovePeer is called by the switch when the peer is stopped (due to error or other reason)
func (*BaseReactor) RemovePeer(peer *Peer, reason interface{}) {}
+
+//Receive is called when msgBytes is received from peer
func (*BaseReactor) Receive(chID byte, peer *Peer, msgBytes []byte) {}
cmn "github.com/tendermint/tmlibs/common"
)
+//Listener subset of the methods of DefaultListener
type Listener interface {
Connections() <-chan net.Conn
InternalAddress() *NetAddress
Stop() bool
}
-// Implements Listener
+//DefaultListener Implements bytomd server Listener
type DefaultListener struct {
cmn.BaseService
return host, port
}
-// skipUPNP: If true, does not try getUPNPExternalAddress()
+//NewDefaultListener create a default listener
func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) (Listener, bool) {
// Local listen IP & port
lAddrIP, lAddrPort := splitHostPort(lAddr)
// Determine external address...
var extAddr *NetAddress
+ //skipUPNP: If true, does not try getUPNPExternalAddress()
if !skipUPNP {
// If the lAddrIP is INADDR_ANY, try UPnP
if lAddrIP == "" || lAddrIP == "0.0.0.0" {
return dl, listenerStatus
}
+//OnStart start listener
func (l *DefaultListener) OnStart() error {
l.BaseService.OnStart()
go l.listenRoutine()
return nil
}
+//OnStop stop listener
func (l *DefaultListener) OnStop() {
l.BaseService.OnStop()
l.listener.Close()
}
-// Accept connections and pass on the channel
+//listenRoutine Accept connections and pass on the channel
func (l *DefaultListener) listenRoutine() {
for {
conn, err := l.listener.Accept()
}
}
-// A channel of inbound connections.
-// It gets closed when the listener closes.
+//Connections a channel of inbound connections. It gets closed when the listener closes.
func (l *DefaultListener) Connections() <-chan net.Conn {
return l.connections
}
+//InternalAddress listener internal address
func (l *DefaultListener) InternalAddress() *NetAddress {
return l.intAddr
}
+//ExternalAddress listener external address for remote peer dial
func (l *DefaultListener) ExternalAddress() *NetAddress {
return l.extAddr
}
-// NOTE: The returned listener is already Accept()'ing.
-// So it's not suitable to pass into http.Serve().
+// NetListener the returned listener is already Accept()'ing. So it's not suitable to pass into http.Serve().
func (l *DefaultListener) NetListener() net.Listener {
return l.listener
}
+//String string of default listener
func (l *DefaultListener) String() string {
return fmt.Sprintf("Listener(@%v)", l.extAddr)
}
-/* external address helpers */
-
-// UPNP external address discovery & port mapping
+//getUPNPExternalAddress UPNP external address discovery & port mapping
func getUPNPExternalAddress(externalPort, internalPort int) *NetAddress {
log.Info("Getting UPNP external address")
nat, err := upnp.Discover()
return na.str
}
+//DialString dial address string representation
func (na *NetAddress) DialString() string {
return net.JoinHostPort(
na.IP.String(),
na.RFC4193() || na.RFC4843() || na.Local())
}
-// For IPv4 these are either a 0 or all bits set address. For IPv6 a zero
+// Valid 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() bool {
return na.IP != nil && !(na.IP.IsUnspecified() || na.RFC3849() ||
Unreachable = 0
Default = iota
Teredo
- Ipv6_weak
+ Ipv6Weak
Ipv4
- Ipv6_strong
+ Ipv6Strong
)
if !na.Routable() {
return Unreachable
return Teredo
} else if o.IP.To4() != nil {
return Ipv4
- } else { // ipv6
- return Ipv6_weak
}
+ return Ipv6Weak
} else if na.IP.To4() != nil {
if o.Routable() && o.IP.To4() != nil {
return Ipv4
}
return Default
- } else /* ipv6 */ {
- var tunnelled bool
- // Is our v6 is tunnelled?
- if o.RFC3964() || o.RFC6052() || o.RFC6145() {
- tunnelled = true
- }
- if !o.Routable() {
- return Default
- } else if o.RFC4380() {
- return Teredo
- } else if o.IP.To4() != nil {
- return Ipv4
- } else if tunnelled {
- // only prioritise ipv6 if we aren't tunnelling it.
- return Ipv6_weak
- }
- return Ipv6_strong
}
+
+ var tunnelled bool
+ // Is our v6 is tunnelled?
+ if o.RFC3964() || o.RFC6052() || o.RFC6145() {
+ tunnelled = true
+ }
+ if !o.Routable() {
+ return Default
+ } else if o.RFC4380() {
+ return Teredo
+ } else if o.IP.To4() != nil {
+ return Ipv4
+ } else if tunnelled {
+ // only prioritise ipv6 if we aren't tunnelling 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 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)}
+// RFC1918 IPv4 Private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
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) }
+ return rfc1918_10.Contains(na.IP) || rfc1918_192.Contains(na.IP) || rfc1918_172.Contains(na.IP)
+}
+
+// RFC3849 IPv6 Documentation address (2001:0DB8::/32)
+func (na *NetAddress) RFC3849() bool {
+ return rfc3849.Contains(na.IP)
+}
+
+// RFC3927 IPv4 Autoconfig (169.254.0.0/16)
+func (na *NetAddress) RFC3927() bool {
+ return rfc3927.Contains(na.IP)
+}
+
+// RFC3964 IPv6 6to4 (2002::/16)
+func (na *NetAddress) RFC3964() bool {
+ return rfc3964.Contains(na.IP)
+}
+
+// RFC4193 IPv6 unique local (FC00::/7)
+func (na *NetAddress) RFC4193() bool {
+ return rfc4193.Contains(na.IP)
+}
+
+// RFC4380 IPv6 Teredo tunneling (2001::/32)
+func (na *NetAddress) RFC4380() bool {
+ return rfc4380.Contains(na.IP)
+}
+
+// RFC4843 IPv6 ORCHID: (2001:10::/28)
+func (na *NetAddress) RFC4843() bool {
+ return rfc4843.Contains(na.IP)
+}
+
+// RFC4862 IPv6 Autoconfig (FE80::/64)
+func (na *NetAddress) RFC4862() bool {
+ return rfc4862.Contains(na.IP)
+}
+
+// RFC6052 IPv6 well known prefix (64:FF9B::/96)
+func (na *NetAddress) RFC6052() bool {
+ return rfc6052.Contains(na.IP)
+}
+
+// RFC6145 IPv6 IPv4 translated address ::FFFF:0:0:0/96
+func (na *NetAddress) RFC6145() bool {
+ return rfc6145.Contains(na.IP)
+}
const maxNodeInfoSize = 10240 // 10Kb
+//NodeInfo peer node info
type NodeInfo struct {
PubKey crypto.PubKeyEd25519 `json:"pub_key"`
Moniker string `json:"moniker"`
return nil
}
+//ListenHost peer listener ip address
func (info *NodeInfo) ListenHost() string {
host, _, _ := net.SplitHostPort(info.ListenAddr)
return host
}
+//ListenPort peer listener port
func (info *NodeInfo) ListenPort() int {
_, port, _ := net.SplitHostPort(info.ListenAddr)
- port_i, err := strconv.Atoi(port)
+ portInt, err := strconv.Atoi(port)
if err != nil {
return -1
}
- return port_i
+ return portInt
}
+//RemoteAddrHost peer external ip address
func (info *NodeInfo) RemoteAddrHost() string {
host, _, _ := net.SplitHostPort(info.RemoteAddr)
return host
}
+//String representation
func (info NodeInfo) String() string {
return fmt.Sprintf("NodeInfo{pk: %v, moniker: %v, network: %v [listen %v], version: %v (%v)}", info.PubKey, info.Moniker, info.Network, info.ListenAddr, info.Version, info.Other)
}
import (
"fmt"
- "io"
"net"
"time"
cfg "github.com/bytom/config"
)
-// Peer could be marked as persistent, in which case you can use
-// Redial function to reconnect. Note that inbound peers can't be
-// made persistent. They should be made persistent on the other end.
-//
-
// peerConn contains the raw connection and its config.
type peerConn struct {
outbound bool
conn net.Conn // source connection
}
-// Before using a peer, you will need to perform a handshake on connection.
+// Peer represent a bytom network node
type Peer struct {
cmn.BaseService
return p.mconn.CanSend(chID)
}
-// WriteTo writes the peer's public key to w.
-func (p *Peer) WriteTo(w io.Writer) (n int64, err error) {
- var n_ int
- wire.WriteString(p.Key, w, &n_, &err)
- n += int64(n_)
- return
-}
-
// String representation.
func (p *Peer) String() string {
if p.outbound {
return len(ps.list)
}
-// threadsafe list of peers.
+// List threadsafe list of peers.
func (ps *PeerSet) List() []*Peer {
ps.mtx.Lock()
defer ps.mtx.Unlock()
defaultBanDuration = time.Hour * 1
)
+//pre-define errors for connecting fail
var (
ErrDuplicatePeer = errors.New("Duplicate peer")
ErrConnectSelf = errors.New("Connect self")
return sw.nodeInfo
}
-// SetNodeKey sets the switch's private key for authenticated encryption.
+// SetNodePrivKey sets the switch's private key for authenticated encryption.
// NOTE: Not goroutine safe.
func (sw *Switch) SetNodePrivKey(nodePrivKey crypto.PrivKeyEd25519) {
sw.nodePrivKey = nodePrivKey
}
}
-// addPeer performs the P2P handshake with a peer
+// AddPeer performs the P2P handshake with a peer
// that already has a SecretConnection. If all goes well,
// it starts the peer and adds it to the switch.
// NOTE: This performs a blocking handshake before the peer is added.
return nil
}
-// Dial a list of seeds asynchronously in random order
+// DialSeeds a list of seeds asynchronously in random order
func (sw *Switch) DialSeeds(seeds []string) error {
netAddrs, err := NewNetAddressStrings(seeds)
if err != nil {
return nil
}
+//DialPeerWithAddress dial node from net address
func (sw *Switch) DialPeerWithAddress(addr *NetAddress) error {
log.Debug("Dialing peer address:", addr)
return nil
}
+//IsDialing prevent duplicate dialing
func (sw *Switch) IsDialing(addr *NetAddress) bool {
return sw.dialing.Has(addr.IP.String())
}
-// Returns the count of outbound/inbound and outbound-dialing peers.
+// NumPeers Returns the count of outbound/inbound and outbound-dialing peers.
func (sw *Switch) NumPeers() (outbound, inbound, dialing int) {
peers := sw.peers.List()
for _, peer := range peers {
return
}
+//Peers return switch peerset
func (sw *Switch) Peers() *PeerSet {
return sw.peers
}
sw.stopAndRemovePeer(peer, reason)
}
-// Disconnect from a peer gracefully.
+// StopPeerGracefully disconnect from a peer gracefully.
func (sw *Switch) StopPeerGracefully(peer *Peer) {
log.Info("Stopping peer gracefully")
sw.stopAndRemovePeer(peer, nil)
return nil
}
+//AddBannedPeer add peer to blacklist
func (sw *Switch) AddBannedPeer(peer *Peer) error {
sw.mtx.Lock()
defer sw.mtx.Unlock()
cfg "github.com/bytom/config"
)
+//PanicOnAddPeerErr add peer error
var PanicOnAddPeerErr = false
-// Switches connected via arbitrary net.Conn; useful for testing
+// MakeConnectedSwitches switches connected via arbitrary net.Conn; useful for testing
// Returns n switches, connected according to the connect func.
// If connect==Connect2Switches, the switches will be fully connected.
// initSwitch defines how the ith switch should be initialized (ie. with what reactors).
return switches
}
-// Will connect switches i and j via net.Pipe()
+// Connect2Switches will connect switches i and j via net.Pipe()
// Blocks until a conection is established.
// NOTE: caller ensures i and j are within bounds
func Connect2Switches(switches []*Switch, i, j int) {
package p2p
+//Version p2p library version
const Version = "0.5.0"