go-proxy/server_runtime.go
Virgil f0477b9980 refactor(proxy): use semantic runtime names
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-04 12:01:40 +00:00

84 lines
1.6 KiB
Go

package proxy
import (
"crypto/tls"
"errors"
"net"
"strconv"
)
// NewServer binds one miner-facing TCP listener.
//
// 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 begins accepting connections in a 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.
//
// 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")