-- Leo's gemini proxy

-- Connecting to gemini.clehaxze.tw:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Announcing GNUnet++, experimental high level GNUnet C++ wrapper


home


Today I'm announcing GNUnet++. An experimentable yet sensable C++ wrapper for GNUnet services. You can find my introduction to GNUnet in my older articles [1][2]. TL;DR GNUnet is GNU's version of IPFS and libp2p. It has some pros and cons over `libp2p`. Like built-in trafic covering, firewall bypass, etc.. But has (much) lower adoption rate and stablity. In any case, it's a fun project and I see potential in it. The pure C API is a pain point I can help fix - with GNUnet++.


[1]: Thinking About Pratical Web3.0 and GNUNet as Infrastructure

[2]: GNUnet File Sharing Tutorial and an Alternative to IPFS


GNUnet++


GNUnet++ aims to provide a RAII-style API for GNUnet. At least make managing GNUnet object lifetime not as painful. And high level function calls for commonly used functions. Currently basic capablitites of the following subsystems are wrapped:


DHT

File Share

Identity

Crypto

GNS

Scheduler


And more is to come. I shall demonstrate what GNUnet++ can do with a simple example. Let's say we want to query the GNS system for the IP address of gnunet.org. We can do this with the following code.


auto gns = std::make_shared<gnunetpp::GNS>(cfg);
gns->lookup("gnunet.org", [](auto result) {
    if(result.empty())
        std::cout << "No result found" << std::endl;
    else {
        for(auto& record : result)
            std::cout << "Found record: " << record << std::endl;
    }
});

Likewise, to publish file to GNUnet's file share system, we can do this:


gnunetpp::FS::publish(cfg, "/path/to/the/file.txt", {}
    , [](auto status, const std::string& uri, const std::string& namespace_uri) {
    if(status == gnunetpp::FS::PublishResult::Success)
        std::cout << "Published " << filename << " at " << uri << std::endl;
    else
        std::cout << "Publish failed" << std::endl;
});

Contrast to what GNUnet's official thousand line utility to publich files. I think GNUnet++ is a lot more reasonable and easier to use. Sure, there's lots of functions missing. I'm adding them as I need. And more importantly, contributions are always welcome.


Source code of gnunet-publish, GNUnet's official utility to publish files.


New CLI Tools


GNUnet++ replements a subset of GNUnet's CLI tools as examples of how to use GNUnet++. These tools are better organized with subcommands and with better help messages. It shoes what's required parameters and the default of optional parameters. For example, the help message of `gnunetpp-dht put` is:


❯ ./examples/gnunetpp-dht put --help
Put a key-value pair into the GNUnet DHT
Usage: ./examples/gnunetpp-dht put [OPTIONS]

Options:
  -h,--help                   Print this help message and exit
  -k,--key TEXT REQUIRED      Key of the key value pair
  -v,--value TEXT REQUIRED    Value of the key value pair
  -e,--expiration UINT [3600]
                              Expiration time for the value in seconds
  -r,--replication UINT [5]   Estimation of how many nearest peer this request reaches (not data replication count)

While the oginal `gnunet-dht-put` is more cryptic:


❯ gnunet-dht-put -h
gnunet-dht-put
Issue a PUT request to the GNUnet DHT insert DATA under KEY.
Arguments mandatory for long options are also mandatory for short options.
  -c, --config=FILENAME      use configuration file FILENAME
  -d, --data=DATA            the data to insert under the key
  -e, --expiration=EXPIRATIONhow long to store this entry in the dht (in
                               seconds)
  -h, --help                 print this help
  -k, --key=KEY              the query key
  -L, --log=LOGLEVEL         configure logging to use LOGLEVEL
  -l, --logfile=FILENAME     configure logging to write logs to FILENAME
  -R, --record               use DHT's record route option
  -r, --replication=LEVEL    how many replicas to create
  -t, --type=TYPE            the type to insert data as
  -V, --verbose              be verbose
  -v, --version              print the version number
  -x, --demultiplex          use DHT's demultiplex everywhere option

Limitations


Like I said above, GNUnet++ is a high level library. This means that it's not as flexible as the original GNUnet API. For example, GNUnet++ doesn't expose the routing information along with the DHT query result. However, I think this is a reasonable tradeoff as that information is rarely used. And it's not hard to add it back if you really need it. Also, GNunet++ is not as "efficient" as using the raw C API as it has to do some extra work to manage object lifetime. Again, I think this is a reasonable tradeoff for very obvious reasons.


Near future work


I decide to announce GNUnet++ at it's current form for a few reasons. 1. The callback hell is getting out of hands and I'll be turning them into coroutines. But that will take some serious problem solving for lifetime management. 2. It's good enough to be slightly useful and I want to get some feedback if anyone happens to find it.


The main thing missing now is CADET and namestore support. Looking at their APIs. I rather implement them after coroutines are done. I'm also debating myself if I should support the chat and auction subsystems. They are such high level that I'm not sure if anyone would use them programmatically.


Pratical Use


I haven't come up with a good pratical use case for GNUnet++ yet (at least something I'd spend time to build). Decentralized p2p is very attractive. But is also hard. In the sense that the traditional client-server archicture is easy to build, low latency and low noise. Decentralizing means you gave up all that and have to deal with a lot of new problems. Like easy DoS attacks, unreliable network, and so on.


I'm working hard on it though. I truely believe in the power of p2p networks.


===


Find the source code at the following link.

GNUnet++ on GitHub

-- Response ended

-- Page fetched on Fri Jun 14 03:14:10 2024