atlet99/dtorrent_tracker_v2

[FEATURE] - Improve UDP response error handling;

オープン

#16 opened on 2025/11/03

 (0 件のコメント) (0 件のリアクション) (0 人の担当者)Dart (0 件のフォーク)auto 404
enhancementhelp wanted

Repository metrics

Stars
 (0 個のスター)
PR merge metrics
 (30d に merged PR はありません)

説明

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

コントリビューターガイド