savoirfairelinux / opendht

OpenDHT: a C++17 Distributed Hash Table implementation
GNU General Public License v3.0
1.02k stars 172 forks source link

Bootsrap is not working when opendht compiled for android #684

Open sl4v3k opened 10 months ago

sl4v3k commented 10 months ago

Hi, just tryed to build "Hello World" application base on libopendht.a taken from android build. And i realized that node->bootstrap("bootstap.jami.net", "4222"); is doing anything. What i found that bootstrap call chain is finally calling addBootstrap from securedht.h:

void addBootstrap(const std::string& host, const std::string& service) override {
    logger_->d("DhtRunner::bootstrap from securedht %s %s", host, service); **<----- this is the last log i see**
    dht_->addBootstrap(host, service);
}

and this is the last log string in logcat. Log put inside dht_->addBootstrap(host, service); is not called:

located in dht.h void addBootstrap(const std::string& host, const std::string& service) override { logger->d("dht->addBootstrap %s %s", host, service); <------ this is not going to logcat bootstrap_nodes.emplace_back(host, service); startBootstrap(); }

means dht_->addBootstrap(host, service); is calling wrong function.

More, if i compile this on intel x64 all works. Looks like android clang is breaking something? override is not working?

sl4v3k commented 10 months ago

Look, i added log in to addBootstrap dht_interface.h and now log is called

lOC 83 in dhtinterface.h virtual void addBootstrap(const std::string& /host/, const std::string& /service/) {logger->d("dht_->addBootstrap interface");};

Logcat out: com.dht.k0der I DhtRunner::bootstrap bootstrap.jami.net 4222 com.dht.k0der I DhtRunner::bootstrap from securedht bootstrap.jami.net 4222 com.dht.k0der I dht_->addBootstrap interface

means clang for some reason is using functions from dht_inteface.h instead of dht.h

sl4v3k commented 10 months ago

This migt be also reason that jami android app stops communicating after some time of sleep even if service is runnig. I made many tests with Push with noPush and service running. And result the same, after some time app is in background just stops cummunicating. In log i just see that ICE is not able to find connection.

aberaud commented 10 months ago

Hi,

From the behaviour you encountered, you might be using the DHT Proxy client ?

In that case, dht.cpp and the bootstrap option are not used. dht_proxy_client is used instead.

However, to be able to use push notifications you need to setup a push notification server configured with a push service working on your device. On Android that's typically a FCM/GCM API account, which would works with gorush and the DHT proxy server.

sl4v3k commented 10 months ago

Yes You are right i am using DhtProxy client mode, yes make sense local bootstrap is not needed.

I started investigation becuse of android app is loosing connectivity when going to background for some time even with service running and all push enabled.

sl4v3k commented 10 months ago

Still simple HW app is not connecting to dht nework, could You check below logs and say what could be possible reason.

com.dht.k0der                        I  [runner 0x7bbb12b020] state changed to Running
com.dht.k0der                        I  [proxy:client] start proxy with dhtproxy.jami.net:80
com.dht.k0der                        I  [proxy:client] starting io_context
com.dht.k0der                        I  [proxy:client] [connectivity] get status
com.dht.k0der                        I  [proxy:client] [info] requesting proxy server node information
com.dht.k0der                        I  [proxy:client] [status] sending request
com.dht.k0der                        I  [proxy:client] [status] query ipv4 info
com.dht.k0der                        I  [proxy:client] [status] query ipv6 info
com.dht.k0der                        I  [http:request:1] connect begin: 51.91.75.152:80 
com.dht.k0der                        I  [connection:1] start http session
com.dht.k0der                        E  [http:request:2] connect: no endpoints provided
com.dht.k0der                        E  [http:request:2] end with error: Transport endpoint is not connected
com.dht.k0der                        E  [proxy:client] [status] ipv6 failed with code=0
com.dht.k0der                        E  [proxy:client] [info] request failed for ipv6
com.dht.k0der                        I  [http:request:1] done with status code 0
com.dht.k0der                        E  [proxy:client] [status] ipv4 failed with code=0
com.dht.k0der                        E  [proxy:client] [info] request failed for ipv4

node->put always fails

node->put("aaaa", value, [value](bool ok) {
            __android_log_print(ANDROID_LOG_INFO, "result -> ", ok ? "success" : "failure");
        });

node->getNodeInfo gives node_id always 0

com.dht.k0der                        I  OpenDHT node 0000000000000000000000000000000000000000
com.dht.k0der                        I  Public key ID c3925b7fe014d3730f41ed882a6e5c27fa8337ea

The code and config of simple app:

main {
        in_port_t port {0};
        node = std::make_shared<DhtRunner>();
        auto dhtConf = getDhtConfig();
        node->run(port, dhtConf.first, std::move(dhtConf.second));
        node->bootstrap("bootstrap.jami.net", "4222"); <--this is not needed if Proxy used??
        while (runner.wait());
}
std::pair<dht::DhtRunner::Config, dht::DhtRunner::Context>
getDhtConfig()
{
    auto node_ca = std::make_unique<dht::crypto::Identity>(dht::crypto::generateEcIdentity("DHT Node CA"));
    auto id = dht::crypto::generateIdentity("DHT Node", *node_ca);

    dht::DhtRunner::Config config {};
    config.dht_config.node_config.network = 0;
    config.dht_config.node_config.maintain_storage = false;
//        config.dht_config.node_config.persist_path = params.persist_path;
//        config.dht_config.node_config.public_stable = params.public_stable;
    config.dht_config.id = id;
    config.dht_config.cert_cache_all = static_cast<bool>(id.first);
    config.threaded = true;
    config.proxy_server = "dhtproxy.jami.net:80";
    config.push_node_id = "dhtnode";
    config.push_token = id.second->getPublicKey().getId().toString();
    config.peer_discovery = false;
    config.peer_publish = false;

    dht::DhtRunner::Context context {};
    context.logger = getLogger();

    return {std::move(config), std::move(context)};
}
aberaud commented 10 months ago

From the logs, it looks like network requests to the proxy server fail (for both ipv4 and ipv6), which is odd. Was the log captured when the app was in the background ?

Note that to work with push notifications, unfortunately you would need to have a FCM API token configured with the Android app and provided as the "push_token"

sl4v3k commented 10 months ago

Above issue is solved, on the device i was initially testing HW app, selinux was blocking network connections. After moving HW app to another device all works. HW app means dhtnode like app with listen to specific value. So just opendht layer running with dht proxy option, no push, seems to be super stable, after almost 24 hours on the phone works fine, sending and receiving data on listen handler.

sl4v3k commented 10 months ago

but all tests done on jami android app with different configurations:

and result same after some time of phone is left no touched jami app stops receiving and sending messages

sl4v3k commented 10 months ago

in the logs i see issue related to ICE, mainly: "All ICE checklists failed" (PJNATH_EICEFAILED). I can get detialed logs if You would like to check it.