Skip to content

Enable dht relay for phone#328

Open
defnax wants to merge 1 commit into
RetroShare:masterfrom
defnax:enable-dht-relay-for-phone
Open

Enable dht relay for phone#328
defnax wants to merge 1 commit into
RetroShare:masterfrom
defnax:enable-dht-relay-for-phone

Conversation

@defnax

@defnax defnax commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

2. The Root Cause: Why DHT is "Not Working"

On a mobile client (such as Android/iOS), the device is almost always behind CGNAT (Carrier-Grade NAT) or restrictive firewalls. This means:

  1. No Direct UDP Inbound Connections: Other DHT nodes cannot establish direct inbound UDP connections to your device.
  2. Relays are Required: In NAT environments, a DHT client must use DHT relay servers (nodes with public IPs that act as intermediates) to bootstrap and establish connectivity.
  3. Relays Ignored: Because BITDHT_MODE_RELAYSERVERS_IGNORED (4096) is active, your client drops and refuses to contact any DHT relay servers.

As a result, even though bdboot.txt is loaded without issues, all direct UDP pings/queries sent to those bootstrap nodes time out because inbound replies are blocked by your network's NAT/firewall. Without relay support, the DHT is unable to bootstrap and remains offline.


3. The setRelayMode(01) Printing Bug in RetroShare

If you look at the definition of the custom stream insertion operator for enum flags in [libretroshare/src/retroshare/rsflags.h]

template<typename EFT>
typename std::enable_if<Rs__BitFlagsOps<EFT>::enabled, std::ostream>::type&
operator <<(std::ostream& stream, EFT flags)
{
	using u_t = typename std::underlying_type<EFT>::type;
	return stream << std::bitset<sizeof(u_t)>(static_cast<u_t>(flags));
}

The bug lies in std::bitset<sizeof(u_t)>:

  • u_t is uint16_t for RsDhtRelayMode.
  • sizeof(uint16_t) evaluates to 2 (the size in bytes, not bits).
  • Because of this, it prints std::bitset<2>, displaying only the lowest 2 bits of the flag set.
  • RsDhtRelayMode::OFF is 0x0010 (bit 4) and RsDhtRelayMode::ENABLED is 0x0001 (bit 0). Their combined value is 0x0011 (17 in decimal).
  • Truncating 0x0011 to 2 bits yields 01, hiding the fact that OFF (bit 4) was also enabled.

1. Forcing DHT Relays ON for Mobile

In p3bitdht_relay.cc
we added a preprocessor directive inside setRelayMode to override and force the relay mode to ON when compiling for Android (ANDROID) or iOS/macOS (APPLE):

cpp

int p3BitDht::setRelayMode(RsDhtRelayMode mode)
{
#if defined(__ANDROID__) || defined(__APPLE__)
	// Force relay mode to ON on mobile platforms since CGNAT / firewalls prevent direct incoming UDP connections
	mode = (mode & ~RsDhtRelayMode::MASK) | RsDhtRelayMode::ON;
#endif
	std::cerr << "p3BitDht::setRelayMode(" << mode << ")";
	std::cerr << std::endl;

This will bypass any OFF defaults or saved configuration presets, forcing the mobile client to use DHT relays so that it can bootstrap successfully behind NAT.

2. Fixing the stream output printing bug

In
rsflags.h we corrected the std::bitset size calculation so it multiplies bytes by 8 to convert them to bits, fixing the log formatting:

-	return stream << std::bitset<sizeof(u_t)>(static_cast<u_t>(flags));
+	return stream << std::bitset<sizeof(u_t) * 8>(static_cast<u_t>(flags));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant