go-proxy/server_runtime.go

85 lines
1.7 KiB
Go
Raw Permalink Normal View History

package proxy
import (
"crypto/tls"
"errors"
"net"
"strconv"
)
// NewServer opens a listener and prepares the accept loop.
//
// srv, errorValue := proxy.NewServer(proxy.BindAddr{Host: "0.0.0.0", Port: 3333}, nil, rateLimiter, onAccept)
func NewServer(bindAddress BindAddr, tlsConfig *tls.Config, rateLimiter *RateLimiter, onAccept func(net.Conn, uint16)) (*Server, error) {
address := net.JoinHostPort(bindAddress.Host, strconv.Itoa(int(bindAddress.Port)))
listener, errorValue := net.Listen("tcp", address)
if errorValue != nil {
return nil, errorValue
}
return &Server{
addr: bindAddress,
tlsCfg: tlsConfig,
limiter: rateLimiter,
onAccept: onAccept,
listener: listener,
done: make(chan struct{}),
}, nil
}
// Start accepts miners in a background goroutine.
//
// srv.Start()
func (server *Server) Start() {
if server == nil || server.listener == nil {
return
}
go func() {
for {
conn, errorValue := server.listener.Accept()
if errorValue != nil {
select {
case <-server.done:
return
default:
continue
}
}
if server.limiter != nil && !server.limiter.Allow(conn.RemoteAddr().String()) {
_ = conn.Close()
continue
}
if server.tlsCfg != nil {
conn = tls.Server(conn, server.tlsCfg)
}
if server.onAccept == nil {
_ = conn.Close()
continue
}
server.onAccept(conn, server.addr.Port)
}
}()
}
// Stop closes the listener without forcing existing sockets shut.
//
// srv.Stop()
func (server *Server) Stop() {
if server == nil || server.listener == nil {
return
}
select {
case <-server.done:
default:
close(server.done)
}
_ = server.listener.Close()
}
var errServerClosed = errors.New("server closed")