You can’t query IP by jami ID or query jami ID by DHT node ID. Jami only sends IP ( put(key, data) ) in encrypted form when devices need ICE negotiation, and Jami only accepts ICE request from contacts. You can read the source code of jami-daemon.
for (const auto& addr : ice->getLocalCandidates(1)) {
icemsg << addr << "\n";
JAMI_DBG() << "Added local ICE candidate " << addr;
}
// Prepare connection request as a DHT message
PeerConnectionRequest val;
val.id = vid; /* Random id for the message unicity */
val.ice_msg = icemsg.str();
val.connType = connType;
auto value = std::make_shared<dht::Value>(std::move(val));
value->user_type = "peer_request";
// Send connection request through DHT
JAMI_DBG() << "Request connection to " << deviceId;
dht()->putEncrypted(dht::InfoHash::get(PeerConnectionRequest::key_prefix
+ devicePk->getId().toString()),
devicePk,
value,
[deviceId](bool ok) {
JAMI_DEBUG("Sent connection request to {:s}. Put encrypted {:s}",
deviceId.toString(),
(ok ? "ok" : "failed"));
});
for (const auto& addr : ice.getLocalCandidates(1)) {
icemsg << addr << "\n";
}
// Send PeerConnection response
PeerConnectionRequest val;
val.id = id;
val.ice_msg = icemsg.str();
val.isAnswer = true;
auto value = std::make_shared<dht::Value>(std::move(val));
value->user_type = "peer_request";
JAMI_DBG() << "[CNX] connection accepted, DHT reply to " << from->getLongId();
dht()->putEncrypted(dht::InfoHash::get(PeerConnectionRequest::key_prefix
+ from->getId().toString()),
from,
value,
[from](bool ok) {
JAMI_DEBUG("Answer to connection request from {:s}. Put encrypted {:s}",
from->getLongId().toString(),
(ok ? "ok" : "failed"));
});
How do these ISPs block bootstrap? DNS tampering or IP filtering?
For android client built with UnifiedPush support, you can run your own UnifiedPush instance, then use it with default DHT proxy, or also run DHT proxy.
For iOS client and android client built with FCM support, these two services (APNs and FCM) can’t be self-hosted.