atlet99/dtorrent_tracker_v2

[FEATURE] - Improve UDP response error handling;

Aperta

#16 aperta il 3 nov 2025

 (0 commenti) (0 reazioni) (0 assegnatari)Dart (0 fork)auto 404
enhancementhelp wanted

Metriche repository

Star
 (0 stelle)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

Description

The UDP tracker only checks for a minimum data length of 8 bytes, but different UDP tracker actions require different minimum response lengths. This can lead to incomplete parsing or incorrect error handling.

Location

File: lib/src/tracker/udp_tracker_base.dart
Line: 116

Current Code

var datagram = _socket?.receive();
if (datagram == null || datagram.data.length < 8) {  // ❌ Only checks minimum 8 bytes
  close();
  completer.completeError('Wrong datas');
  return;
}

Expected Behavior

Different UDP tracker actions require different minimum response lengths according to BEP 0015:

  1. Connect Response (Action 0): Minimum 16 bytes

    • 4 bytes: action
    • 4 bytes: transaction_id
    • 8 bytes: connection_id
  2. Announce Response (Action 1): Minimum 20 bytes

    • 4 bytes: action
    • 4 bytes: transaction_id
    • 4 bytes: interval
    • 4 bytes: leechers (incomplete)
    • 4 bytes: seeders (complete)
    • Variable: peers (IPv4: 6 bytes each, IPv6: 18 bytes each)
  3. Scrape Response (Action 2): Minimum 8 bytes + (12 bytes × number of info_hashes)

    • 4 bytes: action
    • 4 bytes: transaction_id
    • 12 bytes per info_hash: complete, downloaded, incomplete
  4. Error Response (Action 3): Minimum 8 bytes

    • 4 bytes: action
    • 4 bytes: transaction_id
    • Variable: error message (string)

Proposed Implementation

Add action-specific validation in _processAnnounceResponseData:

void _processAnnounceResponseData(Uint8List data, Map options,
    List<CompactAddress> address, Completer completer) async {
  if (isClosed) {
    if (!completer.isCompleted) completer.completeError('Tracker Closed');
    return;
  }
  
  var view = ByteData.view(data.buffer);
  var tid = view.getUint32(4);
  
  if (tid == transcationIdNum) {
    var action = view.getUint32(0);
    
    // Validate minimum length based on action
    if (!_validateResponseLength(data, action)) {
      if (!completer.isCompleted) {
        completer.completeError('Invalid response length for action $action');
      }
      close();
      return;
    }
    
    // ... rest of processing ...
  }
}

bool _validateResponseLength(Uint8List data, int action) {
  switch (action) {
    case 0: // Connect
      return data.length >= 16;
    case 1: // Announce
      return data.length >= 20;  // Minimum without peers
    case 2: // Scrape
      // For scrape, need to know number of info_hashes
      // This should be checked in UDPScrape class
      return data.length >= 8;
    case 3: // Error
      return data.length >= 8;
    default:
      return false;
  }
}

For Scrape, validate in udp_scrape.dart:

@override
dynamic processResponseData(
    Uint8List data, int action, Iterable<CompactAddress> addresses) {
  if (action != 2) {
    throw Exception('The Action in the returned data does not match.');
  }
  
  // Validate minimum length
  var minLength = 8 + (infoHashSet.length * 12);
  if (data.length < minLength) {
    throw Exception(
      'Invalid scrape response length: expected at least $minLength bytes, '
      'got ${data.length} bytes',
    );
  }
  
  // ... rest of processing ...
}

Improve error messages with expected vs actual length:

if (datagram == null || datagram.data.length < 8) {
  close();
  var errorMsg = datagram == null
      ? 'No data received'
      : 'Invalid response length: expected at least 8 bytes, got ${datagram.data.length}';
  completer.completeError(errorMsg);
  return;
}

Impact

  • Severity: Medium (Quality Improvement)
  • Affected: All UDP tracker operations
  • Benefits:
    • Better error detection for malformed responses
    • Clearer error messages with expected vs actual lengths
    • Prevention of incomplete parsing
    • Better debugging information

Additional Context

Proper length validation helps:

  • Detect malformed or truncated responses
  • Prevent IndexOutOfBounds exceptions
  • Identify network issues
  • Debug tracker communication problems

Related Standards

Guida contributor