Skip to content

Commit

Permalink
refactor: finish udp tracker tests
Browse files Browse the repository at this point in the history
  • Loading branch information
crimist committed Jul 25, 2024
1 parent 6766d57 commit 001a0d5
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 89 deletions.
4 changes: 2 additions & 2 deletions refactoring.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## Current

Finish refactoring the UDP tracker test. Grep for `TODO(latest):`
Refactoring UDP conn cache

## Future

* Refactor UDP sub packages
* Refactor UDP protocol package (probably just needs updated tests)
* Refactor HTTP tracker
* Refactor HTTP tracker tests
* Refactor controller / command line interface
Expand Down
22 changes: 11 additions & 11 deletions tracker/udp/announce.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"go.uber.org/zap"
)

const (
fatalInvalidPort = "invalid announce port"
var (
fatalInvalidPort = []byte("invalid announce port")
)

func (tracker *Tracker) announce(udpAddr *net.UDPAddr, addrPort netip.AddrPort, transactionID int32, data []byte) {
Expand All @@ -21,20 +21,20 @@ func (tracker *Tracker) announce(udpAddr *net.UDPAddr, addrPort netip.AddrPort,
}

if len(data) < minimumAnnounceSize {
tracker.sendError(udpAddr, "announce too short", transactionID)
tracker.fatal(udpAddr, []byte("announce too short"), transactionID)
zap.L().Debug("client sent announce below minimum size", zap.Binary("packet", data), zap.Int("size", len(data)), zap.Any("remote", addrPort))
return
}

announceRequest, err := udpprotocol.NewAnnounceRequest(data)
if err != nil {
tracker.sendError(udpAddr, "failed to parse announce", transactionID)
tracker.fatal(udpAddr, []byte("failed to parse announce"), transactionID)
zap.L().Debug("failed to parse clients announce packet", zap.Binary("packet", data), zap.Error(err), zap.Any("remote", addrPort))
return
}

if announceRequest.Port == 0 {
tracker.sendError(udpAddr, fatalInvalidPort, announceRequest.TransactionID)
tracker.fatal(udpAddr, fatalInvalidPort, announceRequest.TransactionID)
zap.L().Debug("client sent announce with invalid port", zap.Any("announce", announceRequest), zap.Uint16("port", announceRequest.Port), zap.Any("remote", udpAddr))
return
}
Expand All @@ -59,13 +59,13 @@ func (tracker *Tracker) announce(udpAddr *net.UDPAddr, addrPort netip.AddrPort,
Action: udpprotocol.ActionAnnounce,
TransactionID: announceRequest.TransactionID,
Interval: interval,
Leechers: int32(leeches),
Seeders: int32(seeds),
Leeches: int32(leeches),
Seeds: int32(seeds),
Peers: []byte{},
}
respBytes, err := marshalledResp.Marshall()
if err != nil {
tracker.sendError(udpAddr, "failed to marshall announce response", announceRequest.TransactionID)
tracker.fatal(udpAddr, []byte("failed to marshall announce response"), announceRequest.TransactionID)
zap.L().Error("failed to marshall announce response", zap.Error(err), zap.Any("announce", announceRequest), zap.Any("remote", udpAddr))
return
}
Expand Down Expand Up @@ -94,8 +94,8 @@ func (tracker *Tracker) announce(udpAddr *net.UDPAddr, addrPort netip.AddrPort,
Action: udpprotocol.ActionAnnounce,
TransactionID: announceRequest.TransactionID,
Interval: interval,
Leechers: int32(leeches),
Seeders: int32(seeds),
Leeches: int32(leeches),
Seeds: int32(seeds),
}

if ipversion == storage.IPv4 {
Expand All @@ -112,7 +112,7 @@ func (tracker *Tracker) announce(udpAddr *net.UDPAddr, addrPort netip.AddrPort,
}

if err != nil {
tracker.sendError(udpAddr, "failed to marshall announce response", announceRequest.TransactionID)
tracker.fatal(udpAddr, []byte("failed to marshall announce response"), announceRequest.TransactionID)
zap.L().Error("failed to marshall announce response", zap.Error(err), zap.Any("announce", announceRequest), zap.Any("remote", udpAddr))
return
}
Expand Down
54 changes: 26 additions & 28 deletions tracker/udp/announce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func announceError(t *testing.T, conn *net.UDPConn, announceReq udpprotocol.Anno
}

func TestAnnounceStarted(t *testing.T) {
conn := dialMockTracker(t, testNetworkAddress4)
conn := dialMockTracker(t, testNetAddress4)
connectResp := connect(t, conn, udpprotocol.ConnectRequest{
ProtcolID: udpprotocol.ProtocolMagic,
Action: udpprotocol.ActionConnect,
Expand All @@ -83,11 +83,11 @@ func TestAnnounceStarted(t *testing.T) {
Port: 0xAABB,
})

if announceResp.Leechers != 1 {
t.Errorf("Expected leeches = %v; got %v", 1, announceResp.Leechers)
if announceResp.Leeches != 1 {
t.Errorf("Expected leeches = %v; got %v", 1, announceResp.Leeches)
}
if announceResp.Seeders != 0 {
t.Errorf("Expected seeds = %v; got %v", 0, announceResp.Seeders)
if announceResp.Seeds != 0 {
t.Errorf("Expected seeds = %v; got %v", 0, announceResp.Seeds)
}
if len(announceResp.Peers) != 1 {
t.Errorf("Expected len(peers) = %v; got %v", 1, len(announceResp.Peers))
Expand All @@ -101,7 +101,7 @@ func TestAnnounceStarted(t *testing.T) {
}

func TestAnnounceStarted6(t *testing.T) {
conn := dialMockTracker(t, testNetworkAddress4)
conn := dialMockTracker(t, testNetAddress4)
connectResp := connect(t, conn, udpprotocol.ConnectRequest{
ProtcolID: udpprotocol.ProtocolMagic,
Action: udpprotocol.ActionConnect,
Expand All @@ -124,11 +124,11 @@ func TestAnnounceStarted6(t *testing.T) {
Port: 0xAABB,
})

if announceResp.Leechers != 1 {
t.Errorf("Expected leeches = %v; got %v", 1, announceResp.Leechers)
if announceResp.Leeches != 1 {
t.Errorf("Expected leeches = %v; got %v", 1, announceResp.Leeches)
}
if announceResp.Seeders != 0 {
t.Errorf("Expected seeds = %v; got %v", 0, announceResp.Seeders)
if announceResp.Seeds != 0 {
t.Errorf("Expected seeds = %v; got %v", 0, announceResp.Seeds)
}
if len(announceResp.Peers) != 1 {
t.Errorf("Expected len(peers) = %v; got %v", 1, len(announceResp.Peers))
Expand All @@ -143,7 +143,7 @@ func TestAnnounceStarted6(t *testing.T) {

// Test an announce with event = completed
func TestAnnounceCompleteEvent(t *testing.T) {
conn := dialMockTracker(t, testNetworkAddress4)
conn := dialMockTracker(t, testNetAddress4)
connectResp := connect(t, conn, udpprotocol.ConnectRequest{
ProtcolID: udpprotocol.ProtocolMagic,
Action: udpprotocol.ActionConnect,
Expand All @@ -166,11 +166,11 @@ func TestAnnounceCompleteEvent(t *testing.T) {
Port: 0xAABB,
})

if announceResp.Leechers != 1 {
t.Errorf("Expected leeches = %v; got %v", 1, announceResp.Leechers)
if announceResp.Leeches != 1 {
t.Errorf("Expected leeches = %v; got %v", 1, announceResp.Leeches)
}
if announceResp.Seeders != 1 {
t.Errorf("Expected seeds = %v; got %v", 1, announceResp.Seeders)
if announceResp.Seeds != 1 {
t.Errorf("Expected seeds = %v; got %v", 1, announceResp.Seeds)
}
if len(announceResp.Peers) != 1 {
t.Errorf("Expected len(peers) = %v; got %v", 1, len(announceResp.Peers))
Expand All @@ -185,7 +185,7 @@ func TestAnnounceCompleteEvent(t *testing.T) {

// Test an announce where left = 0
func TestAnnounceCompleteLeft(t *testing.T) {
conn := dialMockTracker(t, testNetworkAddress4)
conn := dialMockTracker(t, testNetAddress4)
connectResp := connect(t, conn, udpprotocol.ConnectRequest{
ProtcolID: udpprotocol.ProtocolMagic,
Action: udpprotocol.ActionConnect,
Expand All @@ -208,11 +208,11 @@ func TestAnnounceCompleteLeft(t *testing.T) {
Port: 0xAABB,
})

if announceResp.Leechers != 0 {
t.Errorf("Expected leeches = %v; got %v", 0, announceResp.Leechers)
if announceResp.Leeches != 0 {
t.Errorf("Expected leeches = %v; got %v", 0, announceResp.Leeches)
}
if announceResp.Seeders != 1 {
t.Errorf("Expected seeds = %v; got %v", 1, announceResp.Seeders)
if announceResp.Seeds != 1 {
t.Errorf("Expected seeds = %v; got %v", 1, announceResp.Seeds)
}
if len(announceResp.Peers) != 1 {
t.Errorf("Expected len(peers) = %v; got %v", 1, len(announceResp.Peers))
Expand All @@ -226,7 +226,7 @@ func TestAnnounceCompleteLeft(t *testing.T) {
}

func TestAnnounceStopped(t *testing.T) {
conn := dialMockTracker(t, testNetworkAddress4)
conn := dialMockTracker(t, testNetAddress4)
connectResp := connect(t, conn, udpprotocol.ConnectRequest{
ProtcolID: udpprotocol.ProtocolMagic,
Action: udpprotocol.ActionConnect,
Expand All @@ -249,19 +249,19 @@ func TestAnnounceStopped(t *testing.T) {
Port: 0xAABB,
})

if announceResp.Leechers != 0 {
t.Errorf("Expected leeches = %v; got %v", 0, announceResp.Leechers)
if announceResp.Leeches != 0 {
t.Errorf("Expected leeches = %v; got %v", 0, announceResp.Leeches)
}
if announceResp.Seeders != 0 {
t.Errorf("Expected seeds = %v; got %v", 0, announceResp.Seeders)
if announceResp.Seeds != 0 {
t.Errorf("Expected seeds = %v; got %v", 0, announceResp.Seeds)
}
if len(announceResp.Peers) != 0 {
t.Errorf("Expected len(peers) = %v; got %v", 0, len(announceResp.Peers))
}
}

func TestAnnounceInvalidPort(t *testing.T) {
conn := dialMockTracker(t, testNetworkAddress4)
conn := dialMockTracker(t, testNetAddress4)
connectResp := connect(t, conn, udpprotocol.ConnectRequest{
ProtcolID: udpprotocol.ProtocolMagic,
Action: udpprotocol.ActionConnect,
Expand All @@ -288,5 +288,3 @@ func TestAnnounceInvalidPort(t *testing.T) {
t.Errorf("Expected error = %v; got %v", fatalInvalidPort, errorResp.ErrorString)
}
}

// TODO(latest): write tests for the rest of the fatal client errors
4 changes: 2 additions & 2 deletions tracker/udp/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (tracker *Tracker) connect(udpAddr *net.UDPAddr, addrPort netip.AddrPort, t

connectRequest, err := udpprotocol.NewConnectRequest(data)
if err != nil {
tracker.sendError(udpAddr, "failed to parse connect request", transactionID)
tracker.fatal(udpAddr, []byte("failed to parse connect request"), transactionID)
zap.L().Debug("client sent invalid connect request", zap.Binary("packet", data), zap.Error(err), zap.Any("remote", addrPort))
return
}
Expand All @@ -32,7 +32,7 @@ func (tracker *Tracker) connect(udpAddr *net.UDPAddr, addrPort netip.AddrPort, t

marshalledResp, err := resp.Marshall()
if err != nil {
tracker.sendError(udpAddr, "failed to marshall connect response", connectRequest.TransactionID)
tracker.fatal(udpAddr, []byte("failed to marshall connect response"), connectRequest.TransactionID)
zap.L().Error("failed to marshall connect response", zap.Error(err), zap.Any("connect", connectRequest), zap.Any("remote", udpAddr))
return
}
Expand Down
6 changes: 1 addition & 5 deletions tracker/udp/connect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func connect(t *testing.T, conn *net.UDPConn, connectReq udpprotocol.ConnectRequ
}

func TestConnectSuccess(t *testing.T) {
conn := dialMockTracker(t, testNetworkAddress4)
conn := dialMockTracker(t, testNetAddress4)
connectReq := udpprotocol.ConnectRequest{
ProtcolID: udpprotocol.ProtocolMagic,
Action: udpprotocol.ActionConnect,
Expand All @@ -43,7 +43,3 @@ func TestConnectSuccess(t *testing.T) {
t.Errorf("Expected transaction ID = %v; got %v", connectReq.TransactionID, connectResp.TransactionID)
}
}

func TestConnectBadAction(t *testing.T) {
// TODO: does this test need to be written? Is it a generic bad action test?
}
6 changes: 3 additions & 3 deletions tracker/udp/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ import (
"go.uber.org/zap"
)

// TODO: rename this to `fatal`
func (tracker *Tracker) sendError(remote *net.UDPAddr, message string, TransactionID int32) {
func (tracker *Tracker) fatal(remote *net.UDPAddr, message []byte, TransactionID int32) {
if tracker.stats != nil {
// TODO: this isn't right
tracker.stats.ServerErrors.Add(1)
}

protoError := udpprotocol.ErrorResponse{
Action: udpprotocol.ActionError,
TransactionID: TransactionID,
ErrorString: []byte("internal error"),
ErrorString: message,
}

data, err := protoError.Marshall()
Expand Down
11 changes: 5 additions & 6 deletions tracker/udp/scrape.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"net/netip"

"github.com/crimist/trakx/tracker/udp/udpprotocol"
"github.com/crimist/trakx/utils"
"go.uber.org/zap"
)

Expand All @@ -18,14 +17,14 @@ func (tracker *Tracker) scrape(udpAddr *net.UDPAddr, addrPort netip.AddrPort, tr

scrape, err := udpprotocol.NewScrapeRequest(data)
if err != nil {
tracker.sendError(udpAddr, "failed to parse scrape", transactionID)
tracker.fatal(udpAddr, []byte("failed to parse scrape"), transactionID)
zap.L().Info("failed to parse clients scrape packet", zap.Binary("packet", data), zap.Error(err), zap.Any("remote", addrPort))
return
}

if len(scrape.InfoHashes) > maximumScrapeHashes {
tracker.sendError(udpAddr, "packet contains more than 74 hashes", scrape.TransactionID)
zap.L().Debug("client sent scrape with more than 74 hashes", zap.Int("hashes", len(scrape.InfoHashes)), zap.Any("scrape", scrape), zap.Any("remote", udpAddr))
tracker.fatal(udpAddr, []byte("exceeded 74 hashes"), scrape.TransactionID)
zap.L().Debug("client sent over sized scrape request (> 74 hashes)", zap.Int("hashes", len(scrape.InfoHashes)), zap.Any("scrape", scrape), zap.Any("remote", udpAddr))
return
}

Expand All @@ -36,7 +35,7 @@ func (tracker *Tracker) scrape(udpAddr *net.UDPAddr, addrPort netip.AddrPort, tr

for _, hash := range scrape.InfoHashes {
if len(hash) != 20 {
tracker.sendError(udpAddr, "hash "+utils.ByteToStringUnsafe(hash[0:7])+" is missized", scrape.TransactionID)
tracker.fatal(udpAddr, append([]byte("missized hash "), hash[0:7]...), scrape.TransactionID)
zap.L().Debug("client sent scrape with missized hash", zap.Any("hash", hash), zap.Any("scrape", scrape), zap.Any("remote", udpAddr))
return
}
Expand All @@ -52,7 +51,7 @@ func (tracker *Tracker) scrape(udpAddr *net.UDPAddr, addrPort netip.AddrPort, tr

marshalledResp, err := resp.Marshall()
if err != nil {
tracker.sendError(udpAddr, "failed to marshall scrape response", scrape.TransactionID)
tracker.fatal(udpAddr, []byte("failed to marshall scrape response"), scrape.TransactionID)
zap.L().Error("failed to marshall scrape response", zap.Error(err), zap.Any("scrape", scrape), zap.Any("remote", udpAddr))
return
}
Expand Down
4 changes: 2 additions & 2 deletions tracker/udp/udpprotocol/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package udpprotocol

type Action int32

func (action Action) IsInvalid() bool {
return action < 0 || action > 4
func (action Action) Valid() bool {
return action >= 0 && action <= 4
}

const (
Expand Down
16 changes: 7 additions & 9 deletions tracker/udp/udpprotocol/announce.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,9 @@ type AnnounceResponse struct {
Action Action
TransactionID int32
Interval int32
// TODO: rename to `Leeches`
Leechers int32
// TODO: rename to `Seeds`
Seeders int32
Peers []byte
Leeches int32
Seeds int32
Peers []byte
}

// Marshall encodes an AnnounceResp to a byte slice.
Expand All @@ -71,10 +69,10 @@ func (ar *AnnounceResponse) Marshall() ([]byte, error) {
if err := binary.Write(&buff, binary.BigEndian, ar.Interval); err != nil {
return nil, errors.Wrap(err, "failed to encode announce response iterval")
}
if err := binary.Write(&buff, binary.BigEndian, ar.Leechers); err != nil {
if err := binary.Write(&buff, binary.BigEndian, ar.Leeches); err != nil {
return nil, errors.Wrap(err, "failed to encode announce response leeches")
}
if err := binary.Write(&buff, binary.BigEndian, ar.Seeders); err != nil {
if err := binary.Write(&buff, binary.BigEndian, ar.Seeds); err != nil {
return nil, errors.Wrap(err, "failed to encode announce response seeders")
}
if err := binary.Write(&buff, binary.BigEndian, ar.Peers); err != nil {
Expand All @@ -99,10 +97,10 @@ func NewAnnounceResponse(data []byte) (*AnnounceResponse, error) {
if err := binary.Read(reader, binary.BigEndian, &announceResp.Interval); err != nil {
return nil, errors.Wrap(err, "failed to decode announce response iterval")
}
if err := binary.Read(reader, binary.BigEndian, &announceResp.Leechers); err != nil {
if err := binary.Read(reader, binary.BigEndian, &announceResp.Leeches); err != nil {
return nil, errors.Wrap(err, "failed to decode announce response leeches")
}
if err := binary.Read(reader, binary.BigEndian, &announceResp.Seeders); err != nil {
if err := binary.Read(reader, binary.BigEndian, &announceResp.Seeds); err != nil {
return nil, errors.Wrap(err, "failed to decode announce response seeders")
}
if err := binary.Read(reader, binary.BigEndian, &announceResp.Peers); err != nil {
Expand Down
Loading

0 comments on commit 001a0d5

Please sign in to comment.