Build GNUnet applications from the well-typed concurrent comfort of your Haskell.
build: nix: shell: Add shell-ide, shell with ghcide
fix: CADETStream: c'GNUNET_MQ_send from single thread
Revert "feat: CADET: Clean up in withCreateChannel"


browse  log 



You can also use your local clone with git send-email.


builds.sr.ht status Hydra link

Build GNUnet applications from the well-typed concurrent comfort of your Haskell.

This project is organized in three layers:

network-transport-cadet (not there yet) | plug-in n-t implementation                     | Network.Transport.*
gnunet-hs                               | user-friendly library                          | Network.GNUnet.*
bindings-gnunet                         | autogenerated bindings (in c2hsc/bindings-DSL) | Bindings.GNUnet.*
GNUnet                                  | upstream                                       | gnunet_*_service.h

#Getting started

To see how to use the library, the primary destination is ./examples. Also see tests at ./gnunet-hs/test and a netcat at ./cadetcat.

Here's an impression:

conf <- G.setup "sampleapp" "gnunet.conf" G.NoLog
flip runReaderT conf $ G.run $
  CADET.withCadet $ \c ->
    CADET.withConnection c "0E497SHHFSR09123Z8BZYP19DAMBS5K8HX9PQWV8Q8NQRH9B0VN0" (G.hash "myPort") $
      CADET.send "ola!"

Note we only test on Linux at the moment.


To work on the library itself, here's how you check things work:

cd gnunet-hs
cabal new-run gnunet-hs:test

IDE integration is available at shell-ide.nix.

#Binding something new

  1. Decide what from GNUnet's API at gnunet/src/include/*.h you want

  2. Hook up bindings:

    • Run c2hsc on the header (details in ./bindings-gnunet), add artifact to cabal as exposed module
    • Import what's missing (look at neighbouring bindings for examples)
    • Link with the appropriate lib (cabal pkgconfig-depends)
  3. Build a nicer interface, some suggestions:

    • Grep through gnunet to see how it's used
    • Rule of thumb: user shouldn't have to import anything from bindings-gnunet unless gnunet-hs is incomplete
    • Provide withX
    • If C API is async, consider making it sync and using it with async.
    • Write a test, at the least to showcase the API

#Hacking the scheduler

One complex part of the project is integration between GHC RTS and GNUnet's scheduler, at Network.GNUnet.SchedulerIntegration. We basically implement GNUNET_SCHEDULER_Driver in terms of GHC.Event. It mostly works at the moment. If you'd like to help make it work 💯:

  • Threads are labeled and events annotated so as to make ghc-events-analyze useful
  • If crashes prevent you from getting an eventlog, +RTS -v streams eventlog to stderr
  • gdb is your friend
  • phoityne-vscode might or might not be useful
  • TBD profiling for leaks, randomized testing

#Local GNUnet

By default, GNUnet is supplied via nix. If you wish to have incremental local builds of GNUnet, peruse contrib/localgnunet.sh (consider invoking with direnv).