aboutsummaryrefslogtreecommitdiffstats
path: root/p2p/network.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-12-05 23:27:37 +0800
committerobscuren <geffobscura@gmail.com>2014-12-05 23:27:37 +0800
commit195b2d2ebdfe1e794c096c9b6c9fe91e9df7af1d (patch)
tree9b1a96d7c65c4dcb5515eddf6c2b03e7e6b0d397 /p2p/network.go
parent710360bab61178cf7fbc52213ec4c612be37ad18 (diff)
parent384b8c75f07b6811aa3012ad52a44844b3ab6e52 (diff)
downloaddexon-195b2d2ebdfe1e794c096c9b6c9fe91e9df7af1d.tar.gz
dexon-195b2d2ebdfe1e794c096c9b6c9fe91e9df7af1d.tar.zst
dexon-195b2d2ebdfe1e794c096c9b6c9fe91e9df7af1d.zip
Merge branch 'fjl-feature/p2p-protocol-interface' into poc8
Diffstat (limited to 'p2p/network.go')
-rw-r--r--p2p/network.go196
1 files changed, 0 insertions, 196 deletions
diff --git a/p2p/network.go b/p2p/network.go
deleted file mode 100644
index 820cef1a9..000000000
--- a/p2p/network.go
+++ /dev/null
@@ -1,196 +0,0 @@
-package p2p
-
-import (
- "fmt"
- "math/rand"
- "net"
- "strconv"
- "time"
-)
-
-const (
- DialerTimeout = 180 //seconds
- KeepAlivePeriod = 60 //minutes
- portMappingUpdateInterval = 900 // seconds = 15 mins
- upnpDiscoverAttempts = 3
-)
-
-// Dialer is not an interface in net, so we define one
-// *net.Dialer conforms to this
-type Dialer interface {
- Dial(network, address string) (net.Conn, error)
-}
-
-type Network interface {
- Start() error
- Listener(net.Addr) (net.Listener, error)
- Dialer(net.Addr) (Dialer, error)
- NewAddr(string, int) (addr net.Addr, err error)
- ParseAddr(string) (addr net.Addr, err error)
-}
-
-type NAT interface {
- GetExternalAddress() (addr net.IP, err error)
- AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error)
- DeletePortMapping(protocol string, externalPort, internalPort int) (err error)
-}
-
-type TCPNetwork struct {
- nat NAT
- natType NATType
- quit chan chan bool
- ports chan string
-}
-
-type NATType int
-
-const (
- NONE = iota
- UPNP
- PMP
-)
-
-const (
- portMappingTimeout = 1200 // 20 mins
-)
-
-func NewTCPNetwork(natType NATType) (net *TCPNetwork) {
- return &TCPNetwork{
- natType: natType,
- ports: make(chan string),
- }
-}
-
-func (self *TCPNetwork) Dialer(addr net.Addr) (Dialer, error) {
- return &net.Dialer{
- Timeout: DialerTimeout * time.Second,
- // KeepAlive: KeepAlivePeriod * time.Minute,
- LocalAddr: addr,
- }, nil
-}
-
-func (self *TCPNetwork) Listener(addr net.Addr) (net.Listener, error) {
- if self.natType == UPNP {
- _, port, _ := net.SplitHostPort(addr.String())
- if self.quit == nil {
- self.quit = make(chan chan bool)
- go self.updatePortMappings()
- }
- self.ports <- port
- }
- return net.Listen(addr.Network(), addr.String())
-}
-
-func (self *TCPNetwork) Start() (err error) {
- switch self.natType {
- case NONE:
- case UPNP:
- nat, uerr := upnpDiscover(upnpDiscoverAttempts)
- if uerr != nil {
- err = fmt.Errorf("UPNP failed: ", uerr)
- } else {
- self.nat = nat
- }
- case PMP:
- err = fmt.Errorf("PMP not implemented")
- default:
- err = fmt.Errorf("Invalid NAT type: %v", self.natType)
- }
- return
-}
-
-func (self *TCPNetwork) Stop() {
- q := make(chan bool)
- self.quit <- q
- <-q
-}
-
-func (self *TCPNetwork) addPortMapping(lport int) (err error) {
- _, err = self.nat.AddPortMapping("TCP", lport, lport, "p2p listen port", portMappingTimeout)
- if err != nil {
- logger.Errorf("unable to add port mapping on %v: %v", lport, err)
- } else {
- logger.Debugf("succesfully added port mapping on %v", lport)
- }
- return
-}
-
-func (self *TCPNetwork) updatePortMappings() {
- timer := time.NewTimer(portMappingUpdateInterval * time.Second)
- lports := []int{}
-out:
- for {
- select {
- case port := <-self.ports:
- int64lport, _ := strconv.ParseInt(port, 10, 16)
- lport := int(int64lport)
- if err := self.addPortMapping(lport); err != nil {
- lports = append(lports, lport)
- }
- case <-timer.C:
- for lport := range lports {
- if err := self.addPortMapping(lport); err != nil {
- }
- }
- case errc := <-self.quit:
- errc <- true
- break out
- }
- }
-
- timer.Stop()
- for lport := range lports {
- if err := self.nat.DeletePortMapping("TCP", lport, lport); err != nil {
- logger.Debugf("unable to remove port mapping on %v: %v", lport, err)
- } else {
- logger.Debugf("succesfully removed port mapping on %v", lport)
- }
- }
-}
-
-func (self *TCPNetwork) NewAddr(host string, port int) (net.Addr, error) {
- ip, err := self.lookupIP(host)
- if err == nil {
- return &net.TCPAddr{
- IP: ip,
- Port: port,
- }, nil
- }
- return nil, err
-}
-
-func (self *TCPNetwork) ParseAddr(address string) (net.Addr, error) {
- host, port, err := net.SplitHostPort(address)
- if err == nil {
- iport, _ := strconv.Atoi(port)
- addr, e := self.NewAddr(host, iport)
- return addr, e
- }
- return nil, err
-}
-
-func (*TCPNetwork) lookupIP(host string) (ip net.IP, err error) {
- if ip = net.ParseIP(host); ip != nil {
- return
- }
-
- var ips []net.IP
- ips, err = net.LookupIP(host)
- if err != nil {
- logger.Warnln(err)
- return
- }
- if len(ips) == 0 {
- err = fmt.Errorf("No IP addresses available for %v", host)
- logger.Warnln(err)
- return
- }
- if len(ips) > 1 {
- // Pick a random IP address, simulating round-robin DNS.
- rand.Seed(time.Now().UTC().UnixNano())
- ip = ips[rand.Intn(len(ips))]
- } else {
- ip = ips[0]
- }
- return
-}