|
|
- package peer
-
- import (
- "sync/atomic"
- "net"
- )
-
- const (
- DEFAULT_PORT = 8001
- )
-
- /* Listener */
-
- type Listener interface {
- Connections() <-chan *Connection
- LocalAddress() *NetAddress
- Stop()
- }
-
-
- /* DefaultListener */
-
- type DefaultListener struct {
- listener net.Listener
- connections chan *Connection
- stopped uint32
- }
-
- const (
- DEFAULT_BUFFERED_CONNECTIONS = 10
- )
-
- func NewDefaultListener(protocol string, listenAddr string) Listener {
- listener, err := net.Listen(protocol, listenAddr)
- if err != nil { panic(err) }
-
- dl := &DefaultListener{
- listener: listener,
- connections: make(chan *Connection, DEFAULT_BUFFERED_CONNECTIONS),
- }
-
- go dl.listenHandler()
-
- return dl
- }
-
- func (l *DefaultListener) listenHandler() {
- for {
- conn, err := l.listener.Accept()
-
- if atomic.LoadUint32(&l.stopped) == 1 { return }
-
- // listener wasn't stopped,
- // yet we encountered an error.
- if err != nil { panic(err) }
-
- c := NewConnection(conn)
- l.connections <- c
- }
-
- // cleanup
- close(l.connections)
- for _ = range l.connections {
- // drain
- }
- }
-
- func (l *DefaultListener) Connections() <-chan *Connection {
- return l.connections
- }
-
- func (l *DefaultListener) LocalAddress() *NetAddress {
- return GetLocalAddress()
- }
-
- func (l *DefaultListener) Stop() {
- if atomic.CompareAndSwapUint32(&l.stopped, 0, 1) {
- l.listener.Close()
- }
- }
-
-
- /* local address helpers */
-
- func GetLocalAddress() *NetAddress {
- laddr := GetUPNPLocalAddress()
- if laddr != nil { return laddr }
-
- laddr = GetDefaultLocalAddress()
- if laddr != nil { return laddr }
-
- panic("Could not determine local address")
- }
-
- // UPNP external address discovery & port mapping
- // TODO: more flexible internal & external ports
- func GetUPNPLocalAddress() *NetAddress {
- nat, err := Discover()
- if err != nil { return nil }
-
- ext, err := nat.GetExternalAddress()
- if err != nil { return nil }
-
- _, err = nat.AddPortMapping("tcp", DEFAULT_PORT, DEFAULT_PORT, "tendermint", 0)
- if err != nil { return nil }
-
- return NewNetAddressIPPort(ext, DEFAULT_PORT)
- }
-
- // Naive local IPv4 interface address detection
- // TODO: use syscalls to get actual ourIP. http://pastebin.com/9exZG4rh
- func GetDefaultLocalAddress() *NetAddress {
- addrs, err := net.InterfaceAddrs()
- if err != nil { panic("Wtf") }
- for _, a := range addrs {
- ipnet, ok := a.(*net.IPNet)
- if !ok { continue }
- v4 := ipnet.IP.To4()
- if v4 == nil || v4[0] == 127 { continue } // loopback
- return NewNetAddress(a)
- }
- return nil
- }
-
-
|