github.com/Cloud-Foundations/Dominator@v0.3.4/lib/net/reverseconnection/api.go (about) 1 package reverseconnection 2 3 import ( 4 "net" 5 "net/http" 6 "sync" 7 "time" 8 9 "github.com/Cloud-Foundations/Dominator/lib/log" 10 libnet "github.com/Cloud-Foundations/Dominator/lib/net" 11 ) 12 13 type acceptEvent struct { 14 conn *listenerConn 15 error error 16 } 17 18 type listenerConn struct { 19 libnet.TCPConn 20 listener *Listener 21 } 22 23 type Dialer struct { 24 dialer *net.Dialer 25 minimumInterval time.Duration 26 maximumInterval time.Duration 27 logger log.DebugLogger 28 connectionMapLock sync.Mutex 29 connectionMap map[string]net.Conn // Key: address (ip:port). 30 } 31 32 type ip4Address [4]byte 33 34 type Listener struct { 35 listener net.Listener 36 portNumber uint 37 logger log.DebugLogger 38 acceptChannel chan acceptEvent 39 closedLock sync.Mutex 40 closed bool 41 connectionMapLock sync.Mutex 42 connectionMap map[ip4Address]uint 43 } 44 45 // ReverseListenerConfig describes the configuration for a remote server for 46 // which connections are requested. 47 type ReverseListenerConfig struct { 48 Network string // May be empty or "tcp". 49 ServerAddress string // Address of the remote server. 50 MinimumInterval time.Duration // Minimum interval to request connections. 51 MaximumInterval time.Duration // Maximum interval to request connections. 52 } 53 54 // Listen creates a listener which may be used to accept incoming connections. 55 // It listens on all available IP addresses on the local system. 56 func Listen(network string, portNumber uint, logger log.DebugLogger) ( 57 *Listener, error) { 58 return listen(network, portNumber, logger) 59 } 60 61 func (l *Listener) Accept() (net.Conn, error) { 62 return l.accept() 63 } 64 65 func (l *Listener) Addr() net.Addr { 66 return l.listener.Addr() 67 } 68 69 func (l *Listener) Close() error { 70 return l.close() 71 } 72 73 // RequestConnections starts a goroutine which will periodically attempt to 74 // establish a connection with a remote server if there is no incoming 75 // connection from the remote server. The connection that is established will be 76 // returned by the Accept method. The configuration information for the remote 77 // server is read from the JSON-encoded file with filename: 78 // "/etc/reverse-listeners/"+serviceName with the format ReverseListenerConfig. 79 func (l *Listener) RequestConnections(serviceName string) error { 80 return l.requestConnections(serviceName) 81 } 82 83 // NewDialer creates a dialer that may be used to make connections. It also 84 // registers a HTTP handler for receiving connections from remote systems which 85 // have requested connections. When the Dial method is called, if a new 86 // connection has been received it is used instead of dialing out the normal 87 // way. If rawDialer is nil, the default dialer is used to dial out when needed. 88 // If serveMux is nil then the default http.ServeMux is used. NewDialer may be 89 // called only once per serveMux. 90 // The minimumInterval and maximumInterval parameters are passed back to remote 91 // systems which are making connections, overriding their default configuration. 92 func NewDialer(rawDialer *net.Dialer, serveMux *http.ServeMux, 93 minimumInterval, maximumInterval time.Duration, 94 logger log.DebugLogger) *Dialer { 95 return newDialer(rawDialer, serveMux, minimumInterval, maximumInterval, 96 logger) 97 } 98 99 // Dial makes a connection to a remote address, possibly consuming a connection 100 // that was initiated by the remote address. 101 func (d *Dialer) Dial(network, address string) (net.Conn, error) { 102 return d.dial(network, address) 103 }