|
@ -1,12 +1,17 @@ |
|
|
package libp2pquic |
|
|
package libp2pquic |
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
|
|
|
"context" |
|
|
|
|
|
"errors" |
|
|
|
|
|
"fmt" |
|
|
"net" |
|
|
"net" |
|
|
"sync" |
|
|
"sync" |
|
|
"time" |
|
|
"time" |
|
|
|
|
|
|
|
|
"github.com/lucas-clemente/quic-go/logging" |
|
|
|
|
|
"github.com/prometheus/client_golang/prometheus" |
|
|
"github.com/prometheus/client_golang/prometheus" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/lucas-clemente/quic-go" |
|
|
|
|
|
"github.com/lucas-clemente/quic-go/logging" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
var ( |
|
|
var ( |
|
@ -164,7 +169,9 @@ func init() { |
|
|
|
|
|
|
|
|
type metricsTracer struct{} |
|
|
type metricsTracer struct{} |
|
|
|
|
|
|
|
|
func (m *metricsTracer) TracerForConnection(p logging.Perspective, connID logging.ConnectionID) logging.ConnectionTracer { |
|
|
var _ logging.Tracer = &metricsTracer{} |
|
|
|
|
|
|
|
|
|
|
|
func (m *metricsTracer) TracerForConnection(_ context.Context, p logging.Perspective, connID logging.ConnectionID) logging.ConnectionTracer { |
|
|
return &metricsConnTracer{perspective: p, connID: connID} |
|
|
return &metricsConnTracer{perspective: p, connID: connID} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -217,37 +224,38 @@ func (m *metricsConnTracer) StartedConnection(net.Addr, net.Addr, logging.Connec |
|
|
collector.AddConn(m.connID.String(), m) |
|
|
collector.AddConn(m.connID.String(), m) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (m *metricsConnTracer) ClosedConnection(r logging.CloseReason) { |
|
|
func (m *metricsConnTracer) NegotiatedVersion(chosen quic.VersionNumber, clientVersions []quic.VersionNumber, serverVersions []quic.VersionNumber) { |
|
|
if _, _, ok := r.ApplicationError(); ok { |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (m *metricsConnTracer) ClosedConnection(e error) { |
|
|
|
|
|
var ( |
|
|
|
|
|
transportErr *quic.TransportError |
|
|
|
|
|
remote bool |
|
|
|
|
|
desc string |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
switch { |
|
|
|
|
|
case errors.Is(e, &quic.ApplicationError{}): |
|
|
return |
|
|
return |
|
|
} |
|
|
case errors.As(e, &transportErr): |
|
|
var desc string |
|
|
remote = transportErr.Remote |
|
|
side := "local" |
|
|
desc = transportErr.ErrorCode.String() |
|
|
if _, ok := r.StatelessReset(); ok { |
|
|
case errors.Is(e, &quic.StatelessResetError{}): |
|
|
side = "remote" |
|
|
remote = true |
|
|
desc = "stateless_reset" |
|
|
desc = "stateless_reset" |
|
|
} |
|
|
case errors.Is(e, &quic.VersionNegotiationError{}): |
|
|
if _, ok := r.VersionNegotiation(); ok { |
|
|
|
|
|
desc = "version_negotiation" |
|
|
desc = "version_negotiation" |
|
|
|
|
|
case errors.Is(e, &quic.IdleTimeoutError{}): |
|
|
|
|
|
desc = "idle_timeout" |
|
|
|
|
|
case errors.Is(e, &quic.HandshakeTimeoutError{}): |
|
|
|
|
|
desc = "handshake_timeout" |
|
|
|
|
|
default: |
|
|
|
|
|
desc = fmt.Sprintf("unknown error: %v", e) |
|
|
} |
|
|
} |
|
|
if timeout, ok := r.Timeout(); ok { |
|
|
|
|
|
switch timeout { |
|
|
side := "local" |
|
|
case logging.TimeoutReasonHandshake: |
|
|
if remote { |
|
|
desc = "handshake_timeout" |
|
|
side = "remote" |
|
|
case logging.TimeoutReasonIdle: |
|
|
|
|
|
desc = "idle_timeout" |
|
|
|
|
|
default: |
|
|
|
|
|
desc = "unknown timeout" |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if code, remote, ok := r.TransportError(); ok { |
|
|
|
|
|
if code == 0xc { // ignore APPLICATION_ERROR
|
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
if remote { |
|
|
|
|
|
side = "remote" |
|
|
|
|
|
} |
|
|
|
|
|
desc = code.String() |
|
|
|
|
|
} |
|
|
} |
|
|
connErrors.WithLabelValues(side, desc).Inc() |
|
|
connErrors.WithLabelValues(side, desc).Inc() |
|
|
} |
|
|
} |
|
|