commit | bd9a2886fbf3d8af26d2b88489af7f5fda7c1642 | [log] [tgz] |
---|---|---|
author | François-Simon Fauteux-Chapleau <francois-simon.fauteux-chapleau@savoirfairelinux.com> | Fri Aug 30 12:44:32 2024 -0400 |
committer | François-Simon Fauteux-Chapleau <francois-simon.fauteux-chapleau@savoirfairelinux.com> | Fri Aug 30 16:13:41 2024 -0400 |
tree | 38df23f41c389830cc4fb56f177892863d31ef81 | |
parent | 14d54f2d7360b12bf4c9bc5c9dc0abe1edc76d6b [diff] |
natpmp: fix out-of-order responses bug This patch fixes a few issues with the way libnatpmp was used in DHTNet. The two most important ones are the following: 1) Each call to sendnewportmapping is now followed by a call to readResponse. This is important because libnatpmp expects the response to each request to be read before another request is sent; skipping a request can cause the responses to later requests to be incorrect. 2) All requests are now sent from the Asio thread. This wasn't the case before, and as a result the responses to requests made from different threads would sometimes get mixed up (e.g. if thread 1 sends request A and thread 2 sends request B, then thread 1 could end up reading the response to request B). The other (minor) issues are: 3) The readResponse function would return the NATPMP_ERR_SOCKETERROR error code when the MAX_READ_RETRIES limit was hit instead of NATPMP_TRYAGAIN, which made this case look identical to a poll error in the logs. The function would also sleep unnecessarily after the last iteration when the limit was reached. 4) The sendMappingRequest function tried to make up to MAX_READ_RETRIES calls to readResponse when it detected that it had gotten a response of the wrong type, but this doesn't work because libnatpmp doesn't allow reading multiple responses in a row and will simply return a NATPMP_ERR_NOPENDINGREQ error for each call after the first one. GitLab: #33 Change-Id: If8f0824eef1de601411c9e70bd33df46230a24f8
DHTNet is a C++17 library designed to serve as a network overlay that provides an IP network abstraction. Its main objective is to establish secure peer-to-peer connections using public-key authentication.
Dhtnet allows you to connect with a device simply by knowing its public key and efficiently manages peer discovery and connectivity establishment, including NAT traversal.
Connection Management: DHTNet simplifies the establishment and management of connections to peers, streamlining the communication process.
Multiplexed Sockets: It provides multiplexed sockets that allow multiple channels for data transmission, optimizing network resources.
UPnP Integration: DHTNet seamlessly integrates with UPnP, enabling automatic port mapping and enhanced network connectivity.
Server TURN Support: DHTNet includes support for server TURN, used as a fallback for connections if the NAT block all possible connections.
For detailed information on using DHTNet, consult our documentation:
Get started with DHTNet by building and installing the library:
#include "connectionmanager.h" #include <opendht/log.h> #include <opendht/utils.h> #include <opendht/thread_pool.h> #include <fmt/core.h> int main() { // Create identities for CA (Certificate Authority), client, and server auto ca = dht::crypto::generateIdentity("ca"); auto id_client = dht::crypto::generateIdentity("client", ca); auto id_server = dht::crypto::generateIdentity("server", ca); // Create client and server ConnectionManager instances auto client = std::make_shared<ConnectionManager>(id_client); auto server = std::make_shared<ConnectionManager>(id_server); // Launch dht nodes client->onDhtConnected(id_client.first->getPublicKey()); server->onDhtConnected(id_server.first->getPublicKey()); // Connect the client to the server's device via a channel named "channelName" client->connectDevice(id_server.second->getId(), "channelName", [&](std::shared_ptr<dhtnet::ChannelSocket> socket, const dht::InfoHash&) { if (socket) { // Send a message (example: "Hello") to the server std::error_code ec; std::string data = "hello"; socket->write(data.data(), data.size(), ec); } }); // Define a callback function for when the server's connection is ready server->onConnectionReady([&](const DeviceId& device, const std::string& name, std::shared_ptr<ChannelSocket> socket) { if (socket) { // Server: Connection succeeded fmt::print("Server: Connection succeeded\n"); // Set a callback for receiving messages socket->setOnRecv([&](const uint8_t* data, size_t size) { fmt::print("Message received: {}\n", std::string_view(data, data + size)); // Print received message }); } else { // Server: Connection failed fmt::print("Server: Connection failed\n"); } }); return 0; }
DHTNet depends on the following libraries:
In extras/packaging
, you will find a build_packages.sh
script which will build packages for supported plateform. You must provide as argument the OS for which you want to build. You can't specify the plateform (arm64, x86, ...) as you can compile only for the same plateform as the one you are running on.
Usage:
extras/packaging/build_packages.sh -a # -a or --all will build all plateform which are known to be supported extras/packaging/build_packages.sh -u # -u or --ubuntu will build for all supported versions of Ubuntu extras/packaging/build_packages.sh -u22 -d11 # -u22 will build for ubuntu 22.04 and -d11 will build for Debian 11
dnc is a command-line program that provides network connectivity between peers in a Distributed Hash Table (DHT) network. It allows peers to establish connections with other peers and create a TCP socket on a remote devices, similar to the behavior of the traditional nc utility.
dsh is a Distributed Shell command-line program that enables peers to establish connections with other peers in a Distributed Hash Table (DHT) network and execute a binary on the remote target.
dvpn is a VPN tool built on the foundation of the DHTNet library. dvpn supports both server and client modes, offering flexibility in deployment sceanrios.
dhtnet-crtmgr is a command-line tool designed to manage certificates for the DHTNet network. It provides functionality for generating and signing certificates.
If the client and server are on the same machine, they should use different certificates for authentication, so make sure to specify different identity file paths for the client and server. This ensures that they use separate certificates.
Report issues on Gitlab: https://git.jami.net/savoirfairelinux/dhtnet/-/issues