hopp/listen.go

106 lines
3.1 KiB
Go

package hopp
import "net"
import "errors"
import "crypto/tls"
// Listener is an object which listens for incoming HOPP connections.
type Listener interface {
// Accept waits for and returns the next connection to the listener.
Accept() (Conn, error)
// Close closes the listener. Any blocked Accept operations will be
// unblocked and return errors.
Close() error
// Addr returns the listener's network address.
Addr() net.Addr
}
// Listen listens for incoming HOPP connections. The network must be one of:
//
// - "quic"
// - "quic4" (IPv4-only)
// - "quic6" (IPv6-only)
// - "tls"
// - "tls4" (IPv4-only)
// - "tls6" (IPv6-only)
// - "tcp"
// - "tcp4" (IPv4-only)
// - "tcp6" (IPv6-only)
// - "unix"
//
// For now, QUIC is unsupported.
func Listen(network, address string, tlsConf *tls.Config) (Listener, error) {
switch network {
case "quic", "quic4", "quic6": return ListenQUIC(network, address, tlsConf)
case "tls", "tls4", "tls6": return ListenTLS(network, address, tlsConf)
case "tcp", "tcp4", "tcp6":
addr, err := net.ResolveTCPAddr(network, address)
if err != nil { return nil, err }
return ListenTCP(network, addr)
case "unix":
addr, err := net.ResolveUnixAddr(network, address)
if err != nil { return nil, err }
return ListenUnix(network, addr)
default:
return nil, ErrUnknownNetwork
}
}
// ListenQUIC listens for incoming HOPP connections using QUIC as a transport.
// The network must be one of "quic", "quic4", (IPv4-only) or "quic6"
// (IPv6-only).
func ListenQUIC(network, address string, tlsConf *tls.Config) (Listener, error) {
// tlsConf = tlsConfig(tlsConf)
return nil, errors.New("quic is not yet implemented")
}
// ListenTLS listens for incoming HOPP connections using a TLS socket as a
// transport. The network must be "tcp".
func ListenTLS(network, address string, tlsConf *tls.Config) (Listener, error) {
network, err := tlsNetworkToTCPNetwork(network)
if err != nil { return nil, err }
listener, err := tls.Listen(network, address, tlsConf)
if err != nil { return nil, err }
return &netListenerWrapper {
underlying: listener,
}, nil
}
// ListenTCP listens for incoming HOPP connections using a TCP socket as a
// transport. The network must be "tcp".
func ListenTCP(network string, laddr *net.TCPAddr) (Listener, error) {
listener, err := net.ListenTCP(network, laddr)
if err != nil { return nil, err }
return &netListenerWrapper {
underlying: listener,
}, nil
}
// ListenUnix listens for incoming HOPP connections using a Unix domain socket
// as a transport. The network must be "unix".
func ListenUnix(network string, addr *net.UnixAddr) (Listener, error) {
listener, err := net.ListenUnix(network, addr)
if err != nil { return nil, err }
return &netListenerWrapper {
underlying: listener,
}, nil
}
type netListenerWrapper struct {
underlying net.Listener
}
func (this *netListenerWrapper) Accept() (Conn, error) {
conn, err := this.underlying.Accept()
if err != nil { return nil, err }
return AdaptA(conn, ServerSide), nil
}
func (this *netListenerWrapper) Close() error {
return this.underlying.Close()
}
func (this *netListenerWrapper) Addr() net.Addr {
return this.underlying.Addr()
}