80 lines
1.4 KiB
Go
80 lines
1.4 KiB
Go
package proxy
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"errors"
|
|
"net"
|
|
"strconv"
|
|
)
|
|
|
|
// NewServer binds one miner-facing TCP listener.
|
|
//
|
|
// srv, errorValue := proxy.NewServer(bind, nil, limiter, onAccept)
|
|
func NewServer(bind BindAddr, tlsCfg *tls.Config, limiter *RateLimiter, onAccept func(net.Conn, uint16)) (*Server, error) {
|
|
address := net.JoinHostPort(bind.Host, strconv.Itoa(int(bind.Port)))
|
|
listener, errorValue := net.Listen("tcp", address)
|
|
if errorValue != nil {
|
|
return nil, errorValue
|
|
}
|
|
|
|
return &Server{
|
|
addr: bind,
|
|
tlsCfg: tlsCfg,
|
|
limiter: limiter,
|
|
onAccept: onAccept,
|
|
listener: listener,
|
|
done: make(chan struct{}),
|
|
}, nil
|
|
}
|
|
|
|
// Start begins accepting connections in a goroutine.
|
|
//
|
|
// srv.Start()
|
|
func (s *Server) Start() {
|
|
if s == nil || s.listener == nil {
|
|
return
|
|
}
|
|
|
|
go func() {
|
|
for {
|
|
conn, errorValue := s.listener.Accept()
|
|
if errorValue != nil {
|
|
select {
|
|
case <-s.done:
|
|
return
|
|
default:
|
|
continue
|
|
}
|
|
}
|
|
|
|
if s.limiter != nil && !s.limiter.Allow(conn.RemoteAddr().String()) {
|
|
_ = conn.Close()
|
|
continue
|
|
}
|
|
|
|
if s.onAccept == nil {
|
|
_ = conn.Close()
|
|
continue
|
|
}
|
|
s.onAccept(conn, s.addr.Port)
|
|
}
|
|
}()
|
|
}
|
|
|
|
// Stop closes the listener.
|
|
//
|
|
// srv.Stop()
|
|
func (s *Server) Stop() {
|
|
if s == nil || s.listener == nil {
|
|
return
|
|
}
|
|
|
|
select {
|
|
case <-s.done:
|
|
default:
|
|
close(s.done)
|
|
}
|
|
_ = s.listener.Close()
|
|
}
|
|
|
|
var errServerClosed = errors.New("server closed")
|