mirror of
https://github.com/mjl-/mox.git
synced 2024-12-28 01:13:47 +03:00
Count ALPN connections separately in metrics
Also this required a new attribute on the IMAP and SMTP connection structs, and made it easier to avoid using the reflection tools.
This commit is contained in:
parent
f02e04df72
commit
f7976539ea
2 changed files with 19 additions and 14 deletions
|
@ -52,7 +52,6 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"slices"
|
||||
"sort"
|
||||
|
@ -171,6 +170,7 @@ type conn struct {
|
|||
state state
|
||||
conn net.Conn
|
||||
tls bool // Whether TLS has been initialized.
|
||||
viaHTTPS bool // Whether this connection came in via HTTPS (using TLS ALPN).
|
||||
br *bufio.Reader // From remote, with TLS unwrapped in case of TLS.
|
||||
line chan lineErr // If set, instead of reading from br, a line is read from this channel. For reading a line in IDLE while also waiting for mailbox/account updates.
|
||||
lastLine string // For detecting if syntax error is fatal, i.e. if this ends with a literal. Without crlf.
|
||||
|
@ -347,8 +347,9 @@ func Listen() http.FnALPNHelper {
|
|||
}
|
||||
if listener.IMAPS.EnableOnHTTPS && alpnHelper == nil {
|
||||
alpnHelper = func(tc *tls.Config, conn net.Conn) {
|
||||
protocol = protocol + "https"
|
||||
metricIMAPConnection.WithLabelValues(protocol).Inc()
|
||||
serve(name, mox.Cid(), tc, conn, true, false)
|
||||
serve(name, mox.Cid(), tc, conn, true, false, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +392,7 @@ func listen1(protocol, listenerName, ip string, port int, tlsConfig *tls.Config,
|
|||
}
|
||||
|
||||
metricIMAPConnection.WithLabelValues(protocol).Inc()
|
||||
go serve(listenerName, mox.Cid(), tlsConfig, conn, xtls, noRequireSTARTTLS)
|
||||
go serve(listenerName, mox.Cid(), tlsConfig, conn, xtls, noRequireSTARTTLS, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -646,7 +647,7 @@ func (c *conn) xhighestModSeq(tx *bstore.Tx, mailboxID int64) store.ModSeq {
|
|||
|
||||
var cleanClose struct{} // Sentinel value for panic/recover indicating clean close of connection.
|
||||
|
||||
func serve(listenerName string, cid int64, tlsConfig *tls.Config, nc net.Conn, xtls, noRequireSTARTTLS bool) {
|
||||
func serve(listenerName string, cid int64, tlsConfig *tls.Config, nc net.Conn, xtls, noRequireSTARTTLS, viaHTTPS bool) {
|
||||
var remoteIP net.IP
|
||||
if a, ok := nc.RemoteAddr().(*net.TCPAddr); ok {
|
||||
remoteIP = a.IP
|
||||
|
@ -659,6 +660,7 @@ func serve(listenerName string, cid int64, tlsConfig *tls.Config, nc net.Conn, x
|
|||
cid: cid,
|
||||
conn: nc,
|
||||
tls: xtls,
|
||||
viaHTTPS: viaHTTPS,
|
||||
lastlog: time.Now(),
|
||||
baseTLSConfig: tlsConfig,
|
||||
remoteIP: remoteIP,
|
||||
|
@ -728,8 +730,7 @@ func serve(listenerName string, cid int64, tlsConfig *tls.Config, nc net.Conn, x
|
|||
}
|
||||
}()
|
||||
|
||||
isAlreadyTLS := reflect.TypeOf(nc) == reflect.TypeFor[*tls.Conn]()
|
||||
if xtls && !isAlreadyTLS {
|
||||
if xtls && !viaHTTPS {
|
||||
// Start TLS on connection. We perform the handshake explicitly, so we can set a
|
||||
// timeout, do client certificate authentication, log TLS details afterwards.
|
||||
c.xtlsHandshakeAndAuthenticate(c.conn)
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"net"
|
||||
"net/textproto"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"slices"
|
||||
"sort"
|
||||
|
@ -266,7 +265,7 @@ func Listen() http.FnALPNHelper {
|
|||
alpnHelper = func(tc *tls.Config, conn net.Conn) {
|
||||
log := mlog.New("smtpserver", nil)
|
||||
resolver := dns.StrictResolver{Log: log.Logger}
|
||||
serve(name, mox.Cid(), hostname, tc, conn, resolver, true, true, maxMsgSize, true, true, true, nil, 0)
|
||||
serve(name, mox.Cid(), hostname, tc, conn, resolver, true, true, true, maxMsgSize, true, true, true, nil, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +309,7 @@ func listen1(protocol, name, ip string, port int, hostname dns.Domain, tlsConfig
|
|||
|
||||
// Package is set on the resolver by the dkim/spf/dmarc/etc packages.
|
||||
resolver := dns.StrictResolver{Log: log.Logger}
|
||||
go serve(name, mox.Cid(), hostname, tlsConfig, conn, resolver, submission, xtls, maxMessageSize, requireTLSForAuth, requireTLSForDelivery, requireTLS, dnsBLs, firstTimeSenderDelay)
|
||||
go serve(name, mox.Cid(), hostname, tlsConfig, conn, resolver, submission, xtls, false, maxMessageSize, requireTLSForAuth, requireTLSForDelivery, requireTLS, dnsBLs, firstTimeSenderDelay)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,6 +335,7 @@ type conn struct {
|
|||
|
||||
tls bool
|
||||
extRequireTLS bool // Whether to announce and allow the REQUIRETLS extension.
|
||||
viaHTTPS bool // Whether the connection came in via the HTTPS port (using TLS ALPN).
|
||||
resolver dns.Resolver
|
||||
r *bufio.Reader
|
||||
w *bufio.Writer
|
||||
|
@ -810,7 +810,7 @@ func (c *conn) writelinef(format string, args ...any) {
|
|||
|
||||
var cleanClose struct{} // Sentinel value for panic/recover indicating clean close of connection.
|
||||
|
||||
func serve(listenerName string, cid int64, hostname dns.Domain, tlsConfig *tls.Config, nc net.Conn, resolver dns.Resolver, submission, xtls bool, maxMessageSize int64, requireTLSForAuth, requireTLSForDelivery, requireTLS bool, dnsBLs []dns.Domain, firstTimeSenderDelay time.Duration) {
|
||||
func serve(listenerName string, cid int64, hostname dns.Domain, tlsConfig *tls.Config, nc net.Conn, resolver dns.Resolver, submission, xtls, viaHTTPS bool, maxMessageSize int64, requireTLSForAuth, requireTLSForDelivery, requireTLS bool, dnsBLs []dns.Domain, firstTimeSenderDelay time.Duration) {
|
||||
var localIP, remoteIP net.IP
|
||||
if a, ok := nc.LocalAddr().(*net.TCPAddr); ok {
|
||||
localIP = a.IP
|
||||
|
@ -831,6 +831,7 @@ func serve(listenerName string, cid int64, hostname dns.Domain, tlsConfig *tls.C
|
|||
conn: nc,
|
||||
submission: submission,
|
||||
tls: xtls,
|
||||
viaHTTPS: viaHTTPS,
|
||||
extRequireTLS: requireTLS,
|
||||
resolver: resolver,
|
||||
lastlog: time.Now(),
|
||||
|
@ -894,8 +895,7 @@ func serve(listenerName string, cid int64, hostname dns.Domain, tlsConfig *tls.C
|
|||
}
|
||||
}()
|
||||
|
||||
isAlreadyTLS := reflect.TypeOf(nc) == reflect.TypeFor[*tls.Conn]()
|
||||
if xtls && !isAlreadyTLS {
|
||||
if xtls && !viaHTTPS {
|
||||
// Start TLS on connection. We perform the handshake explicitly, so we can set a
|
||||
// timeout, do client certificate authentication, log TLS details afterwards.
|
||||
c.xtlsHandshakeAndAuthenticate(c.conn)
|
||||
|
@ -1046,10 +1046,14 @@ func command(c *conn) {
|
|||
|
||||
// For use in metric labels.
|
||||
func (c *conn) kind() string {
|
||||
k := "smtp"
|
||||
if c.submission {
|
||||
return "submission"
|
||||
k = "submission"
|
||||
}
|
||||
return "smtp"
|
||||
if c.viaHTTPS {
|
||||
k = k + "https"
|
||||
}
|
||||
return k
|
||||
}
|
||||
|
||||
func (c *conn) xneedHello() {
|
||||
|
|
Loading…
Reference in a new issue