dialBack method

  1. @override
Future<void> dialBack(
  1. PeerId peer
)
override

Requests a peer providing AutoNAT services to test dial back and report the address on a successful connection.

Implementation

@override
Future<void> dialBack(PeerId peer) async {
  P2PStream? stream;
  try {
    final ctx = Context(timeout: _requestTimeout); // Use the configured request timeout
    stream = await _host.newStream(peer, [autoNATV1Proto], ctx);

    await stream.scope().setService(serviceName);
    await stream.scope().reserveMemory(_autoNATClientMaxMessageScopeReservation, ReservationPriority.always);

    // Determine the effective deadline: earlier of context timeout and stream I/O timeout
    final now = DateTime.now();
    final contextAbsoluteDeadline = now.add(_requestTimeout);
    final streamIoAbsoluteDeadline = now.add(streamTimeout); // streamTimeout is the 60s constant

    final effectiveDeadline = contextAbsoluteDeadline.isBefore(streamIoAbsoluteDeadline)
        ? contextAbsoluteDeadline
        : streamIoAbsoluteDeadline;

    await stream.setDeadline(effectiveDeadline);

    final localPeerInfo = AddrInfo(_host.id, _addrFunc()); // Used _host.id
    final req = _newDialMessage(localPeerInfo);

    await writeDelimited(stream, req); // Pass stream directly, and await

    // Read the response using the delimited reader
    final res = await readDelimited(stream, pb.Message.fromBuffer); // Pass stream directly

    if (res.type != pb.Message_MessageType.DIAL_RESPONSE) {
      throw Exception('Unexpected response: ${res.type}');
    }

    final status = res.dialResponse.status;
    _metricsTracer?.receivedDialResponse(status);

    switch (status) {
      case pb.Message_ResponseStatus.OK:
        return;
      default:
        throw AutoNATError(status, res.dialResponse.statusText);
    }
  } catch (e) {
    // In Go, s.Reset() is called in several error paths.
    // In Dart, closing the stream or letting it be garbage collected is typical.
    // If specific reset logic is needed, it would be part of P2PStream.
    rethrow;
  } finally {
    if (stream != null) {
      stream.scope().releaseMemory(_autoNATClientMaxMessageScopeReservation);
      await stream.close();
    }
  }
}