fix: log cmpp packet decode failures
This commit is contained in:
@@ -25,6 +25,7 @@ type Server struct {
|
||||
Addr string
|
||||
APIBaseURL string
|
||||
HTTPClient *http.Client
|
||||
LogWriter io.Writer
|
||||
PendingFlushInterval time.Duration
|
||||
PresenceStore PresenceStore
|
||||
RecoveryStore RecoveryStore
|
||||
@@ -116,7 +117,7 @@ func (s Server) ListenAndServe() error {
|
||||
s.logRecoveryCandidates(log.Default())
|
||||
go s.recoverPendingCandidates(log.Default())
|
||||
go s.runPendingFlusher(log.Default())
|
||||
return cmpp.ListenAndServe(addr, cmpp.V30, 30*time.Second, 3, nil,
|
||||
return cmpp.ListenAndServe(addr, cmpp.V30, 30*time.Second, 3, s.LogWriter,
|
||||
cmpp.HandlerFunc(s.handleLogin),
|
||||
cmpp.HandlerFunc(s.handleSubmit),
|
||||
)
|
||||
@@ -158,7 +159,7 @@ func (s Server) handleLogin(response *cmpp.Response, packet *cmpp.Packet, logger
|
||||
go s.flushPending(defaultString(auth.Account, account), logger)
|
||||
logger.Printf(
|
||||
"cmpp inbound event=login_accepted protocol=%s requested_version=0x%02x response_version=0x30 account=%s remote=%s",
|
||||
cmppVersionName(req.Version), req.Version, account, packet.Conn.Conn.RemoteAddr(),
|
||||
cmppVersionName(req.Version), uint8(req.Version), account, packet.Conn.Conn.RemoteAddr(),
|
||||
)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@ package inbound
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -26,6 +28,23 @@ type memoryRecoveryStore struct {
|
||||
completed []DownstreamRecoveryStatus
|
||||
}
|
||||
|
||||
type synchronizedBuffer struct {
|
||||
mu sync.Mutex
|
||||
buffer bytes.Buffer
|
||||
}
|
||||
|
||||
func (b *synchronizedBuffer) Write(data []byte) (int, error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.buffer.Write(data)
|
||||
}
|
||||
|
||||
func (b *synchronizedBuffer) String() string {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.buffer.String()
|
||||
}
|
||||
|
||||
func (m *memoryPresenceStore) TouchAccount(_ context.Context, snapshot DownstreamPresence) error {
|
||||
if m.snapshots == nil {
|
||||
m.snapshots = map[string]DownstreamPresence{}
|
||||
@@ -181,6 +200,33 @@ func TestPostIncludesAPIErrorResponseBody(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInboundServerLogsReadUnpackFailure(t *testing.T) {
|
||||
addr := reserveTCPAddr(t)
|
||||
var logs synchronizedBuffer
|
||||
go func() {
|
||||
_ = (Server{Addr: addr, LogWriter: &logs}).ListenAndServe()
|
||||
}()
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
|
||||
conn, err := net.DialTimeout("tcp", addr, time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("connect inbound server: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
if err := binary.Write(conn, binary.BigEndian, uint32(1)); err != nil {
|
||||
t.Fatalf("write invalid packet length: %v", err)
|
||||
}
|
||||
|
||||
deadline := time.Now().Add(2 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
if strings.Contains(logs.String(), "read/unpack packet failed") && strings.Contains(logs.String(), "total_length") {
|
||||
return
|
||||
}
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
}
|
||||
t.Fatalf("missing read/unpack failure log: %s", logs.String())
|
||||
}
|
||||
|
||||
func TestNormalizeInboundSubmitSupportsCMPP2AndCMPP3(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user