mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 13:29:27 +01:00
make ReloadableListener lock-free
Also stop attaching the *tls.Config to the wrapped connection, since this forces it to be retained beyond its natural lifetime.
This commit is contained in:
parent
bceae9b739
commit
3ceff6a8b1
@ -295,7 +295,7 @@ func (server *Server) RunClient(conn IRCConn) {
|
|||||||
var banMsg string
|
var banMsg string
|
||||||
realIP := utils.AddrToIP(wConn.RemoteAddr())
|
realIP := utils.AddrToIP(wConn.RemoteAddr())
|
||||||
var proxiedIP net.IP
|
var proxiedIP net.IP
|
||||||
if wConn.Config.Tor {
|
if wConn.Tor {
|
||||||
// cover up details of the tor proxying infrastructure (not a user privacy concern,
|
// cover up details of the tor proxying infrastructure (not a user privacy concern,
|
||||||
// but a hardening measure):
|
// but a hardening measure):
|
||||||
proxiedIP = utils.IPv4LoopbackAddress
|
proxiedIP = utils.IPv4LoopbackAddress
|
||||||
@ -329,7 +329,7 @@ func (server *Server) RunClient(conn IRCConn) {
|
|||||||
lastActive: now,
|
lastActive: now,
|
||||||
channels: make(ChannelSet),
|
channels: make(ChannelSet),
|
||||||
ctime: now,
|
ctime: now,
|
||||||
isSTSOnly: wConn.Config.STSOnly,
|
isSTSOnly: wConn.STSOnly,
|
||||||
languages: server.Languages().Default(),
|
languages: server.Languages().Default(),
|
||||||
loginThrottle: connection_limits.GenericThrottle{
|
loginThrottle: connection_limits.GenericThrottle{
|
||||||
Duration: config.Accounts.LoginThrottling.Duration,
|
Duration: config.Accounts.LoginThrottling.Duration,
|
||||||
@ -358,8 +358,8 @@ func (server *Server) RunClient(conn IRCConn) {
|
|||||||
lastActive: now,
|
lastActive: now,
|
||||||
realIP: realIP,
|
realIP: realIP,
|
||||||
proxiedIP: proxiedIP,
|
proxiedIP: proxiedIP,
|
||||||
isTor: wConn.Config.Tor,
|
isTor: wConn.Tor,
|
||||||
hideSTS: wConn.Config.Tor || wConn.Config.HideSTS,
|
hideSTS: wConn.Tor || wConn.HideSTS,
|
||||||
}
|
}
|
||||||
client.sessions = []*Session{session}
|
client.sessions = []*Session{session}
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ func (server *Server) RunClient(conn IRCConn) {
|
|||||||
client.SetMode(modes.TLS, true)
|
client.SetMode(modes.TLS, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if wConn.Config.TLSConfig != nil {
|
if wConn.TLS {
|
||||||
// error is not useful to us here anyways so we can ignore it
|
// error is not useful to us here anyways so we can ignore it
|
||||||
session.certfp, session.peerCerts, _ = utils.GetCertFP(wConn.Conn, RegisterTimeout)
|
session.certfp, session.peerCerts, _ = utils.GetCertFP(wConn.Conn, RegisterTimeout)
|
||||||
}
|
}
|
||||||
|
@ -204,10 +204,10 @@ func confirmProxyData(conn *utils.WrappedConn, remoteAddr, xForwardedFor, xForwa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if conn.Config.TLSConfig != nil || conn.Config.Tor {
|
if conn.TLS || conn.Tor {
|
||||||
// we terminated our own encryption:
|
// we terminated our own encryption:
|
||||||
conn.Secure = true
|
conn.Secure = true
|
||||||
} else if !conn.Config.WebSocket {
|
} else if !conn.WebSocket {
|
||||||
// plaintext normal connection: loopback and secureNets are secure
|
// plaintext normal connection: loopback and secureNets are secure
|
||||||
realIP := utils.AddrToIP(conn.RemoteAddr())
|
realIP := utils.AddrToIP(conn.RemoteAddr())
|
||||||
conn.Secure = realIP.IsLoopback() || utils.IPInNets(realIP, config.Server.secureNets)
|
conn.Secure = realIP.IsLoopback() || utils.IPInNets(realIP, config.Server.secureNets)
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -209,7 +209,11 @@ func parseProxyLineV2(line []byte) (ip net.IP, err error) {
|
|||||||
type WrappedConn struct {
|
type WrappedConn struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
ProxiedIP net.IP
|
ProxiedIP net.IP
|
||||||
Config ListenerConfig
|
TLS bool
|
||||||
|
Tor bool
|
||||||
|
STSOnly bool
|
||||||
|
WebSocket bool
|
||||||
|
HideSTS bool
|
||||||
// Secure indicates whether we believe the connection between us and the client
|
// Secure indicates whether we believe the connection between us and the client
|
||||||
// was secure against interception and modification (including all proxies):
|
// was secure against interception and modification (including all proxies):
|
||||||
Secure bool
|
Secure bool
|
||||||
@ -218,35 +222,30 @@ type WrappedConn struct {
|
|||||||
// ReloadableListener is a wrapper for net.Listener that allows reloading
|
// ReloadableListener is a wrapper for net.Listener that allows reloading
|
||||||
// of config data for postprocessing connections (TLS, PROXY protocol, etc.)
|
// of config data for postprocessing connections (TLS, PROXY protocol, etc.)
|
||||||
type ReloadableListener struct {
|
type ReloadableListener struct {
|
||||||
// TODO: make this lock-free
|
|
||||||
sync.Mutex
|
|
||||||
realListener net.Listener
|
realListener net.Listener
|
||||||
config ListenerConfig
|
// nil means the listener is closed:
|
||||||
isClosed bool
|
config atomic.Pointer[ListenerConfig]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReloadableListener(realListener net.Listener, config ListenerConfig) *ReloadableListener {
|
func NewReloadableListener(realListener net.Listener, config ListenerConfig) *ReloadableListener {
|
||||||
return &ReloadableListener{
|
result := &ReloadableListener{
|
||||||
realListener: realListener,
|
realListener: realListener,
|
||||||
config: config,
|
|
||||||
}
|
}
|
||||||
|
result.config.Store(&config) // heap escape
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rl *ReloadableListener) Reload(config ListenerConfig) {
|
func (rl *ReloadableListener) Reload(config ListenerConfig) {
|
||||||
rl.Lock()
|
rl.config.Store(&config)
|
||||||
rl.config = config
|
|
||||||
rl.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rl *ReloadableListener) Accept() (conn net.Conn, err error) {
|
func (rl *ReloadableListener) Accept() (conn net.Conn, err error) {
|
||||||
conn, err = rl.realListener.Accept()
|
conn, err = rl.realListener.Accept()
|
||||||
|
|
||||||
rl.Lock()
|
config := rl.config.Load()
|
||||||
config := rl.config
|
|
||||||
isClosed := rl.isClosed
|
|
||||||
rl.Unlock()
|
|
||||||
|
|
||||||
if isClosed {
|
if config == nil {
|
||||||
|
// Close() was called
|
||||||
if err == nil {
|
if err == nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
@ -279,14 +278,17 @@ func (rl *ReloadableListener) Accept() (conn net.Conn, err error) {
|
|||||||
return &WrappedConn{
|
return &WrappedConn{
|
||||||
Conn: conn,
|
Conn: conn,
|
||||||
ProxiedIP: proxiedIP,
|
ProxiedIP: proxiedIP,
|
||||||
Config: config,
|
TLS: config.TLSConfig != nil,
|
||||||
|
Tor: config.Tor,
|
||||||
|
STSOnly: config.STSOnly,
|
||||||
|
WebSocket: config.WebSocket,
|
||||||
|
HideSTS: config.HideSTS,
|
||||||
|
// Secure will be set later by client code
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rl *ReloadableListener) Close() error {
|
func (rl *ReloadableListener) Close() error {
|
||||||
rl.Lock()
|
rl.config.Store(nil)
|
||||||
rl.isClosed = true
|
|
||||||
rl.Unlock()
|
|
||||||
|
|
||||||
return rl.realListener.Close()
|
return rl.realListener.Close()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user