84 lines
1.7 KiB
Go
84 lines
1.7 KiB
Go
package proxy
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"errors"
|
|
"net"
|
|
"strconv"
|
|
)
|
|
|
|
// NewServer opens `0.0.0.0:3333` and prepares the accept loop.
|
|
//
|
|
// srv, errorValue := proxy.NewServer(bindAddress, 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 `0.0.0.0:3333` 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")
|