gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] 06/06: Merge branch 'master' of ssh://git.gnunet.org/gnunet


From: gnunet
Subject: [gnunet] 06/06: Merge branch 'master' of ssh://git.gnunet.org/gnunet
Date: Tue, 14 Nov 2023 17:59:19 +0100

This is an automated email from the git hooks/post-receive script.

thejackimonster pushed a commit to branch master
in repository gnunet.

commit b8672206edfb2047132311b9a3ab3a0138bdc422
Merge: 34587531b 8e8c3f1e1
Author: TheJackiMonster <thejackimonster@gmail.com>
AuthorDate: Tue Nov 14 17:51:34 2023 +0100

    Merge branch 'master' of ssh://git.gnunet.org/gnunet

 .gitignore                                         |     2 +-
 .gitmodules                                        |     8 +-
 Makefile.am                                        |     8 +-
 README                                             |     5 +-
 README.meson.md                                    |    43 +
 bootstrap                                          |     6 +-
 ci/Containerfile                                   |    43 +
 ci/ci.sh                                           |    30 +
 ci/jobs/0-build/build.sh                           |    10 +
 ci/jobs/0-build/job.sh                             |     6 +
 ci/jobs/2-deb-package/job.sh                       |    22 +
 ci/jobs/2-deb-package/version.sh                   |    12 +
 ci/jobs/3-deploy-package/config.ini                |     5 +
 ci/jobs/3-deploy-package/job.sh                    |    14 +
 configure.ac                                       |   338 +-
 contrib/Makefile.am                                |    42 +-
 contrib/ci/docker/Dockerfile                       |    32 -
 contrib/ci/docker/docker-entrypoint.sh             |     3 -
 contrib/conf/gnunet/meson.build                    |     6 +
 contrib/conf/meson.build                           |     1 +
 contrib/gana                                       |     2 +-
 contrib/gnunet_infrastructure/handbook_pull.sh     |    18 -
 contrib/handbook                                   |     1 +
 contrib/hellos/Makefile.am                         |     6 -
 ...SHMMZ1N1SQCE5TXF93ED6S6JY311K0QT86G9WJC68F6XVZ0 |   Bin 304 -> 0 bytes
 contrib/indent_pre-commit                          |    22 -
 contrib/meson.build                                |     6 +
 contrib/{ => packages/guix}/guix.README            |     0
 contrib/{ => packages/guix}/guix.scm               |     0
 contrib/scripts/meson.build                        |     4 +
 contrib/sphinx                                     |     1 -
 data/Makefile.am                                   |    25 +
 .../branding/logo/gnunet-logo-dark-only-text.svg   |     0
 .../branding/logo/gnunet-logo-dark-text.svg        |     0
 {contrib => data}/branding/logo/gnunet-logo.png    |   Bin
 .../logo/lynXified-amirouche-anonymous-v3.png      |   Bin
 .../branding/logo/lynXified-amirouche-v3.svg       |     0
 .../branding/logo/old-gnunet-logo-big.png          |   Bin
 .../branding/logo/old-gnunet-logo-color.png        |   Bin
 .../branding/logo/old-gnunet-logo-regrouped.svg    |     0
 .../branding/logo/old-gnunet-logo.pdf              |   Bin
 .../branding/logo/old-gnunet-logo.svg              |     0
 {contrib => data}/fcfsd/fcfsd-forbidden.html       |     0
 {contrib => data}/fcfsd/fcfsd-index.html           |     0
 {contrib => data}/fcfsd/fcfsd-notfound.html        |     0
 {contrib => data}/gns/def.tex                      |     0
 {contrib => data}/gns/gns-bcd-forbidden.html       |     0
 {contrib => data}/gns/gns-bcd-internal-error.html  |     0
 {contrib => data}/gns/gns-bcd-invalid-key.html     |     0
 {contrib => data}/gns/gns-bcd-not-found.html       |     0
 {contrib => data}/gns/gns-bcd-png.tex              |     0
 {contrib => data}/gns/gns-bcd-simple.html          |     0
 {contrib => data}/gns/gns-bcd-simple.tex           |     0
 {contrib => data}/gns/gns-bcd.html                 |     0
 {contrib => data}/gns/gns-bcd.tex                  |     0
 ...C2ME19SE00QCSF6X4405EQ2NPBG2XKRA1FEM6S3WRQ6N4H0 |   Bin 0 -> 248 bytes
 data/hellos/Makefile.am                            |     6 +
 data/hellos/meson.build                            |     2 +
 data/meson.build                                   |    22 +
 {contrib => data}/testing_hostkeys.ecc             |   Bin
 debian/control                                     |     5 +
 doc/handbook/meson.build                           |    42 +
 doc/man/meson.build                                |    66 +
 doc/meson.build                                    |     2 +
 meson-dist-script                                  |    35 +
 meson.build                                        |   451 +
 meson.options                                      |     6 +
 meson_options.txt                                  |     1 +
 pkgconfig/Makefile.am                              |    14 +-
 pkgconfig/gnunetats.pc.in                          |    12 -
 pkgconfig/gnunetenv.pc.in                          |    12 -
 pkgconfig/gnunetfragmentation.pc.in                |    12 -
 pkgconfig/gnunetjson.pc.in                         |    12 +
 pkgconfig/gnunetmysql.pc.in                        |    12 -
 pkgconfig/gnunetpeerinfo.pc.in                     |    12 -
 pkgconfig/gnunettestbed.pc.in                      |    12 -
 po/POTFILES.in                                     |  1105 +-
 po/de.po                                           | 12044 ++++++++---------
 po/es.po                                           | 13465 +++++++++----------
 po/fr.po                                           |  9783 ++++++--------
 po/it.po                                           |  9989 ++++++--------
 po/meson.build                                     |     1 +
 po/sr.po                                           | 13432 +++++++++---------
 po/sv.po                                           | 11984 ++++++++---------
 po/vi.po                                           | 12500 ++++++++---------
 po/zh_CN.po                                        | 11124 +++++++--------
 scripts/Makefile.am                                |    23 +
 {contrib => scripts}/get_version.sh                |     0
 scripts/meson.build                                |    12 +
 {contrib => scripts}/netjail/netjail_core.sh       |     0
 {contrib => scripts}/netjail/netjail_exec.sh       |     0
 {contrib => scripts}/netjail/netjail_start.sh      |     0
 {contrib => scripts}/netjail/netjail_stop.sh       |     0
 {contrib => scripts}/netjail/topo.sh               |     0
 scripts/testing-ng/block.sh                        |    11 +
 src/Makefile.am                                    |    96 +-
 src/README                                         |    13 +
 src/abd/Makefile.am                                |   106 -
 src/abd/abd.h                                      |   251 -
 src/abd/abd_api.c                                  |   564 -
 src/abd/abd_serialization.c                        |   516 -
 src/abd/delegate_misc.c                            |   279 -
 src/abd/gnunet-abd.c                               |  1108 --
 src/abd/gnunet-service-abd.c                       |  1778 ---
 src/abd/plugin_gnsrecord_abd.c                     |   357 -
 src/arm/.gitignore                                 |     7 -
 src/arm/Makefile.am                                |   102 -
 src/arm/gnunet-service-arm.c                       |  2227 ---
 src/ats-tool/.gitignore                            |     1 -
 src/ats-tool/Makefile.am                           |    19 -
 src/ats-tool/gnunet-ats.c                          |   992 --
 src/ats/.gitignore                                 |     6 -
 src/ats/Makefile.am                                |   102 -
 src/ats/ats.conf.in                                |    44 -
 src/ats/ats.h                                      |   492 -
 src/ats/ats_api_connectivity.c                     |   362 -
 src/ats/ats_api_performance.c                      |   946 --
 src/ats/ats_api_scanner.c                          |    65 -
 src/ats/ats_api_scheduling.c                       |   781 --
 src/ats/experiments/example.exp                    |   104 -
 src/ats/experiments/gnunet_ats_sim_default.conf    |    18 -
 src/ats/experiments/set_preference.exp             |    95 -
 src/ats/gnunet-ats-solver-eval.c                   |  3588 -----
 src/ats/gnunet-ats-solver-eval.h                   |   335 -
 src/ats/gnunet-service-ats.c                       |   538 -
 src/ats/gnunet-service-ats.h                       |    42 -
 src/ats/gnunet-service-ats_addresses.c             |   686 -
 src/ats/gnunet-service-ats_addresses.h             |   490 -
 src/ats/gnunet-service-ats_connectivity.c          |   222 -
 src/ats/gnunet-service-ats_connectivity.h          |    92 -
 src/ats/gnunet-service-ats_normalization.c         |   299 -
 src/ats/gnunet-service-ats_normalization.h         |    60 -
 src/ats/gnunet-service-ats_performance.c           |   282 -
 src/ats/gnunet-service-ats_performance.h           |    96 -
 src/ats/gnunet-service-ats_plugins.c               |   582 -
 src/ats/gnunet-service-ats_plugins.h               |   149 -
 src/ats/gnunet-service-ats_preferences.c           |   771 --
 src/ats/gnunet-service-ats_preferences.h           |    93 -
 src/ats/gnunet-service-ats_reservations.c          |   211 -
 src/ats/gnunet-service-ats_reservations.h          |    72 -
 src/ats/gnunet-service-ats_scheduling.c            |   195 -
 src/ats/gnunet-service-ats_scheduling.h            |   100 -
 src/ats/perf_ats_simplistic_bandwidth.conf         |    27 -
 src/ats/perf_ats_simplistic_delay.conf             |     8 -
 src/ats/perf_ats_solver.c                          |  1510 ---
 src/ats/perf_ats_solver.conf                       |    28 -
 src/ats/perf_ats_solver_proportional.conf          |     0
 src/ats/plugin_ats_proportional.c                  |  1243 --
 src/ats/test_ats_api.c                             |   296 -
 src/ats/test_ats_api.conf                          |    35 -
 src/ats/test_ats_api_delayed.conf                  |    36 -
 src/ats/test_ats_api_proportional.conf             |    24 -
 src/ats/test_ats_lib.c                             |  1107 --
 src/ats/test_ats_lib.h                             |   512 -
 src/ats/test_ats_reservation_api.c                 |   181 -
 src/ats/test_ats_solver_default.conf               |     2 -
 src/ats/test_ats_solver_delayed_proportional.conf  |    20 -
 src/ats/test_ats_solver_proportional.conf          |    19 -
 src/ats/test_delay                                 |    18 -
 src/auction/Makefile.am                            |    75 -
 src/block/Makefile.am                              |    59 -
 src/cadet/Makefile.am                              |   225 -
 src/cadet/gnunet-cadet-profiler.c                  |  1157 --
 src/cadet/gnunet-cadet.c                           |   851 --
 src/cadet/gnunet-service-cadet.c                   |  1373 --
 src/cadet/gnunet-service-cadet.h                   |   328 -
 src/cadet/gnunet-service-cadet_dht.c               |   331 -
 src/cadet/gnunet-service-cadet_hello.c             |   150 -
 src/cadet/gnunet-service-cadet_hello.h             |    80 -
 src/cadet/gnunet-service-cadet_peer.c              |  1560 ---
 src/cadet/gnunet-service-cadet_peer.h              |   433 -
 src/cadet/test_cadet.c                             |  1605 ---
 src/cadet/test_cadet_drop.conf                     |     4 -
 src/cadet/test_cadet_flow.c                        |   891 --
 src/cli/.gitignore                                 |     2 +
 src/cli/Makefile.am                                |    20 +
 src/cli/arm/.gitignore                             |     1 +
 src/cli/arm/Makefile.am                            |    45 +
 src/{ => cli}/arm/gnunet-arm.c                     |     0
 src/cli/arm/meson.build                            |     8 +
 src/cli/cadet/.gitignore                           |     1 +
 src/cli/cadet/Makefile.am                          |    26 +
 src/cli/cadet/gnunet-cadet.c                       |   851 ++
 src/cli/cadet/meson.build                          |    15 +
 src/cli/core/.gitignore                            |     1 +
 src/cli/core/Makefile.am                           |    24 +
 src/{ => cli}/core/gnunet-core.c                   |     0
 src/cli/core/meson.build                           |     6 +
 src/cli/datastore/.gitignore                       |     1 +
 src/cli/datastore/Makefile.am                      |    24 +
 src/{ => cli}/datastore/gnunet-datastore.c         |     0
 src/cli/datastore/meson.build                      |     9 +
 src/cli/dht/.gitignore                             |     5 +
 src/cli/dht/Makefile.am                            |    52 +
 src/{ => cli}/dht/gnunet-dht-get.c                 |     0
 src/{ => cli}/dht/gnunet-dht-hello.c               |     0
 src/{ => cli}/dht/gnunet-dht-monitor.c             |     0
 src/{ => cli}/dht/gnunet-dht-put.c                 |     0
 src/cli/dht/meson.build                            |    25 +
 src/cli/fs/.gitignore                              |     8 +
 src/cli/fs/Makefile.am                             |   107 +
 src/{ => cli}/fs/gnunet-auto-share.c               |     0
 src/{ => cli}/fs/gnunet-directory.c                |     0
 src/{ => cli}/fs/gnunet-download.c                 |     0
 src/{ => cli}/fs/gnunet-fs.c                       |     0
 src/cli/fs/gnunet-publish.c                        |  1009 ++
 src/{ => cli}/fs/gnunet-search.c                   |     0
 src/{ => cli}/fs/gnunet-unindex.c                  |     0
 src/cli/fs/meson.build                             |    51 +
 src/cli/gns/.gitignore                             |     2 +
 src/cli/gns/Makefile.am                            |   108 +
 src/{ => cli}/gns/gnunet-gns-proxy-ca.template     |     0
 src/{ => cli}/gns/gnunet-gns-proxy-setup-ca.in     |     0
 src/{ => cli}/gns/gnunet-gns.c                     |     0
 src/cli/gns/meson.build                            |    64 +
 src/{ => cli}/gns/openssl.cnf                      |     0
 src/{ => cli}/gns/test_dns2gns.conf                |     0
 src/{ => cli}/gns/test_dns2gns.sh                  |     0
 src/{ => cli}/gns/test_gns_at_lookup.sh            |     0
 src/{ => cli}/gns/test_gns_caa_lookup.sh           |     0
 src/{ => cli}/gns/test_gns_config_lookup.sh        |     0
 src/{ => cli}/gns/test_gns_defaults.conf           |     0
 src/{ => cli}/gns/test_gns_delegated_lookup.sh     |     0
 src/{ => cli}/gns/test_gns_dht_lookup.sh           |     0
 src/{ => cli}/gns/test_gns_gns2dns_cname_lookup.sh |     0
 src/{ => cli}/gns/test_gns_gns2dns_lookup.sh       |     0
 src/{ => cli}/gns/test_gns_gns2dns_zkey_lookup.sh  |     0
 src/{ => cli}/gns/test_gns_ipv6_lookup.sh          |     0
 src/{ => cli}/gns/test_gns_lookup.conf             |     0
 src/{ => cli}/gns/test_gns_lookup.sh               |     0
 src/{ => cli}/gns/test_gns_lookup_peer1.conf       |     0
 src/{ => cli}/gns/test_gns_lookup_peer2.conf       |     0
 .../gns/test_gns_multiple_record_lookup.sh         |     0
 src/{ => cli}/gns/test_gns_mx_lookup.sh            |     0
 src/{ => cli}/gns/test_gns_quickupdate.sh          |     0
 src/{ => cli}/gns/test_gns_redirect_lookup.sh      |     0
 src/{ => cli}/gns/test_gns_rel_expiration.sh       |     0
 src/{ => cli}/gns/test_gns_revocation.sh           |     0
 src/{ => cli}/gns/test_gns_simple_lookup.conf      |     0
 src/{ => cli}/gns/test_gns_soa_lookup.sh           |     0
 src/{ => cli}/gns/test_gns_txt_lookup.sh           |     0
 src/{ => cli}/gns/test_gns_zkey_lookup.sh          |     0
 src/{ => cli}/gns/test_gnunet_gns.sh.in            |     0
 ...25GVU8TTV0PBNNN8JVCPUEDFV1UHJJU884JD25V0T0.zkey |   Bin
 ...8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey |   Bin
 ...1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey |   Bin
 src/{ => cli}/gns/zonefiles/test_zonekey           |   Bin
 src/cli/identity/Makefile.am                       |    35 +
 src/cli/identity/gnunet-identity.c                 |   624 +
 src/cli/identity/meson.build                       |     9 +
 src/{ => cli}/identity/test_identity_messages.sh   |     0
 src/cli/meson.build                                |    19 +
 src/cli/messenger/.gitignore                       |     1 +
 src/cli/messenger/Makefile.am                      |    25 +
 src/cli/messenger/gnunet-messenger.c               |   409 +
 src/cli/messenger/meson.build                      |     9 +
 src/cli/namecache/.gitignore                       |     1 +
 src/cli/namecache/Makefile.am                      |    20 +
 src/cli/namecache/gnunet-namecache.c               |   245 +
 src/cli/namecache/meson.build                      |    10 +
 src/cli/namestore/.gitignore                       |     6 +
 src/cli/namestore/Makefile.am                      |    70 +
 src/{ => cli}/namestore/example_zonefile           |     0
 src/{ => cli}/namestore/gnunet-namestore-dbtool.c  |     0
 src/cli/namestore/gnunet-namestore-zonefile.c      |   763 ++
 src/cli/namestore/gnunet-namestore.c               |  2120 +++
 src/cli/namestore/gnunet-zoneimport.c              |  1872 +++
 src/cli/namestore/meson.build                      |    38 +
 src/{ => cli}/namestore/test_namestore_delete.sh   |     0
 src/{ => cli}/namestore/test_namestore_lookup.sh   |     0
 src/{ => cli}/namestore/test_namestore_put.sh      |     0
 .../namestore/test_namestore_put_multiple.sh       |     0
 .../namestore/test_namestore_put_stdin.sh          |     0
 .../namestore/test_namestore_zonefile_import.sh    |     0
 src/cli/nat-auto/.gitignore                        |     2 +
 src/cli/nat-auto/Makefile.am                       |    26 +
 src/{ => cli}/nat-auto/gnunet-nat-auto.c           |     0
 src/cli/nat-auto/gnunet-nat-server.c               |   403 +
 src/cli/nat-auto/meson.build                       |    14 +
 src/cli/nat/.gitignore                             |     1 +
 src/cli/nat/Makefile.am                            |    17 +
 src/{ => cli}/nat/gnunet-nat.c                     |     0
 src/cli/nat/meson.build                            |     7 +
 src/cli/nse/.gitignore                             |     1 +
 src/cli/nse/Makefile.am                            |    19 +
 src/{ => cli}/nse/gnunet-nse.c                     |     0
 src/cli/nse/meson.build                            |     7 +
 src/cli/reclaim/.gitignore                         |     2 +
 src/cli/reclaim/Makefile.am                        |    55 +
 src/cli/reclaim/gnunet-did.c                       |   646 +
 src/cli/reclaim/gnunet-reclaim.c                   |   928 ++
 src/cli/reclaim/meson.build                        |    22 +
 src/{ => cli}/reclaim/test_reclaim.sh              |     0
 src/{ => cli}/reclaim/test_reclaim_attribute.sh    |     0
 src/{ => cli}/reclaim/test_reclaim_consume.sh      |     0
 src/{ => cli}/reclaim/test_reclaim_issue.sh        |     0
 src/{ => cli}/reclaim/test_reclaim_revoke.sh       |     0
 src/cli/revocation/Makefile.am                     |    52 +
 src/cli/revocation/gnunet-revocation-tvg.c         |   230 +
 src/cli/revocation/gnunet-revocation.c             |   581 +
 src/cli/revocation/meson.build                     |    22 +
 .../revocation/test_local_revocation.py.in         |     0
 src/cli/statistics/.gitignore                      |     1 +
 src/cli/statistics/Makefile.am                     |    40 +
 src/cli/statistics/gnunet-statistics.c             |   889 ++
 src/cli/statistics/meson.build                     |     8 +
 src/cli/util/.gitignore                            |    10 +
 src/cli/util/Makefile.am                           |   108 +
 src/{ => cli}/util/crypto-test-vectors.json        |     0
 src/{ => cli}/util/gnunet-base32.c                 |     0
 src/{ => cli}/util/gnunet-config-diff.c            |     0
 src/{ => cli}/util/gnunet-config.c                 |     0
 src/cli/util/gnunet-crypto-tvg.c                   |  1608 +++
 src/{ => cli}/util/gnunet-ecc.c                    |     0
 src/{ => cli}/util/gnunet-qr.c                     |     0
 src/{ => cli}/util/gnunet-resolver.c               |     0
 src/{ => cli}/util/gnunet-scrypt.c                 |     0
 src/{ => cli}/util/gnunet-timeout.c                |     0
 src/{ => cli}/util/gnunet-uri.c                    |     0
 src/cli/util/meson.build                           |    62 +
 src/{ => cli}/util/test_crypto_vectors.sh          |     0
 src/cli/vpn/.gitignore                             |     1 +
 src/cli/vpn/Makefile.am                            |    22 +
 src/{ => cli}/vpn/gnunet-vpn.c                     |     0
 src/cli/vpn/meson.build                            |    13 +
 src/consensus/Makefile.am                          |   118 -
 src/consensus/gnunet-consensus-profiler.c          |   586 -
 src/contrib/Makefile.am                            |     3 +
 src/contrib/cli/Makefile.am                        |     2 +
 src/contrib/cli/meson.build                        |     1 +
 src/contrib/cli/template/.gitignore                |     1 +
 src/contrib/cli/template/Makefile.am               |    21 +
 src/{ => contrib/cli}/template/gnunet-template.c   |     0
 src/contrib/cli/template/meson.build               |     6 +
 src/contrib/meson.build                            |     5 +
 src/contrib/service/Makefile.am                    |    23 +
 src/{ => contrib/service}/abd/.gitignore           |     0
 src/contrib/service/abd/Makefile.am                |   106 +
 src/{ => contrib/service}/abd/abd.conf.in          |     0
 src/contrib/service/abd/abd.h                      |   251 +
 src/contrib/service/abd/abd_api.c                  |   563 +
 src/contrib/service/abd/abd_serialization.c        |   516 +
 src/{ => contrib/service}/abd/abd_serialization.h  |     0
 src/contrib/service/abd/delegate_misc.c            |   279 +
 src/{ => contrib/service}/abd/delegate_misc.h      |     0
 src/contrib/service/abd/gnunet-abd.c               |  1108 ++
 src/contrib/service/abd/gnunet-service-abd.c       |  1778 +++
 src/contrib/service/abd/plugin_gnsrecord_abd.c     |   357 +
 src/{ => contrib/service}/abd/test_abd_bi_and.sh   |     0
 src/{ => contrib/service}/abd/test_abd_bi_and2.sh  |     0
 src/{ => contrib/service}/abd/test_abd_bi_and3.sh  |     0
 src/{ => contrib/service}/abd/test_abd_bi_and4.sh  |     0
 src/{ => contrib/service}/abd/test_abd_bi_bw.sh    |     0
 .../service}/abd/test_abd_bi_bw_link.sh            |     0
 .../service}/abd/test_abd_bi_bw_link2.sh           |     0
 src/{ => contrib/service}/abd/test_abd_bi_fw.sh    |     0
 .../service}/abd/test_abd_defaults.conf            |     0
 src/{ => contrib/service}/abd/test_abd_issue.sh    |     0
 src/{ => contrib/service}/abd/test_abd_lookup.conf |     0
 src/{ => contrib/service}/abd/test_abd_own.sh      |     0
 src/{ => contrib/service}/abd/test_abd_verify.sh   |     0
 .../service}/abd/test_abd_verify_and.sh            |     0
 .../service}/abd/test_abd_verify_simple.sh         |     0
 src/{ => contrib/service}/auction/.gitignore       |     0
 src/contrib/service/auction/Makefile.am            |    75 +
 src/{ => contrib/service}/auction/auction.conf     |     0
 src/{ => contrib/service}/auction/auction.h        |     0
 .../service}/auction/gnunet-auction-create.c       |     0
 .../service}/auction/gnunet-auction-info.c         |     0
 .../service}/auction/gnunet-auction-join.c         |     0
 .../service}/auction/gnunet-service-auction.c      |     0
 .../service}/auction/test_auction_api.c            |     0
 .../service}/auction/test_auction_create.sh        |     0
 src/{ => contrib/service}/consensus/.gitignore     |     0
 src/contrib/service/consensus/Makefile.am          |   106 +
 .../service}/consensus/consensus-simulation.py.in  |     0
 .../service}/consensus/consensus.conf.in           |     0
 src/{ => contrib/service}/consensus/consensus.h    |     0
 .../service}/consensus/consensus_api.c             |     0
 .../service}/consensus/consensus_protocol.h        |     0
 .../service}/consensus/gnunet-service-consensus.c  |     0
 src/contrib/service/consensus/meson.build          |    66 +
 .../service}/consensus/plugin_block_consensus.c    |     0
 .../service}/consensus/test_consensus.conf         |     0
 .../service}/consensus/test_consensus_api.c        |     0
 src/{ => contrib/service}/conversation/.gitignore  |     0
 src/contrib/service/conversation/Makefile.am       |   263 +
 .../service}/conversation/build_gst_test.sh        |     0
 .../service}/conversation/conversation.conf.in     |     0
 .../service}/conversation/conversation.h           |     0
 .../service/conversation/conversation_api.c        |   897 ++
 .../service/conversation/conversation_api_call.c   |   749 ++
 .../service}/conversation/displaydot.sh            |     0
 .../conversation/gnunet-conversation-test.c        |     0
 .../service/conversation/gnunet-conversation.c     |  1232 ++
 .../gnunet-helper-audio-playback-gst.c             |     0
 .../conversation/gnunet-helper-audio-playback.c    |     0
 .../conversation/gnunet-helper-audio-record-gst.c  |     0
 .../conversation/gnunet-helper-audio-record.c      |     0
 .../conversation/gnunet-service-conversation.c     |  1461 ++
 .../service}/conversation/gnunet_gst.c             |     0
 .../service}/conversation/gnunet_gst.h             |     0
 .../service}/conversation/gnunet_gst_def.h         |     0
 .../service}/conversation/gnunet_gst_test.c        |     0
 .../service}/conversation/mediahelper.conf         |     0
 src/contrib/service/conversation/meson.build       |   192 +
 .../service}/conversation/microphone.c             |     0
 .../conversation/plugin_gnsrecord_conversation.c   |     0
 src/{ => contrib/service}/conversation/speaker.c   |     0
 src/{ => contrib/service}/conversation/test.sh     |     0
 .../service}/conversation/test_conversation.conf   |     0
 .../service/conversation/test_conversation_api.c   |   510 +
 .../conversation/test_conversation_api_reject.c    |   363 +
 .../conversation/test_conversation_api_twocalls.c  |   642 +
 src/contrib/service/meson.build                    |    11 +
 src/{ => contrib/service}/rps/.gitignore           |     0
 src/contrib/service/rps/Makefile.am                |   167 +
 .../service}/rps/gnunet-rps-profiler.c             |     0
 src/{ => contrib/service}/rps/gnunet-rps.c         |     0
 src/contrib/service/rps/gnunet-service-rps.c       |  5009 +++++++
 .../service}/rps/gnunet-service-rps_custommap.c    |     0
 .../service}/rps/gnunet-service-rps_custommap.h    |     0
 .../service}/rps/gnunet-service-rps_sampler.c      |     0
 .../service}/rps/gnunet-service-rps_sampler.h      |     0
 .../service}/rps/gnunet-service-rps_sampler_elem.c |     0
 .../service}/rps/gnunet-service-rps_sampler_elem.h |     0
 .../service}/rps/gnunet-service-rps_view.c         |     0
 .../service}/rps/gnunet-service-rps_view.h         |     0
 src/{ => contrib/service}/rps/profiler_rps.conf    |     0
 src/{ => contrib/service}/rps/rps-sampler_client.c |     0
 src/{ => contrib/service}/rps/rps-sampler_client.h |     0
 src/{ => contrib/service}/rps/rps-sampler_common.c |     0
 src/{ => contrib/service}/rps/rps-sampler_common.h |     0
 src/{ => contrib/service}/rps/rps-test_util.c      |     0
 src/{ => contrib/service}/rps/rps-test_util.h      |     0
 src/{ => contrib/service}/rps/rps.conf.in          |     0
 src/{ => contrib/service}/rps/rps.h                |     0
 src/{ => contrib/service}/rps/rps_api.c            |     0
 src/{ => contrib/service}/rps/test_rps.c           |     0
 src/{ => contrib/service}/rps/test_rps.conf        |     0
 src/{ => contrib/service}/rps/test_rps_api.c       |     0
 .../service}/rps/test_service_rps_custommap.c      |     0
 .../service}/rps/test_service_rps_sampler_elem.c   |     0
 .../service}/rps/test_service_rps_view.c           |     0
 src/{ => contrib/service}/scalarproduct/.gitignore |     0
 src/contrib/service/scalarproduct/Makefile.am      |   116 +
 .../service}/scalarproduct/gnunet-scalarproduct.c  |     0
 .../gnunet-service-scalarproduct-ecc.h             |     0
 .../gnunet-service-scalarproduct-ecc_alice.c       |  1150 ++
 .../gnunet-service-scalarproduct-ecc_bob.c         |     0
 .../scalarproduct/gnunet-service-scalarproduct.h   |     0
 .../gnunet-service-scalarproduct_alice.c           |  1388 ++
 .../gnunet-service-scalarproduct_bob.c             |  1384 ++
 src/contrib/service/scalarproduct/meson.build      |   101 +
 .../service}/scalarproduct/perf_scalarproduct.sh   |     0
 .../service}/scalarproduct/scalarproduct.conf.in   |     0
 .../service}/scalarproduct/scalarproduct.h         |     0
 .../service}/scalarproduct/scalarproduct_api.c     |     0
 .../scalarproduct/test_ecc_scalarproduct.c         |     0
 .../service}/scalarproduct/test_scalarproduct.conf |     0
 .../service}/scalarproduct/test_scalarproduct.sh   |     0
 .../scalarproduct/test_scalarproduct_negative.sh   |     0
 .../test_scalarproduct_negativezero.sh             |     0
 src/{ => contrib/service}/secretsharing/.gitignore |     0
 src/contrib/service/secretsharing/Makefile.am      |    74 +
 .../secretsharing/gnunet-secretsharing-profiler.c  |     0
 .../secretsharing/gnunet-service-secretsharing.c   |     0
 src/contrib/service/secretsharing/meson.build      |    45 +
 .../service}/secretsharing/secretsharing.conf.in   |     0
 .../service}/secretsharing/secretsharing.h         |     0
 .../service}/secretsharing/secretsharing_api.c     |     0
 .../service}/secretsharing/secretsharing_common.c  |     0
 .../secretsharing/secretsharing_protocol.h         |     0
 .../service}/secretsharing/test_secretsharing.conf |     0
 .../secretsharing/test_secretsharing_api.c         |     0
 src/{ => contrib/service}/set/.gitignore           |     0
 src/contrib/service/set/Makefile.am                |   122 +
 src/{ => contrib/service}/set/gnunet-service-set.c |     0
 src/{ => contrib/service}/set/gnunet-service-set.h |     0
 .../service}/set/gnunet-service-set_intersection.c |     0
 .../service}/set/gnunet-service-set_intersection.h |     0
 .../service}/set/gnunet-service-set_protocol.h     |     0
 .../service}/set/gnunet-service-set_union.c        |     0
 .../service}/set/gnunet-service-set_union.h        |     0
 .../gnunet-service-set_union_strata_estimator.c    |     0
 .../gnunet-service-set_union_strata_estimator.h    |     0
 .../service}/set/gnunet-set-ibf-profiler.c         |     0
 .../service}/set/gnunet-set-profiler.c             |     0
 src/{ => contrib/service}/set/ibf.c                |     0
 src/{ => contrib/service}/set/ibf.h                |     0
 src/{ => contrib/service}/set/ibf_sim.c            |     0
 src/contrib/service/set/meson.build                |    45 +
 .../service}/set/plugin_block_set_test.c           |     0
 src/{ => contrib/service}/set/set.conf.in          |     0
 src/{ => contrib/service}/set/set.h                |     0
 src/{ => contrib/service}/set/set_api.c            |     0
 src/{ => contrib/service}/set/test_set.conf        |     0
 src/{ => contrib/service}/set/test_set_api.c       |     0
 .../set/test_set_intersection_result_full.c        |     0
 .../service}/set/test_set_union_copy.c             |     0
 .../service}/set/test_set_union_result_symmetric.c |     0
 src/{ => contrib/service}/template/.gitignore      |     0
 src/contrib/service/template/Makefile.am           |    41 +
 .../service}/template/gnunet-service-template.c    |     0
 src/contrib/service/template/meson.build           |    21 +
 src/{ => contrib/service}/template/template.conf   |     0
 .../service}/template/test_template_api.c          |     0
 src/conversation/Makefile.am                       |   263 -
 src/conversation/conversation_api.c                |   897 --
 src/conversation/conversation_api_call.c           |   749 --
 src/conversation/gnunet-conversation.c             |  1232 --
 src/conversation/gnunet-service-conversation.c     |  1461 --
 src/conversation/test_conversation_api.c           |   510 -
 src/conversation/test_conversation_api_reject.c    |   363 -
 src/conversation/test_conversation_api_twocalls.c  |   642 -
 src/core/.gitignore                                |     9 -
 src/core/Makefile.am                               |   143 -
 src/core/core.h                                    |   327 -
 src/core/gnunet-service-core.c                     |   987 --
 src/core/gnunet-service-core_kx.c                  |  1933 ---
 src/core/gnunet-service-core_kx.h                  |   103 -
 src/core/gnunet-service-core_typemap.c             |   371 -
 src/core/gnunet-service-core_typemap.h             |   163 -
 src/curl/Makefile.am                               |    38 -
 src/curl/curl.c                                    |   898 --
 src/datacache/Makefile.am                          |   206 -
 src/datacache/perf_datacache.c                     |   174 -
 src/datacache/perf_datacache_data_heap.conf        |     5 -
 src/datacache/perf_datacache_data_postgres.conf    |     8 -
 src/datacache/perf_datacache_data_sqlite.conf      |     4 -
 src/datacache/test_datacache.c                     |   206 -
 src/datacache/test_datacache_quota.c               |   194 -
 src/datastore/.gitignore                           |    16 -
 src/datastore/Makefile.am                          |   328 -
 .../perf_plugin_datastore_data_mysql.conf          |    10 -
 src/datastore/plugin_datastore_mysql.c             |  1204 --
 src/datastore/test_datastore_api_data_mysql.conf   |    10 -
 .../test_plugin_datastore_data_mysql.conf          |     9 -
 src/dht/.gitignore                                 |    13 -
 src/dht/Makefile.am                                |   229 -
 src/dht/dht_api.c                                  |  1503 ---
 src/dht/gnunet-service-dht.c                       |   543 -
 src/dht/gnunet-service-dht.h                       |   213 -
 src/dht/gnunet-service-dht_clients.c               |  1706 ---
 src/dht/gnunet-service-dht_neighbours.c            |  3007 -----
 src/dht/gnunet-service-dht_neighbours.h            |   224 -
 src/dht/plugin_block_dht.c                         |   410 -
 src/dht/test_dht_api.c                             |   194 -
 src/dhtu/Makefile.am                               |    82 -
 src/dhtu/plugin_dhtu_gnunet.c                      |   635 -
 src/dns/Makefile.am                                |    97 -
 src/exit/Makefile.am                               |    38 -
 src/fragmentation/.gitignore                       |     2 -
 src/fragmentation/Makefile.am                      |    42 -
 src/fragmentation/defragmentation.c                |   590 -
 src/fragmentation/fragmentation.c                  |   527 -
 src/fragmentation/fragmentation.h                  |    87 -
 src/fragmentation/test_fragmentation.c             |   303 -
 src/fragmentation/test_fragmentation_data.conf     |     5 -
 src/fragmentation/test_fragmentation_parallel.c    |   254 -
 src/fs/.gitignore                                  |    43 -
 src/fs/Makefile.am                                 |   575 -
 src/fs/gnunet-publish.c                            |  1009 --
 src/fs/gnunet-service-fs.c                         |  1430 --
 src/fs/gnunet-service-fs.h                         |   306 -
 src/fs/gnunet-service-fs_cp.c                      |  1795 ---
 src/fs/meta_data.c                                 |  1232 --
 src/fs/test_gnunet_fs_idx.py.in                    |   113 -
 src/fs/test_gnunet_fs_idx_data.conf                |     7 -
 src/fs/test_gnunet_fs_psd.py.in                    |   149 -
 src/fs/test_gnunet_fs_psd_data.conf                |     7 -
 src/fs/test_gnunet_fs_rec.py.in                    |   171 -
 src/fs/test_gnunet_fs_rec_data.conf                |     7 -
 src/gns/Makefile.am                                |   306 -
 src/gns/gns_api.c                                  |   441 -
 src/gns/gns_tld_api.c                              |   353 -
 src/gns/gnunet-bcd.c                               |   677 -
 src/gns/gnunet-gns-import.c                        |   498 -
 src/gns/gnunet-gns-proxy.c                         |  3912 ------
 src/gns/gnunet-service-gns.c                       |   618 -
 src/gns/gnunet-service-gns.h                       |    54 -
 src/gns/gnunet-service-gns_interceptor.c           |   412 -
 src/gns/gnunet-service-gns_resolver.c              |  2992 ----
 src/gns/gnunet-service-gns_resolver.h              |   106 -
 src/gns/plugin_gnsrecord_gns.c                     |   431 -
 src/gns/plugin_rest_gns.c                          |   485 -
 src/gns/test_plugin_rest_gns.sh                    |    76 -
 src/gnsrecord/Makefile.am                          |   129 -
 src/gnsrecord/gnsrecord_crypto.c                   |  1091 --
 src/gnsrecord/gnsrecord_crypto.h                   |    85 -
 src/gnsrecord/gnsrecord_misc.c                     |   567 -
 src/gnsrecord/gnunet-gnsrecord-tvg.c               |   539 -
 src/gnsrecord/perf_gnsrecord_crypto.c              |   139 -
 src/gnsrecord/test_gnsrecord_block_expiration.c    |   113 -
 src/gnsrecord/test_gnsrecord_crypto.c              |   207 -
 src/gnsrecord/test_gnsrecord_testvectors.c         |   711 -
 src/hello/Makefile.am                              |    69 -
 src/hello/address.c                                |   139 -
 src/hello/gnunet-hello.c                           |   215 -
 src/hello/hello-ng.c                               |   199 -
 src/hello/hello-uri.c                              |   898 --
 src/hello/hello.c                                  |  1249 --
 src/hello/test_friend_hello.c                      |   185 -
 src/hello/test_hello-ng.c                          |    60 -
 src/hello/test_hello-uri.c                         |   213 -
 src/hello/test_hello.c                             |   253 -
 src/hostlist/Makefile.am                           |    83 -
 src/hostlist/gnunet-daemon-hostlist_client.c       |  1801 ---
 src/hostlist/gnunet-daemon-hostlist_server.c       |   904 --
 src/hostlist/hostlist.conf                         |    45 -
 src/identity/Makefile.am                           |    95 -
 src/identity/gnunet-identity.c                     |   624 -
 src/identity/gnunet-service-identity.c             |  1035 --
 src/identity/identity.h                            |   226 -
 src/identity/identity_api.c                        |  1373 --
 src/identity/identity_api_lookup.c                 |   244 -
 src/identity/identity_api_suffix_lookup.c          |   246 -
 src/identity/plugin_rest_identity.c                |  1286 --
 src/identity/test_identity.c                       |   324 -
 src/include/.gitignore                             |     7 +-
 src/include/Makefile.am                            |    17 +-
 src/include/gnu_name_system_record_types.h         |   192 +
 src/include/gnunet_abd_service.h                   |    28 +-
 src/include/gnunet_ats_application_service.h       |   109 -
 src/include/gnunet_ats_plugin.h                    |   492 -
 src/include/gnunet_ats_service.h                   |   631 -
 src/include/gnunet_ats_transport_service.h         |   241 -
 src/include/gnunet_bandwidth_lib.h                 |     4 -
 src/include/gnunet_bio_lib.h                       |    37 +-
 src/include/gnunet_cadet_service.h                 |     2 -
 src/include/gnunet_container_lib.h                 |    13 +-
 src/include/gnunet_conversation_service.h          |     2 +-
 src/include/gnunet_core_service.h                  |     1 -
 src/include/gnunet_crypto_lib.h                    |  1418 +-
 src/include/gnunet_curl_lib.h                      |     2 +-
 src/include/gnunet_dht_block_types.h               |   156 +
 src/include/gnunet_dht_service.h                   |     1 -
 src/include/gnunet_error_codes.h                   |   242 +
 src/include/gnunet_fragmentation_lib.h             |   235 -
 src/include/gnunet_friends_lib.h                   |   124 -
 src/include/gnunet_gns_service.h                   |     4 +-
 src/include/gnunet_gnsrecord_lib.h                 |   164 +-
 src/include/gnunet_hello_lib.h                     |   545 -
 src/include/gnunet_hello_uri_lib.h                 |    62 +-
 src/include/gnunet_identity_service.h              |   575 +-
 src/include/gnunet_json_lib.h                      |    24 +
 src/include/gnunet_messenger_service.h             |    17 +-
 src/include/gnunet_mq_lib.h                        |     3 +-
 src/include/gnunet_mst_lib.h                       |     4 +-
 src/include/gnunet_my_lib.h                        |   511 -
 src/include/gnunet_mysql_compat.h.in               |    57 -
 src/include/gnunet_mysql_lib.h                     |   151 -
 src/include/gnunet_namestore_plugin.h              |    14 +-
 src/include/gnunet_namestore_service.h             |    28 +-
 src/include/gnunet_network_lib.h                   |     3 +-
 src/include/gnunet_nt_lib.h                        |     5 +
 src/include/gnunet_peerstore_service.h             |   148 +-
 src/include/gnunet_plugin_lib.h                    |     2 +-
 src/include/gnunet_pq_lib.h                        |     2 +-
 src/include/gnunet_program_lib.h                   |    41 +-
 src/include/gnunet_reclaim_service.h               |    32 +-
 src/include/gnunet_rest_plugin.h                   |    21 +-
 src/include/gnunet_revocation_service.h            |   134 +-
 src/include/gnunet_service_lib.h                   |   112 +-
 src/include/gnunet_signatures.h                    |   254 +
 src/include/gnunet_testing_netjail_lib.h           |    21 +
 src/include/gnunet_testing_ng_lib.h                |   311 +-
 src/include/gnunet_testing_plugin.h                |     8 +-
 src/include/gnunet_transport_application_service.h |     3 +-
 .../gnunet_transport_communication_service.h       |     3 +-
 src/include/gnunet_transport_hello_service.h       |   207 -
 .../gnunet_transport_manipulation_service.h        |   123 -
 src/include/gnunet_transport_monitor_service.h     |     1 -
 src/include/gnunet_transport_plugin.h              |   733 -
 src/include/gnunet_transport_service.h             |   715 -
 src/include/gnunet_transport_testing_ng_lib.h      |    81 +
 src/include/gnunet_util_lib.h                      |     1 +
 src/include/meson.build                            |   123 +
 src/integration-tests/.gitignore                   |    10 -
 src/integration-tests/Makefile.am                  |    90 -
 .../confs/c_bootstrap_server.conf                  |    92 -
 src/integration-tests/confs/c_nat_client.conf      |    72 -
 src/integration-tests/confs/c_no_nat_client.conf   |   105 -
 src/integration-tests/confs/c_no_nat_client_2.conf |   119 -
 src/integration-tests/confs/test_defaults.conf     |    76 -
 src/integration-tests/gnunet_pyexpect.py.in        |    94 -
 src/integration-tests/gnunet_testing.py.in         |   381 -
 src/integration-tests/hostkeys/c_bootstrap_server  |     1 -
 src/integration-tests/hostkeys/c_nat_client        |     1 -
 src/integration-tests/hostkeys/c_no_nat_client     |     1 -
 src/integration-tests/hostkeys/c_no_nat_client_2   |     1 -
 .../test_integration_bootstrap_and_connect.py.in   |   212 -
 .../test_integration_clique.py.in                  |   236 -
 .../test_integration_disconnect.py.in              |   215 -
 .../test_integration_disconnect_nat.py.in          |   223 -
 .../test_integration_reconnect.py.in               |   237 -
 .../test_integration_reconnect_nat.py.in           |   237 -
 src/json/Makefile.am                               |    57 -
 src/json/json_helper.c                             |  1139 --
 src/json/json_pack.c                               |   354 -
 src/json/test_json.c                               |   247 -
 src/lib/Makefile.am                                |    13 +
 src/lib/block/Makefile.am                          |    31 +
 src/{ => lib}/block/bg_bf.c                        |     0
 src/{ => lib}/block/block.c                        |     0
 src/lib/block/meson.build                          |    24 +
 src/lib/curl/Makefile.am                           |    38 +
 src/lib/curl/curl.c                                |   907 ++
 src/{ => lib}/curl/curl_reschedule.c               |     0
 src/lib/curl/meson.build                           |    13 +
 src/{ => lib}/gnsrecord/.gitignore                 |     0
 src/lib/gnsrecord/Makefile.am                      |   111 +
 src/{ => lib}/gnsrecord/gnsrecord.c                |     0
 src/lib/gnsrecord/gnsrecord_crypto.c               |  1091 ++
 src/lib/gnsrecord/gnsrecord_crypto.h               |    94 +
 src/lib/gnsrecord/gnsrecord_misc.c                 |   567 +
 src/lib/gnsrecord/gnsrecord_pow.c                  |   462 +
 src/{ => lib}/gnsrecord/gnsrecord_serialization.c  |     0
 src/lib/gnsrecord/gnunet-gnsrecord-tvg.c           |   539 +
 src/{ => lib}/gnsrecord/json_gnsrecord.c           |     0
 src/lib/gnsrecord/meson.build                      |    86 +
 src/lib/gnsrecord/perf_gnsrecord_crypto.c          |   139 +
 .../gnsrecord/test_gnsrecord_block_expiration.c    |   117 +
 src/lib/gnsrecord/test_gnsrecord_crypto.c          |   211 +
 .../gnsrecord/test_gnsrecord_serialization.c       |     0
 src/lib/gnsrecord/test_gnsrecord_testvectors.c     |   708 +
 src/{ => lib}/hello/.gitignore                     |     0
 src/lib/hello/Makefile.am                          |    33 +
 src/lib/hello/gnunet-hello.c                       |   426 +
 src/lib/hello/hello-ng.c                           |   198 +
 src/lib/hello/hello-uri.c                          |  1045 ++
 src/lib/hello/meson.build                          |    27 +
 src/lib/hello/test_hello-uri.c                     |   216 +
 src/{ => lib}/json/.gitignore                      |     0
 src/lib/json/Makefile.am                           |    57 +
 src/{ => lib}/json/json.c                          |     0
 src/{ => lib}/json/json_generator.c                |     0
 src/lib/json/json_helper.c                         |  1182 ++
 src/{ => lib}/json/json_mhd.c                      |     0
 src/lib/json/json_pack.c                           |   367 +
 src/lib/json/meson.build                           |    44 +
 src/lib/json/test_json.c                           |   247 +
 src/{ => lib}/json/test_json_mhd.c                 |     0
 src/lib/meson.build                                |     8 +
 src/{ => lib}/pq/.gitignore                        |     0
 src/lib/pq/Makefile.am                             |    51 +
 src/lib/pq/meson.build                             |    32 +
 src/{ => lib}/pq/pq.c                              |     0
 src/{ => lib}/pq/pq.h                              |     0
 src/{ => lib}/pq/pq_connect.c                      |     0
 src/{ => lib}/pq/pq_eval.c                         |     0
 src/{ => lib}/pq/pq_event.c                        |     0
 src/{ => lib}/pq/pq_exec.c                         |     0
 src/{ => lib}/pq/pq_prepare.c                      |     0
 src/lib/pq/pq_query_helper.c                       |  1328 ++
 src/{ => lib}/pq/pq_result_helper.c                |     0
 src/lib/pq/test_pq.c                               |   630 +
 src/{ => lib}/pq/versioning.sql                    |     0
 src/{ => lib}/sq/.gitignore                        |     0
 src/lib/sq/Makefile.am                             |    38 +
 src/lib/sq/meson.build                             |    30 +
 src/lib/sq/sq.c                                    |   131 +
 src/lib/sq/sq_exec.c                               |   113 +
 src/lib/sq/sq_prepare.c                            |    77 +
 src/{ => lib}/sq/sq_query_helper.c                 |     0
 src/{ => lib}/sq/sq_result_helper.c                |     0
 src/lib/sq/test_sq.c                               |   291 +
 src/lib/util/.gitignore                            |    80 +
 src/lib/util/Makefile.am                           |   598 +
 src/{ => lib}/util/bandwidth.c                     |     0
 src/{ => lib}/util/benchmark.c                     |     0
 src/{ => lib}/util/benchmark.h                     |     0
 src/lib/util/bio.c                                 |  1380 ++
 src/{ => lib}/util/buffer.c                        |     0
 src/{ => lib}/util/child_management.c              |     0
 src/{ => lib}/util/child_management_test.sh        |     0
 src/{ => lib}/util/client.c                        |     0
 src/{ => lib}/util/common_allocation.c             |     0
 src/{ => lib}/util/common_endian.c                 |     0
 src/{ => lib}/util/common_logging.c                |     0
 src/{ => lib}/util/compress.c                      |     0
 src/lib/util/configuration.c                       |  2576 ++++
 src/{ => lib}/util/configuration_helper.c          |     0
 src/{ => lib}/util/consttime_memcmp.c              |     0
 src/{ => lib}/util/container_bloomfilter.c         |     0
 src/lib/util/container_heap.c                      |   501 +
 src/lib/util/container_multihashmap.c              |   974 ++
 src/lib/util/container_multihashmap32.c            |   606 +
 src/lib/util/container_multipeermap.c              |   895 ++
 src/lib/util/container_multishortmap.c             |   904 ++
 src/lib/util/container_multiuuidmap.c              |   902 ++
 src/lib/util/crypto_blind_sign.c                   |   713 +
 src/{ => lib}/util/crypto_crc.c                    |     0
 src/lib/util/crypto_cs.c                           |   366 +
 src/lib/util/crypto_ecc.c                          |   956 ++
 src/{ => lib}/util/crypto_ecc_dlog.c               |     0
 src/lib/util/crypto_ecc_gnsrecord.c                |   451 +
 src/{ => lib}/util/crypto_ecc_setup.c              |     0
 src/{ => lib}/util/crypto_edx25519.c               |     0
 src/{ => lib}/util/crypto_hash.c                   |     0
 src/{ => lib}/util/crypto_hash_file.c              |     0
 src/{ => lib}/util/crypto_hkdf.c                   |     0
 src/{ => lib}/util/crypto_kdf.c                    |     0
 src/{ => lib}/util/crypto_mpi.c                    |     0
 src/{ => lib}/util/crypto_paillier.c               |     0
 src/lib/util/crypto_pkey.c                         |   618 +
 src/{ => lib}/util/crypto_pow.c                    |     0
 src/{ => lib}/util/crypto_random.c                 |     0
 src/lib/util/crypto_rsa.c                          |  1290 ++
 src/{ => lib}/util/crypto_symmetric.c              |     0
 src/{ => lib}/util/disk.c                          |     0
 src/{ => lib}/util/disk.h                          |     0
 src/{ => lib}/util/dnsparser.c                     |     0
 src/{ => lib}/util/dnsstub.c                       |     0
 src/{ => lib}/util/getopt.c                        |     0
 src/{ => lib}/util/getopt_helpers.c                |     0
 src/lib/util/gnunet_error_codes.c                  |   262 +
 src/lib/util/helper.c                              |   672 +
 src/{ => lib}/util/load.c                          |     0
 src/lib/util/meson.build                           |   624 +
 src/{ => lib}/util/mq.c                            |     0
 src/{ => lib}/util/mst.c                           |     0
 src/{ => lib}/util/nc.c                            |     0
 src/lib/util/network.c                             |  1311 ++
 src/lib/util/nt.c                                  |   438 +
 src/{ => lib}/util/op.c                            |     0
 src/{ => lib}/util/os_installation.c               |     0
 src/lib/util/os_network.c                          |   444 +
 src/lib/util/os_priority.c                         |  1063 ++
 src/{ => lib}/util/peer.c                          |     0
 src/{ => lib}/util/perf_crypto_asymmetric.c        |     0
 src/{ => lib}/util/perf_crypto_cs.c                |     0
 src/{ => lib}/util/perf_crypto_ecc_dlog.c          |     0
 src/{ => lib}/util/perf_crypto_hash.c              |     0
 src/{ => lib}/util/perf_crypto_paillier.c          |     0
 src/lib/util/perf_crypto_rsa.c                     |   211 +
 src/{ => lib}/util/perf_crypto_symmetric.c         |     0
 src/{ => lib}/util/perf_malloc.c                   |     0
 src/{ => lib}/util/perf_mq.c                       |     0
 src/{ => lib}/util/perf_scheduler.c                |     0
 src/{ => lib}/util/plugin.c                        |     0
 src/{ => lib}/util/proc_compat.c                   |     0
 src/lib/util/program.c                             |   454 +
 src/{ => lib}/util/regex.c                         |     0
 src/lib/util/resolver.conf                         |    20 +
 src/{ => lib}/util/resolver.h                      |     0
 src/{ => lib}/util/resolver_api.c                  |     0
 src/{ => lib}/util/scheduler.c                     |     0
 src/lib/util/service.c                             |  2608 ++++
 src/{ => lib}/util/signal.c                        |     0
 src/{ => lib}/util/socks.c                         |     0
 src/{ => lib}/util/speedup.c                       |     0
 src/{ => lib}/util/speedup.h                       |     0
 src/lib/util/strings.c                             |  2007 +++
 src/{ => lib}/util/test_bio.c                      |     0
 src/{ => lib}/util/test_child_management.c         |     0
 src/{ => lib}/util/test_client.c                   |     0
 src/{ => lib}/util/test_client_data.conf           |     0
 src/{ => lib}/util/test_client_unix.conf           |     0
 src/{ => lib}/util/test_common_allocation.c        |     0
 src/{ => lib}/util/test_common_endian.c            |     0
 src/{ => lib}/util/test_common_logging.c           |     0
 src/{ => lib}/util/test_common_logging_dummy.c     |     0
 .../util/test_common_logging_runtime_loglevels.c   |     0
 src/{ => lib}/util/test_configuration.c            |     0
 src/{ => lib}/util/test_configuration_data.conf    |     0
 src/{ => lib}/util/test_container_bloomfilter.c    |     0
 src/{ => lib}/util/test_container_dll.c            |     0
 src/{ => lib}/util/test_container_heap.c           |     0
 src/{ => lib}/util/test_container_multihashmap.c   |     0
 src/{ => lib}/util/test_container_multihashmap32.c |     0
 src/{ => lib}/util/test_container_multipeermap.c   |     0
 src/lib/util/test_crypto_blind.c                   |    86 +
 src/{ => lib}/util/test_crypto_crc.c               |     0
 src/lib/util/test_crypto_cs.c                      |   621 +
 src/{ => lib}/util/test_crypto_ecc_dlog.c          |     0
 src/{ => lib}/util/test_crypto_ecdh_ecdsa.c        |     0
 src/{ => lib}/util/test_crypto_ecdh_eddsa.c        |     0
 src/{ => lib}/util/test_crypto_ecdhe.c             |     0
 src/{ => lib}/util/test_crypto_ecdsa.c             |     0
 src/{ => lib}/util/test_crypto_eddsa.c             |     0
 src/{ => lib}/util/test_crypto_edx25519.c          |     0
 src/{ => lib}/util/test_crypto_hash.c              |     0
 src/{ => lib}/util/test_crypto_hash_context.c      |     0
 src/{ => lib}/util/test_crypto_hkdf.c              |     0
 src/{ => lib}/util/test_crypto_kdf.c               |     0
 src/{ => lib}/util/test_crypto_paillier.c          |     0
 src/{ => lib}/util/test_crypto_random.c            |     0
 src/lib/util/test_crypto_rsa.c                     |   171 +
 src/{ => lib}/util/test_crypto_symmetric.c         |     0
 src/{ => lib}/util/test_disk.c                     |     0
 src/{ => lib}/util/test_getopt.c                   |     0
 src/{ => lib}/util/test_hexcoder.c                 |     0
 src/{ => lib}/util/test_mq.c                       |     0
 src/lib/util/test_os_network.c                     |    93 +
 src/{ => lib}/util/test_os_start_process.c         |     0
 src/{ => lib}/util/test_peer.c                     |     0
 src/{ => lib}/util/test_plugin.c                   |     0
 src/{ => lib}/util/test_plugin_plug.c              |     0
 src/{ => lib}/util/test_program.c                  |     0
 src/{ => lib}/util/test_program_data.conf          |     0
 src/{ => lib}/util/test_regex.c                    |     0
 src/{ => lib}/util/test_scheduler.c                |     0
 src/{ => lib}/util/test_scheduler_delay.c          |     0
 src/{ => lib}/util/test_scheduler_hogging_cancel.c |     0
 .../util/test_scheduler_hogging_priority.c         |     0
 src/{ => lib}/util/test_service.c                  |     0
 src/{ => lib}/util/test_service_data.conf          |     0
 src/{ => lib}/util/test_socks.c                    |     0
 src/{ => lib}/util/test_speedup.c                  |     0
 src/{ => lib}/util/test_speedup_data.conf          |     0
 src/{ => lib}/util/test_strings.c                  |     0
 src/{ => lib}/util/test_strings_to_data.c          |     0
 src/{ => lib}/util/test_time.c                     |     0
 src/{ => lib}/util/test_tun.c                      |     0
 src/{ => lib}/util/test_uri.c                      |     0
 src/{ => lib}/util/time.c                          |     0
 src/{ => lib}/util/tun.c                           |     0
 src/{ => lib}/util/uri.c                           |     0
 src/{ => lib}/util/util.conf                       |     0
 src/{ => lib}/util/util.supp                       |     0
 src/meson.build                                    |     6 +
 src/messenger/Makefile.am                          |   237 -
 src/messenger/gnunet-messenger.c                   |   409 -
 src/messenger/gnunet-service-messenger.c           |   496 -
 src/messenger/gnunet-service-messenger_ego_store.c |   527 -
 src/messenger/gnunet-service-messenger_ego_store.h |   206 -
 src/messenger/gnunet-service-messenger_handle.c    |   571 -
 src/messenger/gnunet-service-messenger_handle.h    |   213 -
 src/messenger/gnunet-service-messenger_member.c    |   460 -
 src/messenger/gnunet-service-messenger_member.h    |   180 -
 .../gnunet-service-messenger_member_session.c      |   857 --
 .../gnunet-service-messenger_member_session.h      |   297 -
 .../gnunet-service-messenger_member_store.h        |   159 -
 .../gnunet-service-messenger_message_recv.c        |   229 -
 .../gnunet-service-messenger_message_send.c        |   197 -
 src/messenger/gnunet-service-messenger_room.c      |  1390 --
 src/messenger/gnunet-service-messenger_room.h      |   389 -
 src/messenger/messenger_api.c                      |  1075 --
 src/messenger/messenger_api_contact.c              |   119 -
 src/messenger/messenger_api_contact.h              |   116 -
 src/messenger/messenger_api_contact_store.c        |   207 -
 src/messenger/messenger_api_contact_store.h        |   126 -
 src/messenger/messenger_api_ego.h                  |    38 -
 src/messenger/messenger_api_handle.c               |   271 -
 src/messenger/messenger_api_handle.h               |   193 -
 src/messenger/messenger_api_message.c              |  1149 --
 src/messenger/messenger_api_message.h              |   317 -
 src/messenger/messenger_api_message_kind.c         |   190 -
 src/messenger/messenger_api_message_kind.h         |   130 -
 src/messenger/messenger_api_queue_messages.c       |   108 -
 src/messenger/messenger_api_queue_messages.h       |    89 -
 src/messenger/messenger_api_util.c                 |   127 -
 src/messenger/messenger_api_util.h                 |    98 -
 src/messenger/test_messenger.c                     |   217 -
 src/messenger/test_messenger_anonymous.c           |   190 -
 src/my/.gitignore                                  |     1 -
 src/my/Makefile.am                                 |    41 -
 src/my/my.c                                        |   270 -
 src/my/my_query_helper.c                           |   401 -
 src/my/my_result_helper.c                          |   868 --
 src/my/test_my.c                                   |   301 -
 src/my/test_my.conf                                |     0
 src/mysql/Makefile.am                              |    18 -
 src/mysql/mysql.c                                  |   485 -
 src/namecache/.gitignore                           |     7 -
 src/namecache/Makefile.am                          |   179 -
 src/namecache/gnunet-namecache.c                   |   245 -
 src/namecache/plugin_namecache_flat.c              |   430 -
 src/namecache/plugin_namecache_postgres.c          |   316 -
 src/namecache/plugin_namecache_sqlite.c            |   590 -
 src/namecache/test_namecache_api_cache_block.c     |   244 -
 src/namestore/.gitignore                           |    61 -
 src/namestore/Makefile.am                          |   543 -
 src/namestore/gnunet-namestore-fcfsd.c             |  1160 --
 src/namestore/gnunet-namestore-zonefile.c          |   763 --
 src/namestore/gnunet-namestore.c                   |  2120 ---
 src/namestore/gnunet-service-namestore.c           |  2754 ----
 src/namestore/gnunet-zoneimport.c                  |  1872 ---
 src/namestore/namestore_api.c                      |  1563 ---
 src/namestore/namestore_api_monitor.c              |   443 -
 src/namestore/perf_namestore_api_import.c          |   406 -
 src/namestore/perf_namestore_api_zone_iteration.c  |   378 -
 src/namestore/plugin_namestore_flat.c              |   818 --
 src/namestore/plugin_namestore_postgres.c          |   796 --
 src/namestore/plugin_namestore_sqlite.c            |   983 --
 src/namestore/plugin_rest_namestore.c              |  1364 --
 src/namestore/test_hostkey                         |     0
 src/namestore/test_namestore_api.conf              |    43 -
 src/namestore/test_namestore_api_edit_records.c    |   399 -
 src/namestore/test_namestore_api_lookup_nick.c     |   347 -
 src/namestore/test_namestore_api_monitoring.c      |   378 -
 .../test_namestore_api_monitoring_existing.c       |   393 -
 src/namestore/test_namestore_api_remove.c          |   219 -
 ...test_namestore_api_remove_not_existing_record.c |   179 -
 src/namestore/test_namestore_api_store.c           |   172 -
 src/namestore/test_namestore_api_store_update.c    |   269 -
 src/namestore/test_namestore_api_tx_rollback.c     |   264 -
 src/namestore/test_namestore_api_zone_iteration.c  |   464 -
 .../test_namestore_api_zone_iteration_nick.c       |   460 -
 ...st_namestore_api_zone_iteration_specific_zone.c |   447 -
 .../test_namestore_api_zone_iteration_stop.c       |   449 -
 src/namestore/test_namestore_api_zone_to_name.c    |   266 -
 src/namestore/test_plugin_namestore.c              |   218 -
 src/nat-auto/.gitignore                            |     3 -
 src/nat-auto/Makefile.am                           |    60 -
 src/nat-auto/gnunet-nat-server.c                   |   402 -
 src/nat/Makefile.am                                |   118 -
 src/nat/gnunet-service-nat.c                       |  2083 ---
 src/nse/Makefile.am                                |   106 -
 src/nse/gnunet-service-nse.c                       |  1587 ---
 src/nse/nse_api.c                                  |   209 -
 src/nt/Makefile.am                                 |    33 -
 src/nt/nt.c                                        |   439 -
 src/peerinfo-tool/.gitignore                       |     2 -
 src/peerinfo-tool/Makefile.am                      |    64 -
 src/peerinfo-tool/gnunet-peerinfo.c                |   864 --
 src/peerinfo-tool/gnunet-peerinfo_plugins.c        |   196 -
 src/peerinfo-tool/gnunet-peerinfo_plugins.h        |    58 -
 src/peerinfo-tool/plugin_rest_peerinfo.c           |   842 --
 src/peerinfo-tool/test_gnunet_peerinfo.py.in       |   143 -
 src/peerinfo-tool/test_gnunet_peerinfo_data.conf   |    13 -
 src/peerinfo/.gitignore                            |     6 -
 src/peerinfo/Makefile.am                           |   105 -
 src/peerinfo/gnunet-service-peerinfo.c             |  1370 --
 src/peerinfo/peerinfo.conf.in                      |    31 -
 src/peerinfo/peerinfo.h                            |   122 -
 src/peerinfo/peerinfo_api.c                        |   557 -
 src/peerinfo/peerinfo_api_notify.c                 |   291 -
 src/peerinfo/perf_peerinfo_api.c                   |   193 -
 src/peerinfo/test_peerinfo_api.c                   |   172 -
 src/peerinfo/test_peerinfo_api_data.conf           |    15 -
 src/peerinfo/test_peerinfo_api_friend_only.c       |   172 -
 .../test_peerinfo_api_notify_friend_only.c         |   261 -
 src/peerinfo/test_peerinfo_shipped_hellos.c        |   144 -
 src/peerstore/Makefile.am                          |   148 -
 src/peerstore/gnunet-service-peerstore.c           |   610 -
 src/peerstore/peerstore.conf.in                    |    13 -
 src/peerstore/peerstore_api.c                      |   938 --
 src/peerstore/plugin_peerstore_flat.c              |   606 -
 src/peerstore/plugin_peerstore_sqlite.c            |   702 -
 src/plugin/Makefile.am                             |    18 +
 src/plugin/block/Makefile.am                       |    37 +
 src/plugin/block/meson.build                       |    15 +
 src/{ => plugin}/block/plugin_block_template.c     |     0
 src/{ => plugin}/block/plugin_block_test.c         |     0
 src/plugin/datacache/Makefile.am                   |    76 +
 src/{ => plugin}/datacache/datacache-0001.sql      |     0
 src/{ => plugin}/datacache/datacache-drop.sql      |     0
 src/plugin/datacache/meson.build                   |    30 +
 src/{ => plugin}/datacache/plugin_datacache_heap.c |     0
 .../datacache/plugin_datacache_postgres.c          |     0
 .../datacache/plugin_datacache_sqlite.c            |     0
 .../datacache/plugin_datacache_template.c          |     0
 src/plugin/datastore/Makefile.am                   |   150 +
 src/{ => plugin}/datastore/datastore-0001.sql      |     0
 src/{ => plugin}/datastore/datastore-drop.sql      |     0
 src/plugin/datastore/meson.build                   |    75 +
 src/{ => plugin}/datastore/perf_plugin_datastore.c |     0
 .../datastore/perf_plugin_datastore_data_heap.conf |     0
 .../perf_plugin_datastore_data_postgres.conf       |     0
 .../perf_plugin_datastore_data_sqlite.conf         |     0
 src/{ => plugin}/datastore/plugin_datastore_heap.c |     0
 .../datastore/plugin_datastore_postgres.c          |     0
 .../datastore/plugin_datastore_sqlite.c            |     0
 .../datastore/plugin_datastore_template.c          |     0
 src/{ => plugin}/datastore/test_defaults.conf      |     0
 src/{ => plugin}/datastore/test_plugin_datastore.c |     0
 .../datastore/test_plugin_datastore_data_heap.conf |     0
 .../test_plugin_datastore_data_postgres.conf       |     0
 .../test_plugin_datastore_data_sqlite.conf         |     0
 src/plugin/dht/Makefile.am                         |    27 +
 src/plugin/dht/meson.build                         |     9 +
 src/plugin/dht/plugin_block_dht.c                  |   308 +
 src/plugin/dns/Makefile.am                         |    25 +
 src/plugin/dns/meson.build                         |     6 +
 src/{ => plugin}/dns/plugin_block_dns.c            |     0
 src/plugin/fs/Makefile.am                          |    35 +
 src/plugin/fs/meson.build                          |     8 +
 src/{ => plugin}/fs/plugin_block_fs.c              |     0
 src/{ => plugin}/fs/test_plugin_block_fs.c         |     0
 src/plugin/gns/Makefile.am                         |    59 +
 src/plugin/gns/meson.build                         |    17 +
 src/{ => plugin}/gns/plugin_block_gns.c            |     0
 src/plugin/gns/plugin_gnsrecord_gns.c              |   431 +
 src/plugin/gnsrecord/Makefile.am                   |    25 +
 src/plugin/gnsrecord/meson.build                   |     6 +
 src/{ => plugin}/gnsrecord/plugin_gnsrecord_dns.c  |     0
 src/plugin/meson.build                             |    17 +
 src/plugin/messenger/Makefile.am                   |    26 +
 src/plugin/messenger/meson.build                   |     7 +
 .../messenger/plugin_gnsrecord_messenger.c         |     0
 src/plugin/namecache/Makefile.am                   |   108 +
 src/plugin/namecache/meson.build                   |    22 +
 src/{ => plugin}/namecache/namecache-0001.sql      |     0
 src/{ => plugin}/namecache/namecache-drop.sql      |     0
 src/plugin/namecache/plugin_namecache_flat.c       |   429 +
 src/plugin/namecache/plugin_namecache_postgres.c   |   315 +
 src/plugin/namecache/plugin_namecache_sqlite.c     |   589 +
 src/{ => plugin}/namecache/test_plugin_namecache.c |     0
 .../namecache/test_plugin_namecache_flat.conf      |     0
 .../namecache/test_plugin_namecache_postgres.conf  |     0
 .../namecache/test_plugin_namecache_sqlite.conf    |     0
 src/plugin/namestore/Makefile.am                   |    79 +
 src/plugin/namestore/meson.build                   |    51 +
 src/{ => plugin}/namestore/namestore-0001.sql      |     0
 src/{ => plugin}/namestore/namestore-drop.sql      |     0
 src/plugin/namestore/plugin_namestore_flat.c       |   817 ++
 src/plugin/namestore/plugin_namestore_postgres.c   |   795 ++
 src/plugin/namestore/plugin_namestore_sqlite.c     |   982 ++
 src/plugin/namestore/test_plugin_namestore.c       |   217 +
 .../namestore/test_plugin_namestore_postgres.conf  |     0
 .../namestore/test_plugin_namestore_sqlite.conf    |     0
 .../namestore/test_plugin_rest_namestore.sh        |     0
 src/plugin/peerstore/Makefile.am                   |    67 +
 src/plugin/peerstore/meson.build                   |     9 +
 src/plugin/peerstore/plugin_peerstore_flat.c       |   606 +
 src/plugin/peerstore/plugin_peerstore_sqlite.c     |   702 +
 src/{ => plugin}/peerstore/test_plugin_peerstore.c |     0
 .../peerstore/test_plugin_peerstore_flat.conf      |     0
 .../peerstore/test_plugin_peerstore_sqlite.conf    |     0
 src/plugin/reclaim/Makefile.am                     |    70 +
 src/plugin/reclaim/meson.build                     |    28 +
 src/{ => plugin}/reclaim/pabc_helper.c             |     0
 src/{ => plugin}/reclaim/pabc_helper.h             |     0
 .../reclaim/plugin_gnsrecord_reclaim.c             |     0
 .../reclaim/plugin_reclaim_attribute_basic.c       |     0
 .../reclaim/plugin_reclaim_credential_jwt.c        |     0
 .../reclaim/plugin_reclaim_credential_pabc.c       |     0
 src/plugin/regex/Makefile.am                       |    40 +
 src/plugin/regex/meson.build                       |    23 +
 src/{ => plugin}/regex/plugin_block_regex.c        |     0
 src/{ => plugin}/regex/regex_block_lib.c           |     0
 src/{ => plugin}/regex/regex_block_lib.h           |     0
 src/plugin/revocation/Makefile.am                  |    27 +
 src/plugin/revocation/meson.build                  |     9 +
 src/plugin/revocation/plugin_block_revocation.c    |   309 +
 src/plugin/seti/Makefile.am                        |    25 +
 src/plugin/seti/meson.build                        |     7 +
 src/{ => plugin}/seti/plugin_block_seti_test.c     |     0
 src/plugin/setu/Makefile.am                        |    21 +
 src/plugin/setu/meson.build                        |     7 +
 src/{ => plugin}/setu/plugin_block_setu_test.c     |     0
 src/pq/Makefile.am                                 |    51 -
 src/pq/pq_query_helper.c                           |  1328 --
 src/pq/test_pq.c                                   |   629 -
 src/pt/Makefile.am                                 |    93 -
 src/pt/test_gns_vpn.c                              |   864 --
 src/reclaim/Makefile.am                            |   252 -
 src/reclaim/did.h                                  |    49 -
 src/reclaim/did_core.c                             |   265 -
 src/reclaim/did_helper.c                           |   203 -
 src/reclaim/did_helper.h                           |    74 -
 src/reclaim/did_misc.c                             |    70 -
 src/reclaim/gnunet-did.c                           |   647 -
 src/reclaim/gnunet-reclaim.c                       |   928 --
 src/reclaim/gnunet-service-reclaim.c               |  2814 ----
 src/reclaim/gnunet-service-reclaim_tickets.c       |  1894 ---
 src/reclaim/gnunet-service-reclaim_tickets.h       |   280 -
 src/reclaim/oidc_helper.c                          |  1026 --
 src/reclaim/oidc_helper.h                          |   196 -
 src/reclaim/plugin_rest_openid_connect.c           |  3162 -----
 src/reclaim/plugin_rest_reclaim.c                  |  1564 ---
 src/reclaim/reclaim_api.c                          |  1813 ---
 src/reclaim/test_did_helper.c                      |   137 -
 src/regex/Makefile.am                              |   196 -
 src/regex/gnunet-daemon-regexprofiler.c            |   407 -
 src/regex/regex_internal_dht.c                     |   829 --
 src/regex/regex_internal_lib.h                     |   268 -
 src/rest/Makefile.am                               |    68 -
 src/rest/gnunet-rest-server.c                      |  1381 --
 src/rest/plugin_rest_config.c                      |   455 -
 src/rest/plugin_rest_copying.c                     |   238 -
 src/revocation/Makefile.am                         |   120 -
 src/revocation/gnunet-revocation-tvg.c             |   229 -
 src/revocation/gnunet-revocation.c                 |   581 -
 src/revocation/gnunet-service-revocation.c         |  1064 --
 src/revocation/plugin_block_revocation.c           |   308 -
 src/revocation/revocation.h                        |   124 -
 src/revocation/revocation_api.c                    |   764 --
 src/revocation/test_revocation.c                   |   419 -
 src/revocation/test_revocation_testvectors.c       |   297 -
 src/rps/Makefile.am                                |   172 -
 src/rps/gnunet-service-rps.c                       |  5007 -------
 src/scalarproduct/Makefile.am                      |   116 -
 .../gnunet-service-scalarproduct-ecc_alice.c       |  1149 --
 .../gnunet-service-scalarproduct_alice.c           |  1387 --
 .../gnunet-service-scalarproduct_bob.c             |  1383 --
 src/secretsharing/Makefile.am                      |    73 -
 src/service/Makefile.am                            |    36 +
 src/service/arm/.gitignore                         |     7 +
 src/service/arm/Makefile.am                        |    77 +
 src/{ => service}/arm/arm.conf.in                  |     0
 src/{ => service}/arm/arm.h                        |     0
 src/{ => service}/arm/arm_api.c                    |     0
 src/{ => service}/arm/arm_monitor_api.c            |     0
 src/service/arm/gnunet-service-arm.c               |  2227 +++
 src/service/arm/meson.build                        |    71 +
 src/{ => service}/arm/mockup-service.c             |     0
 src/{ => service}/arm/mockup_service               |     0
 src/{ => service}/arm/test_arm_api.c               |     0
 src/{ => service}/arm/test_arm_api_data.conf       |     0
 src/{ => service}/arm/test_exponential_backoff.c   |     0
 src/{ => service}/arm/test_gnunet_arm.py.in        |     0
 src/{ => service}/arm/test_gnunet_service_arm.c    |     0
 src/{ => service}/cadet/.gitignore                 |     0
 src/service/cadet/Makefile.am                      |    81 +
 src/{ => service}/cadet/TODO                       |     0
 src/{ => service}/cadet/cadet.conf.in              |     0
 src/{ => service}/cadet/cadet.h                    |     0
 src/{ => service}/cadet/cadet_api.c                |     0
 src/{ => service}/cadet/cadet_api_drop_message.c   |     0
 src/{ => service}/cadet/cadet_api_get_channel.c    |     0
 src/{ => service}/cadet/cadet_api_get_path.c       |     0
 src/{ => service}/cadet/cadet_api_helper.c         |     0
 src/{ => service}/cadet/cadet_api_list_peers.c     |     0
 src/{ => service}/cadet/cadet_api_list_tunnels.c   |     0
 src/{ => service}/cadet/cadet_protocol.h           |     0
 src/{ => service}/cadet/cadet_test_lib.c           |     0
 src/{ => service}/cadet/cadet_test_lib.h           |     0
 src/{ => service}/cadet/desirability_table.c       |     0
 src/service/cadet/gnunet-service-cadet.c           |  1376 ++
 src/service/cadet/gnunet-service-cadet.h           |   328 +
 .../cadet/gnunet-service-cadet_channel.c           |     0
 .../cadet/gnunet-service-cadet_channel.h           |     0
 .../cadet/gnunet-service-cadet_connection.c        |     0
 .../cadet/gnunet-service-cadet_connection.h        |     0
 .../cadet/gnunet-service-cadet_core.c              |     0
 .../cadet/gnunet-service-cadet_core.h              |     0
 src/service/cadet/gnunet-service-cadet_dht.c       |   339 +
 src/{ => service}/cadet/gnunet-service-cadet_dht.h |     0
 src/service/cadet/gnunet-service-cadet_hello.c     |   164 +
 src/service/cadet/gnunet-service-cadet_hello.h     |    80 +
 .../cadet/gnunet-service-cadet_paths.c             |     0
 .../cadet/gnunet-service-cadet_paths.h             |     0
 src/service/cadet/gnunet-service-cadet_peer.c      |  1554 +++
 src/service/cadet/gnunet-service-cadet_peer.h      |   433 +
 .../cadet/gnunet-service-cadet_tunnels.c           |     0
 .../cadet/gnunet-service-cadet_tunnels.h           |     0
 src/{ => service}/cadet/loopcheck.sh               |     0
 src/service/cadet/meson.build                      |    72 +
 src/{ => service}/cadet/profiler.conf              |     0
 src/{ => service}/cadet/run_profiler.sh            |     0
 src/{ => service}/cadet/small.dat                  |     0
 src/{ => service}/cadet/test_cadet.conf            |     0
 src/{ => service}/cadet/test_cadet_local_mq.c      |     0
 src/{ => service}/cadet/valgrind-cadet.supp        |     0
 src/service/core/.gitignore                        |     9 +
 src/service/core/Makefile.am                       |   127 +
 src/{ => service}/core/core.conf.in                |     0
 src/service/core/core.h                            |   326 +
 src/{ => service}/core/core_api.c                  |     0
 src/service/core/core_api_cmd_connecting_peers.c   |   273 +
 src/{ => service}/core/core_api_monitor_peers.c    |     0
 src/service/core/gnunet-service-core.c             |   988 ++
 src/{ => service}/core/gnunet-service-core.h       |     0
 src/service/core/gnunet-service-core_kx.c          |  1934 +++
 src/service/core/gnunet-service-core_kx.h          |   102 +
 .../core/gnunet-service-core_sessions.c            |     0
 .../core/gnunet-service-core_sessions.h            |     0
 src/service/core/gnunet-service-core_typemap.c     |   370 +
 src/service/core/gnunet-service-core_typemap.h     |   162 +
 src/service/core/meson.build                       |   112 +
 src/{ => service}/core/test_core_api.c             |     0
 src/{ => service}/core/test_core_api_data.conf     |     0
 src/{ => service}/core/test_core_api_peer1.conf    |     0
 src/{ => service}/core/test_core_api_peer2.conf    |     0
 src/{ => service}/core/test_core_api_reliability.c |     0
 .../core/test_core_api_send_to_self.c              |     0
 .../core/test_core_api_send_to_self.conf           |     0
 src/{ => service}/core/test_core_api_start_only.c  |     0
 src/{ => service}/core/test_core_defaults.conf     |     0
 src/service/core/test_core_just_run.conf           |    55 +
 src/service/core/test_core_just_run_host.conf      |    45 +
 src/service/core/test_core_plugin_cmd_just_run.c   |   390 +
 ...t_core_quota_asymmetric_recv_limited_peer1.conf |     0
 ...t_core_quota_asymmetric_recv_limited_peer2.conf |     0
 ...est_core_quota_asymmetric_send_limit_peer1.conf |     0
 ...est_core_quota_asymmetric_send_limit_peer2.conf |     0
 .../core/test_core_quota_compliance.c              |     0
 src/{ => service}/core/test_core_quota_peer1.conf  |     0
 src/{ => service}/core/test_core_quota_peer2.conf  |     0
 src/service/core/test_core_start_testcase.sh       |    15 +
 src/{ => service}/datacache/.gitignore             |     0
 src/service/datacache/Makefile.am                  |   104 +
 src/{ => service}/datacache/datacache.c            |     0
 src/{ => service}/datacache/datacache.conf         |     0
 src/service/datacache/meson.build                  |   109 +
 src/service/datacache/test_datacache.c             |   210 +
 .../datacache/test_datacache_data_heap.conf        |     0
 .../datacache/test_datacache_data_postgres.conf    |     0
 .../datacache/test_datacache_data_sqlite.conf      |     0
 src/service/datacache/test_datacache_quota.c       |   199 +
 src/service/datastore/.gitignore                   |    15 +
 src/service/datastore/Makefile.am                  |   142 +
 src/{ => service}/datastore/datastore.conf.in      |     0
 src/{ => service}/datastore/datastore.h            |     0
 src/{ => service}/datastore/datastore_api.c        |     0
 .../datastore/gnunet-service-datastore.c           |     0
 src/service/datastore/meson.build                  |   126 +
 src/{ => service}/datastore/perf_datastore_api.c   |     0
 src/{ => service}/datastore/selectrandom.sql       |     0
 src/{ => service}/datastore/test_datastore_api.c   |     0
 .../datastore/test_datastore_api_data_heap.conf    |     0
 .../test_datastore_api_data_postgres.conf          |     0
 .../datastore/test_datastore_api_data_sqlite.conf  |     0
 .../datastore/test_datastore_api_management.c      |     0
 src/{ => service}/datastore/test_defaults.conf     |     0
 src/service/dht/.gitignore                         |     8 +
 src/service/dht/Makefile.am                        |    71 +
 src/{ => service}/dht/dht.conf.in                  |     0
 src/{ => service}/dht/dht.h                        |     0
 src/service/dht/dht_api.c                          |  1501 +++
 src/{ => service}/dht/dht_test_lib.c               |     0
 src/{ => service}/dht/dht_test_lib.h               |     0
 src/{ => service}/dht/dhtu_testbed_connect.sh      |     0
 src/{ => service}/dht/dhtu_testbed_deploy.conf     |     0
 src/{ => service}/dht/dhtu_testbed_deploy.sh       |     0
 src/service/dht/gnunet-service-dht.c               |   554 +
 src/service/dht/gnunet-service-dht.h               |   212 +
 src/service/dht/gnunet-service-dht_clients.c       |  1705 +++
 .../dht/gnunet-service-dht_datacache.c             |     0
 .../dht/gnunet-service-dht_datacache.h             |     0
 src/service/dht/gnunet-service-dht_neighbours.c    |  3009 +++++
 src/service/dht/gnunet-service-dht_neighbours.h    |   226 +
 src/{ => service}/dht/gnunet-service-dht_routing.c |     0
 src/{ => service}/dht/gnunet-service-dht_routing.h |     0
 src/{ => service}/dht/gnunet_dht_profiler.c        |     0
 src/service/dht/meson.build                        |    59 +
 src/{ => service}/dht/test_dht_2dtorus.conf        |     0
 src/service/dht/test_dht_api.c                     |   193 +
 src/{ => service}/dht/test_dht_api_data.conf       |     0
 src/{ => service}/dht/test_dht_api_peer1.conf      |     0
 src/{ => service}/dht/test_dht_line.conf           |     0
 src/{ => service}/dht/test_dht_monitor.c           |     0
 src/{ => service}/dht/test_dht_monitor.conf        |     0
 src/{ => service}/dht/test_dht_multipeer.conf      |     0
 .../dht/test_dht_multipeer_topology.dat            |     0
 src/{ => service}/dht/test_dht_tools.conf          |     0
 src/{ => service}/dht/test_dht_tools.py.in         |     0
 src/{ => service}/dht/test_dht_tools.sh            |     0
 src/{ => service}/dht/test_dht_topo.c              |     0
 src/{ => service}/dhtu/.gitignore                  |     0
 src/service/dhtu/Makefile.am                       |    81 +
 src/{ => service}/dhtu/dhtu.conf                   |     0
 src/service/dhtu/meson.build                       |    61 +
 src/service/dhtu/plugin_dhtu_gnunet.c              |   603 +
 src/{ => service}/dhtu/plugin_dhtu_ip.c            |     0
 src/{ => service}/dhtu/test_dhtu_ip.c              |     0
 src/{ => service}/dhtu/testing_dhtu_cmd_send.c     |     0
 src/{ => service}/dns/.gitignore                   |     0
 src/service/dns/Makefile.am                        |    83 +
 src/{ => service}/dns/dns.conf.in                  |     0
 src/{ => service}/dns/dns.h                        |     0
 src/{ => service}/dns/dns_api.c                    |     0
 src/{ => service}/dns/gnunet-dns-monitor.c         |     0
 src/{ => service}/dns/gnunet-dns-redirector.c      |     0
 src/{ => service}/dns/gnunet-helper-dns.c          |     0
 src/{ => service}/dns/gnunet-service-dns.c         |     0
 src/{ => service}/dns/gnunet-zonewalk.c            |     0
 src/service/dns/meson.build                        |    64 +
 src/{ => service}/dns/test_gnunet_dns.sh           |     0
 src/{ => service}/exit/.gitignore                  |     0
 src/service/exit/Makefile.am                       |    38 +
 src/{ => service}/exit/exit.conf                   |     0
 src/{ => service}/exit/exit.h                      |     0
 src/{ => service}/exit/gnunet-daemon-exit.c        |     0
 src/{ => service}/exit/gnunet-helper-exit.c        |     0
 src/service/exit/meson.build                       |    25 +
 src/service/fs/.gitignore                          |    36 +
 src/service/fs/Makefile.am                         |   385 +
 src/{ => service}/fs/fs.conf.in                    |     0
 src/{ => service}/fs/fs.h                          |     0
 src/{ => service}/fs/fs_api.c                      |     0
 src/{ => service}/fs/fs_api.h                      |     0
 src/{ => service}/fs/fs_directory.c                |     0
 src/{ => service}/fs/fs_dirmetascan.c              |     0
 src/{ => service}/fs/fs_download.c                 |     0
 src/{ => service}/fs/fs_file_information.c         |     0
 src/{ => service}/fs/fs_getopt.c                   |     0
 src/{ => service}/fs/fs_list_indexed.c             |     0
 src/{ => service}/fs/fs_misc.c                     |     0
 src/{ => service}/fs/fs_namespace.c                |     0
 src/{ => service}/fs/fs_publish.c                  |     0
 src/{ => service}/fs/fs_publish_ksk.c              |     0
 src/{ => service}/fs/fs_publish_ublock.c           |     0
 src/{ => service}/fs/fs_publish_ublock.h           |     0
 src/{ => service}/fs/fs_search.c                   |     0
 src/{ => service}/fs/fs_sharetree.c                |     0
 src/{ => service}/fs/fs_test_lib.c                 |     0
 src/{ => service}/fs/fs_test_lib.h                 |     0
 src/{ => service}/fs/fs_test_lib_data.conf         |     0
 src/{ => service}/fs/fs_tree.c                     |     0
 src/{ => service}/fs/fs_tree.h                     |     0
 src/{ => service}/fs/fs_unindex.c                  |     0
 src/{ => service}/fs/fs_uri.c                      |     0
 src/{ => service}/fs/gnunet-daemon-fsprofiler.c    |     0
 src/{ => service}/fs/gnunet-fs-profiler.c          |     0
 src/{ => service}/fs/gnunet-helper-fs-publish.c    |     0
 src/service/fs/gnunet-service-fs.c                 |  1378 ++
 src/service/fs/gnunet-service-fs.h                 |   304 +
 src/{ => service}/fs/gnunet-service-fs_cadet.h     |     0
 .../fs/gnunet-service-fs_cadet_client.c            |     0
 .../fs/gnunet-service-fs_cadet_server.c            |     0
 src/service/fs/gnunet-service-fs_cp.c              |  1659 +++
 src/{ => service}/fs/gnunet-service-fs_cp.h        |     0
 src/{ => service}/fs/gnunet-service-fs_indexing.c  |     0
 src/{ => service}/fs/gnunet-service-fs_indexing.h  |     0
 src/{ => service}/fs/gnunet-service-fs_pe.c        |     0
 src/{ => service}/fs/gnunet-service-fs_pe.h        |     0
 src/{ => service}/fs/gnunet-service-fs_pr.c        |     0
 src/{ => service}/fs/gnunet-service-fs_pr.h        |     0
 src/{ => service}/fs/gnunet-service-fs_push.c      |     0
 src/{ => service}/fs/gnunet-service-fs_push.h      |     0
 src/{ => service}/fs/gnunet-service-fs_put.c       |     0
 src/{ => service}/fs/gnunet-service-fs_put.h       |     0
 src/service/fs/meson.build                         |    82 +
 src/service/fs/meta_data.c                         |  1229 ++
 src/{ => service}/fs/perf_gnunet_service_fs_p2p.c  |     0
 .../fs/perf_gnunet_service_fs_p2p.conf             |     0
 .../fs/perf_gnunet_service_fs_p2p_respect.c        |     0
 src/{ => service}/fs/test_fs.c                     |     0
 src/{ => service}/fs/test_fs_data.conf             |     0
 src/{ => service}/fs/test_fs_defaults.conf         |     0
 src/{ => service}/fs/test_fs_directory.c           |     0
 src/{ => service}/fs/test_fs_download.c            |     0
 src/{ => service}/fs/test_fs_download_data.conf    |     0
 src/{ => service}/fs/test_fs_download_indexed.conf |     0
 .../fs/test_fs_download_persistence.c              |     0
 src/{ => service}/fs/test_fs_file_information.c    |     0
 .../fs/test_fs_file_information_data.conf          |     0
 src/{ => service}/fs/test_fs_getopt.c              |     0
 src/{ => service}/fs/test_fs_list_indexed.c        |     0
 .../fs/test_fs_list_indexed_data.conf              |     0
 src/{ => service}/fs/test_fs_meta_data.c           |     0
 src/{ => service}/fs/test_fs_namespace.c           |     0
 src/{ => service}/fs/test_fs_namespace_data.conf   |     0
 .../fs/test_fs_namespace_list_updateable.c         |     0
 src/{ => service}/fs/test_fs_publish.c             |     0
 src/{ => service}/fs/test_fs_publish_data.conf     |     0
 src/{ => service}/fs/test_fs_publish_persistence.c |     0
 src/{ => service}/fs/test_fs_search.c              |     0
 src/{ => service}/fs/test_fs_search_data.conf      |     0
 src/{ => service}/fs/test_fs_search_persistence.c  |     0
 src/{ => service}/fs/test_fs_search_probes.c       |     0
 src/{ => service}/fs/test_fs_search_with_and.c     |     0
 src/{ => service}/fs/test_fs_start_stop.c          |     0
 src/{ => service}/fs/test_fs_test_lib.c            |     0
 src/{ => service}/fs/test_fs_unindex.c             |     0
 src/{ => service}/fs/test_fs_unindex_data.conf     |     0
 src/{ => service}/fs/test_fs_unindex_persistence.c |     0
 src/{ => service}/fs/test_fs_uri.c                 |     0
 src/{ => service}/fs/test_gnunet_fs_rec_data.tgz   |   Bin
 .../fs/test_gnunet_service_fs_migration.c          |     0
 .../fs/test_gnunet_service_fs_migration_data.conf  |     0
 src/{ => service}/fs/test_gnunet_service_fs_p2p.c  |     0
 .../fs/test_gnunet_service_fs_p2p_cadet.conf       |     0
 src/{ => service}/fs/test_pseudonym_data.conf      |     0
 src/{ => service}/gns/.gitignore                   |     0
 src/service/gns/Makefile.am                        |   180 +
 src/{ => service}/gns/gns.conf.in                  |     0
 src/{ => service}/gns/gns.h                        |     0
 src/service/gns/gns_api.c                          |   440 +
 src/{ => service}/gns/gns_api.h                    |     0
 src/service/gns/gns_tld_api.c                      |   352 +
 src/service/gns/gnunet-bcd.c                       |   677 +
 src/{ => service}/gns/gnunet-dns2gns.c             |     0
 src/{ => service}/gns/gnunet-gns-benchmark.c       |     0
 src/service/gns/gnunet-gns-import.c                |   498 +
 src/service/gns/gnunet-gns-proxy.c                 |  3912 ++++++
 src/service/gns/gnunet-service-gns.c               |   618 +
 src/service/gns/gnunet-service-gns.h               |    54 +
 src/service/gns/gnunet-service-gns_interceptor.c   |   412 +
 .../gns/gnunet-service-gns_interceptor.h           |     0
 src/service/gns/gnunet-service-gns_resolver.c      |  2992 ++++
 src/service/gns/gnunet-service-gns_resolver.h      |   106 +
 src/{ => service}/gns/gnunet_w32nsp_lib.h          |     0
 src/service/gns/meson.build                        |   113 +
 src/{ => service}/gns/nss/Makefile.am              |     0
 src/{ => service}/gns/nss/map-file                 |     0
 src/service/gns/nss/meson.build                    |    34 +
 src/{ => service}/gns/nss/nss_gns.c                |     0
 src/{ => service}/gns/nss/nss_gns_query.c          |     0
 src/{ => service}/gns/nss/nss_gns_query.h          |     0
 src/{ => service}/gns/test_gns_proxy.c             |     0
 src/{ => service}/gns/test_gns_proxy.conf          |     0
 src/{ => service}/gns/test_proxy.sh                |     0
 src/service/gns/tlds.conf                          |    15 +
 src/{ => service}/gns/w32resolver.h                |     0
 src/{ => service}/hostlist/.gitignore              |     0
 src/service/hostlist/Makefile.am                   |    82 +
 .../hostlist/gnunet-daemon-hostlist.c              |     0
 .../hostlist/gnunet-daemon-hostlist.h              |     0
 .../hostlist/gnunet-daemon-hostlist_client.c       |  1824 +++
 .../hostlist/gnunet-daemon-hostlist_client.h       |     0
 .../hostlist/gnunet-daemon-hostlist_server.c       |   888 ++
 .../hostlist/gnunet-daemon-hostlist_server.h       |     0
 src/service/hostlist/hostlist.conf                 |    45 +
 .../hostlist/hostlists_learn_peer2.file            |   Bin
 src/{ => service}/hostlist/learning_data.conf      |     0
 src/service/hostlist/meson.build                   |    23 +
 .../hostlist/test_gnunet_daemon_hostlist.c         |     0
 .../hostlist/test_gnunet_daemon_hostlist_data.conf |     0
 .../test_gnunet_daemon_hostlist_learning.c         |     0
 .../test_gnunet_daemon_hostlist_peer1.conf         |     0
 .../test_gnunet_daemon_hostlist_peer2.conf         |     0
 .../test_gnunet_daemon_hostlist_reconnect.c        |     0
 .../hostlist/test_hostlist_defaults.conf           |     0
 .../hostlist/test_learning_adv_peer.conf           |     0
 .../hostlist/test_learning_learn_peer.conf         |     0
 .../hostlist/test_learning_learn_peer2.conf        |     0
 src/{ => service}/identity/.gitignore              |     0
 src/service/identity/Makefile.am                   |    66 +
 src/service/identity/gnunet-service-identity.c     |  1035 ++
 src/{ => service}/identity/identity.conf.in        |     0
 src/service/identity/identity.h                    |   226 +
 src/service/identity/identity_api.c                |   768 ++
 src/service/identity/identity_api_lookup.c         |   244 +
 src/service/identity/identity_api_suffix_lookup.c  |   246 +
 src/service/identity/meson.build                   |    40 +
 src/service/identity/test_identity.c               |   324 +
 src/{ => service}/identity/test_identity.conf      |     0
 .../identity/test_plugin_rest_identity.sh          |     0
 .../test_plugin_rest_identity_signature.sh         |     0
 src/service/meson.build                            |    66 +
 src/{ => service}/messenger/.gitignore             |     0
 src/service/messenger/Makefile.am                  |   103 +
 src/service/messenger/gnunet-messenger.c           |   409 +
 src/service/messenger/gnunet-service-messenger.c   |   495 +
 .../messenger/gnunet-service-messenger.h           |     0
 .../messenger/gnunet-service-messenger_basement.c  |     0
 .../messenger/gnunet-service-messenger_basement.h  |     0
 .../messenger/gnunet-service-messenger_ego_store.c |   527 +
 .../messenger/gnunet-service-messenger_ego_store.h |   206 +
 .../messenger/gnunet-service-messenger_handle.c    |   571 +
 .../messenger/gnunet-service-messenger_handle.h    |   213 +
 .../gnunet-service-messenger_list_handles.c        |     0
 .../gnunet-service-messenger_list_handles.h        |     0
 .../gnunet-service-messenger_list_messages.c       |     0
 .../gnunet-service-messenger_list_messages.h       |     0
 .../messenger/gnunet-service-messenger_member.c    |   460 +
 .../messenger/gnunet-service-messenger_member.h    |   180 +
 .../gnunet-service-messenger_member_session.c      |   857 ++
 .../gnunet-service-messenger_member_session.h      |   297 +
 .../gnunet-service-messenger_member_store.c        |     0
 .../gnunet-service-messenger_member_store.h        |   159 +
 .../gnunet-service-messenger_message_handle.c      |     0
 .../gnunet-service-messenger_message_handle.h      |     0
 .../gnunet-service-messenger_message_kind.c        |     0
 .../gnunet-service-messenger_message_kind.h        |     0
 .../gnunet-service-messenger_message_recv.c        |   229 +
 .../gnunet-service-messenger_message_recv.h        |     0
 .../gnunet-service-messenger_message_send.c        |   197 +
 .../gnunet-service-messenger_message_send.h        |     0
 .../gnunet-service-messenger_message_state.c       |     0
 .../gnunet-service-messenger_message_state.h       |     0
 .../gnunet-service-messenger_message_store.c       |     0
 .../gnunet-service-messenger_message_store.h       |     0
 .../messenger/gnunet-service-messenger_operation.c |     0
 .../messenger/gnunet-service-messenger_operation.h |     0
 .../gnunet-service-messenger_operation_store.c     |     0
 .../gnunet-service-messenger_operation_store.h     |     0
 .../messenger/gnunet-service-messenger_room.c      |  1390 ++
 .../messenger/gnunet-service-messenger_room.h      |   389 +
 .../gnunet-service-messenger_sender_session.h      |     0
 .../messenger/gnunet-service-messenger_service.c   |     0
 .../messenger/gnunet-service-messenger_service.h   |     0
 .../messenger/gnunet-service-messenger_tunnel.c    |     0
 .../messenger/gnunet-service-messenger_tunnel.h    |     0
 src/service/messenger/meson.build                  |    69 +
 src/{ => service}/messenger/messenger.conf.in      |     0
 src/service/messenger/messenger_api.c              |  1075 ++
 src/service/messenger/messenger_api_contact.c      |   119 +
 src/service/messenger/messenger_api_contact.h      |   116 +
 .../messenger/messenger_api_contact_store.c        |   207 +
 .../messenger/messenger_api_contact_store.h        |   126 +
 src/service/messenger/messenger_api_ego.h          |    38 +
 src/service/messenger/messenger_api_handle.c       |   271 +
 src/service/messenger/messenger_api_handle.h       |   193 +
 .../messenger/messenger_api_list_tunnels.c         |     0
 .../messenger/messenger_api_list_tunnels.h         |     0
 src/service/messenger/messenger_api_message.c      |  1149 ++
 src/service/messenger/messenger_api_message.h      |   317 +
 src/service/messenger/messenger_api_message_kind.c |   190 +
 src/service/messenger/messenger_api_message_kind.h |   130 +
 .../messenger/messenger_api_peer_store.c           |     0
 .../messenger/messenger_api_peer_store.h           |     0
 .../messenger/messenger_api_queue_messages.c       |   108 +
 .../messenger/messenger_api_queue_messages.h       |    89 +
 src/{ => service}/messenger/messenger_api_room.c   |     0
 src/{ => service}/messenger/messenger_api_room.h   |     0
 src/service/messenger/messenger_api_util.c         |   127 +
 src/service/messenger/messenger_api_util.h         |    98 +
 .../messenger/plugin_gnsrecord_messenger.c         |     0
 src/service/messenger/test_messenger.c             |   217 +
 src/{ => service}/messenger/test_messenger_adapt.c |     0
 src/service/messenger/test_messenger_anonymous.c   |   190 +
 .../messenger/test_messenger_api.conf              |     0
 .../messenger/test_messenger_async_client.c        |     0
 .../messenger/test_messenger_async_p2p.c           |     0
 .../messenger/test_messenger_growth.c              |     0
 src/{ => service}/messenger/test_messenger_ring.c  |     0
 .../messenger/test_messenger_server.c              |     0
 .../messenger/test_messenger_sync_client.c         |     0
 .../messenger/test_messenger_sync_p2p.c            |     0
 .../messenger/test_messenger_worst_client.c        |     0
 .../messenger/test_messenger_worst_p2p.c           |     0
 .../messenger/testing_messenger_barrier.c          |     0
 .../messenger/testing_messenger_barrier.h          |     0
 .../messenger/testing_messenger_setup.c            |     0
 .../messenger/testing_messenger_setup.h            |     0
 src/service/namecache/.gitignore                   |     6 +
 src/service/namecache/Makefile.am                  |    76 +
 .../namecache/gnunet-service-namecache.c           |     0
 src/service/namecache/meson.build                  |    41 +
 src/{ => service}/namecache/namecache.conf.in      |     0
 src/{ => service}/namecache/namecache.h            |     0
 src/{ => service}/namecache/namecache_api.c        |     0
 .../namecache/test_namecache_api.conf              |     0
 .../namecache/test_namecache_api_cache_block.c     |   244 +
 src/service/namestore/.gitignore                   |    57 +
 src/service/namestore/Makefile.am                  |   410 +
 src/service/namestore/gnunet-namestore-fcfsd.c     |  1160 ++
 src/service/namestore/gnunet-service-namestore.c   |  2752 ++++
 src/service/namestore/meson.build                  |   116 +
 src/{ => service}/namestore/namestore.conf.in      |     0
 src/{ => service}/namestore/namestore.h            |     0
 src/service/namestore/namestore_api.c              |  1563 +++
 src/service/namestore/namestore_api_monitor.c      |   443 +
 src/service/namestore/perf_namestore_api_import.c  |   406 +
 .../namestore/perf_namestore_api_postgres.conf     |     0
 .../namestore/perf_namestore_api_sqlite.conf       |     0
 .../namestore/perf_namestore_api_zone_iteration.c  |   378 +
 src/{ => service}/namestore/test_common.c          |     0
 src/service/namestore/test_namestore_api.conf      |    43 +
 .../namestore/test_namestore_api_edit_records.c    |   399 +
 .../namestore/test_namestore_api_lookup_nick.c     |   347 +
 .../namestore/test_namestore_api_monitoring.c      |   378 +
 .../test_namestore_api_monitoring_existing.c       |   393 +
 .../namestore/test_namestore_api_postgres.conf     |     0
 src/service/namestore/test_namestore_api_remove.c  |   219 +
 ...test_namestore_api_remove_not_existing_record.c |   179 +
 .../namestore/test_namestore_api_sqlite.conf       |     0
 src/service/namestore/test_namestore_api_store.c   |   172 +
 .../namestore/test_namestore_api_store_update.c    |   260 +
 .../namestore/test_namestore_api_tx_rollback.c     |   264 +
 .../namestore/test_namestore_api_zone_iteration.c  |   464 +
 .../test_namestore_api_zone_iteration_nick.c       |   460 +
 ...st_namestore_api_zone_iteration_specific_zone.c |   447 +
 .../test_namestore_api_zone_iteration_stop.c       |   449 +
 .../namestore/test_namestore_api_zone_to_name.c    |   266 +
 src/service/nat-auto/.gitignore                    |     2 +
 src/service/nat-auto/Makefile.am                   |    40 +
 .../nat-auto/gnunet-nat-auto_legacy.c              |     0
 .../nat-auto/gnunet-service-nat-auto.c             |     0
 .../nat-auto/gnunet-service-nat-auto_legacy.c      |     0
 src/service/nat-auto/meson.build                   |    36 +
 src/{ => service}/nat-auto/nat-auto.conf.in        |     0
 src/{ => service}/nat-auto/nat-auto.h              |     0
 src/{ => service}/nat-auto/nat_auto_api.c          |     0
 src/{ => service}/nat-auto/nat_auto_api_test.c     |     0
 src/{ => service}/nat/.gitignore                   |     0
 src/service/nat/Makefile.am                        |   106 +
 src/{ => service}/nat/gnunet-helper-nat-client.c   |     0
 src/{ => service}/nat/gnunet-helper-nat-server.c   |     0
 src/{ => service}/nat/gnunet-nat-client-script.sh  |     0
 src/{ => service}/nat/gnunet-nat-server-script.sh  |     0
 src/service/nat/gnunet-service-nat.c               |  2083 +++
 src/{ => service}/nat/gnunet-service-nat.h         |     0
 .../nat/gnunet-service-nat_externalip.c            |     0
 .../nat/gnunet-service-nat_externalip.h            |     0
 src/{ => service}/nat/gnunet-service-nat_helper.c  |     0
 src/{ => service}/nat/gnunet-service-nat_helper.h  |     0
 src/{ => service}/nat/gnunet-service-nat_mini.c    |     0
 src/{ => service}/nat/gnunet-service-nat_mini.h    |     0
 src/{ => service}/nat/gnunet-service-nat_stun.c    |     0
 src/{ => service}/nat/gnunet-service-nat_stun.h    |     0
 src/service/nat/meson.build                        |    67 +
 src/{ => service}/nat/nat.conf.in                  |     0
 src/{ => service}/nat/nat.h                        |     0
 src/{ => service}/nat/nat_api.c                    |     0
 src/{ => service}/nat/nat_api_stun.c               |     0
 src/{ => service}/nat/nat_stun.h                   |     0
 src/{ => service}/nat/test_nat.c                   |     0
 src/{ => service}/nat/test_nat_data.conf           |     0
 src/{ => service}/nat/test_nat_mini.c              |     0
 src/{ => service}/nat/test_nat_test.c              |     0
 src/{ => service}/nat/test_nat_test_data.conf      |     0
 src/{ => service}/nat/test_stun.c                  |     0
 src/{ => service}/nat/test_stun.conf               |     0
 src/{ => service}/nse/.gitignore                   |     0
 src/service/nse/Makefile.am                        |    99 +
 src/{ => service}/nse/gnunet-nse-profiler.c        |     0
 src/service/nse/gnunet-service-nse.c               |  1587 +++
 src/{ => service}/nse/hostkeys.dat                 |   Bin
 src/service/nse/meson.build                        |    39 +
 src/{ => service}/nse/nse.conf.in                  |     0
 src/{ => service}/nse/nse.h                        |     0
 src/service/nse/nse_api.c                          |   208 +
 src/{ => service}/nse/nse_infiniband.conf          |     0
 src/{ => service}/nse/nse_profiler_test.conf       |     0
 src/{ => service}/nse/perf_kdf.c                   |     0
 src/{ => service}/nse/test_nse.conf                |     0
 src/{ => service}/nse/test_nse_api.c               |     0
 src/{ => service}/nse/test_nse_multipeer.c         |     0
 src/{ => service}/peerstore/.gitignore             |     0
 src/service/peerstore/Makefile.am                  |   102 +
 src/{ => service}/peerstore/gnunet-peerstore.c     |     0
 src/service/peerstore/gnunet-service-peerstore.c   |   734 +
 src/service/peerstore/meson.build                  |    39 +
 src/service/peerstore/peerstore.conf.in            |    14 +
 src/{ => service}/peerstore/peerstore.h            |     0
 src/service/peerstore/peerstore_api.c              |  1350 ++
 src/{ => service}/peerstore/peerstore_common.c     |     0
 src/{ => service}/peerstore/peerstore_common.h     |     0
 src/{ => service}/peerstore/perf_peerstore_store.c |     0
 .../peerstore/test_peerstore_api_data.conf         |     0
 .../peerstore/test_peerstore_api_iterate.c         |     0
 .../peerstore/test_peerstore_api_store.c           |     0
 .../peerstore/test_peerstore_api_sync.c            |     0
 .../peerstore/test_peerstore_api_watch.c           |     0
 src/{ => service}/pt/.gitignore                    |     0
 src/service/pt/Makefile.am                         |    93 +
 src/{ => service}/pt/gnunet-daemon-pt.c            |     0
 src/service/pt/meson.build                         |    18 +
 src/{ => service}/pt/pt.conf                       |     0
 src/service/pt/test_gns_vpn.c                      |   864 ++
 src/{ => service}/pt/test_gns_vpn.conf             |     0
 src/{ => service}/pt/test_gnunet_vpn.c             |     0
 src/{ => service}/pt/test_gnunet_vpn.conf          |     0
 src/{ => service}/reclaim/.gitignore               |     0
 src/service/reclaim/Makefile.am                    |   104 +
 src/service/reclaim/did.h                          |    49 +
 src/service/reclaim/did_core.c                     |   265 +
 src/{ => service}/reclaim/did_core.h               |     0
 src/service/reclaim/did_helper.c                   |   203 +
 src/service/reclaim/did_helper.h                   |    74 +
 src/service/reclaim/did_misc.c                     |    70 +
 src/service/reclaim/gnunet-service-reclaim.c       |  2814 ++++
 .../reclaim/gnunet-service-reclaim_tickets.c       |  1894 +++
 .../reclaim/gnunet-service-reclaim_tickets.h       |   280 +
 src/service/reclaim/meson.build                    |    65 +
 src/{ => service}/reclaim/reclaim.conf             |     0
 src/{ => service}/reclaim/reclaim.h                |     0
 src/service/reclaim/reclaim_api.c                  |  1813 +++
 src/{ => service}/reclaim/reclaim_attribute.c      |     0
 src/{ => service}/reclaim/reclaim_attribute.h      |     0
 src/{ => service}/reclaim/reclaim_credential.c     |     0
 src/{ => service}/reclaim/reclaim_credential.h     |     0
 src/service/reclaim/test_did_helper.c              |   137 +
 src/{ => service}/reclaim/test_reclaim.conf        |     0
 src/{ => service}/reclaim/test_reclaim_attribute.c |     0
 .../reclaim/test_reclaim_defaults.conf             |     0
 src/{ => service}/reclaim/test_w3c_ed25519_2020.c  |     0
 src/{ => service}/regex/.gitignore                 |     0
 src/service/regex/Makefile.am                      |   155 +
 src/service/regex/gnunet-daemon-regexprofiler.c    |   407 +
 src/{ => service}/regex/gnunet-regex-profiler.c    |     0
 .../regex/gnunet-regex-simulation-profiler.c       |     0
 src/{ => service}/regex/gnunet-service-regex.c     |     0
 src/service/regex/meson.build                      |    57 +
 src/{ => service}/regex/perf-data.tar.gz           |   Bin
 src/{ => service}/regex/perf-regex.c               |     0
 src/{ => service}/regex/regex.conf.in              |     0
 src/{ => service}/regex/regex_api_announce.c       |     0
 src/{ => service}/regex/regex_api_search.c         |     0
 src/{ => service}/regex/regex_internal.c           |     0
 src/{ => service}/regex/regex_internal.h           |     0
 src/service/regex/regex_internal_dht.c             |   828 ++
 src/service/regex/regex_internal_lib.h             |   268 +
 src/{ => service}/regex/regex_ipc.h                |     0
 .../regex/regex_simulation_profiler_test.conf      |     0
 src/{ => service}/regex/regex_test_graph.c         |     0
 src/{ => service}/regex/regex_test_lib.c           |     0
 src/{ => service}/regex/regex_test_lib.h           |     0
 src/{ => service}/regex/regex_test_random.c        |     0
 src/{ => service}/regex/test_regex_api.c           |     0
 src/{ => service}/regex/test_regex_api_data.conf   |     0
 src/{ => service}/regex/test_regex_eval_api.c      |     0
 src/{ => service}/regex/test_regex_graph_api.c     |     0
 src/{ => service}/regex/test_regex_integration.c   |     0
 src/{ => service}/regex/test_regex_iterate_api.c   |     0
 src/{ => service}/regex/test_regex_proofs.c        |     0
 src/{ => service}/rest/.gitignore                  |     0
 src/service/rest/Makefile.am                       |    75 +
 src/service/rest/config_plugin.c                   |   438 +
 src/service/rest/config_plugin.h                   |    37 +
 src/service/rest/copying_plugin.c                  |   233 +
 src/service/rest/copying_plugin.h                  |    36 +
 src/service/rest/gns_plugin.c                      |   486 +
 src/service/rest/gns_plugin.h                      |    36 +
 src/service/rest/gnunet-rest-server.c              |  1438 ++
 src/service/rest/identity_plugin.c                 |  1287 ++
 src/service/rest/identity_plugin.h                 |    36 +
 src/{reclaim => service/rest}/json_reclaim.c       |     0
 src/{reclaim => service/rest}/json_reclaim.h       |     0
 src/service/rest/meson.build                       |    61 +
 src/service/rest/namestore_plugin.c                |  1364 ++
 src/service/rest/namestore_plugin.h                |    37 +
 src/service/rest/oidc_helper.c                     |  1026 ++
 src/service/rest/oidc_helper.h                     |   196 +
 src/service/rest/openid_plugin.c                   |  3169 +++++
 src/service/rest/openid_plugin.h                   |    36 +
 .../rest/pabc_plugin.c}                            |     0
 src/service/rest/reclaim_plugin.c                  |  1566 +++
 src/service/rest/reclaim_plugin.h                  |    36 +
 src/{ => service}/rest/rest.c                      |     0
 src/{ => service}/rest/rest.conf                   |     0
 src/{ => service}/revocation/.gitignore            |     0
 src/service/revocation/Makefile.am                 |    74 +
 src/service/revocation/gnunet-service-revocation.c |  1066 ++
 src/service/revocation/meson.build                 |    44 +
 src/{ => service}/revocation/revocation.conf.in    |     0
 src/service/revocation/revocation.h                |   115 +
 src/service/revocation/revocation_api.c            |   334 +
 src/service/revocation/test_revocation.c           |   419 +
 src/{ => service}/revocation/test_revocation.conf  |     0
 .../revocation/test_revocation_testvectors.c       |   297 +
 src/{ => service}/seti/.gitignore                  |     0
 src/service/seti/Makefile.am                       |    72 +
 src/{ => service}/seti/gnunet-service-seti.c       |     0
 .../seti/gnunet-service-seti_protocol.h            |     0
 src/{ => service}/seti/gnunet-seti-profiler.c      |     0
 src/service/seti/meson.build                       |    41 +
 src/{ => service}/seti/seti.conf.in                |     0
 src/{ => service}/seti/seti.h                      |     0
 src/{ => service}/seti/seti_api.c                  |     0
 src/{ => service}/seti/test_seti.conf              |     0
 src/{ => service}/seti/test_seti_api.c             |     0
 src/{ => service}/setu/.gitignore                  |     0
 src/service/setu/Makefile.am                       |    92 +
 src/service/setu/gnunet-service-setu.c             |  5460 ++++++++
 .../setu/gnunet-service-setu_protocol.h            |     0
 .../setu/gnunet-service-setu_strata_estimator.c    |     0
 .../setu/gnunet-service-setu_strata_estimator.h    |     0
 src/{ => service}/setu/gnunet-setu-ibf-profiler.c  |     0
 src/{ => service}/setu/gnunet-setu-profiler.c      |     0
 src/{ => service}/setu/ibf.c                       |     0
 src/{ => service}/setu/ibf.h                       |     0
 src/{ => service}/setu/ibf_sim.c                   |     0
 src/service/setu/meson.build                       |    43 +
 src/{ => service}/setu/perf_setu_api.c             |     0
 src/{ => service}/setu/setu.conf.in                |     0
 src/{ => service}/setu/setu.h                      |     0
 src/{ => service}/setu/setu_api.c                  |     0
 src/{ => service}/setu/test_setu.conf              |     0
 src/{ => service}/setu/test_setu_api.c             |     0
 src/{ => service}/statistics/.gitignore            |     0
 src/service/statistics/Makefile.am                 |    89 +
 .../statistics/gnunet-service-statistics.c         |     0
 src/service/statistics/meson.build                 |    35 +
 src/{ => service}/statistics/statistics.conf.in    |     0
 src/{ => service}/statistics/statistics.h          |     0
 src/{ => service}/statistics/statistics_api.c      |     0
 .../statistics/test_gnunet_statistics.py.in        |     0
 src/{ => service}/statistics/test_statistics_api.c |     0
 .../statistics/test_statistics_api_data.conf       |     0
 .../statistics/test_statistics_api_loop.c          |     0
 .../statistics/test_statistics_api_watch.c         |     0
 .../test_statistics_api_watch_zero_value.c         |     0
 src/service/testing/.gitignore                     |     9 +
 src/service/testing/Makefile.am                    |   136 +
 src/{ => service}/testing/gnunet-cmds-helper.c     |     0
 src/{ => service}/testing/gnunet-testing.c         |     0
 src/{ => service}/testing/list-keys.c              |     0
 src/service/testing/meson.build                    |    64 +
 .../testing/test_testing_defaults.conf             |     0
 .../testing/test_testing_peerstartup.c             |     0
 .../testing/test_testing_peerstartup2.c            |     0
 .../testing/test_testing_portreservation.c         |     0
 .../testing/test_testing_servicestartup.c          |     0
 .../testing/test_testing_sharedservices.c          |     0
 .../testing/test_testing_sharedservices.conf       |     0
 .../testing/test_testing_start_with_config.c       |   121 +
 src/{ => service}/testing/testing.c                |     0
 src/{ => service}/testing/testing.conf             |     0
 src/{ => service}/testing/testing.h                |     0
 .../testing/testing_api_cmd_barrier.c              |     0
 .../testing/testing_api_cmd_barrier_reached.c      |   229 +
 src/{ => service}/testing/testing_api_cmd_batch.c  |     0
 .../testing_api_cmd_block_until_external_trigger.c |   119 +
 .../testing/testing_api_cmd_exec_bash_script.c     |   216 +
 src/{ => service}/testing/testing_api_cmd_finish.c |     0
 .../testing/testing_api_cmd_local_test_prepared.c  |     0
 .../testing/testing_api_cmd_netjail_start.c        |     0
 .../testing_api_cmd_netjail_start_cmds_helper.c    |   914 ++
 .../testing/testing_api_cmd_netjail_stop.c         |     0
 .../testing_api_cmd_netjail_stop_cmds_helper.c     |     0
 .../testing/testing_api_cmd_send_peer_ready.c      |     0
 src/service/testing/testing_api_cmd_start_peer.c   |   297 +
 src/service/testing/testing_api_cmd_stop_peer.c    |   130 +
 .../testing/testing_api_cmd_system_create.c        |     0
 .../testing/testing_api_cmd_system_destroy.c       |     0
 src/service/testing/testing_api_loop.c             |   930 ++
 src/{ => service}/testing/testing_api_traits.c     |     0
 src/{ => service}/testing/testing_cmds.h           |     0
 src/{ => service}/testing/topo.sh                  |     0
 src/{ => service}/topology/.gitignore              |     0
 src/service/topology/Makefile.am                   |    47 +
 src/service/topology/gnunet-daemon-topology.c      |  1062 ++
 src/service/topology/meson.build                   |    29 +
 .../topology/test_gnunet_daemon_topology.c         |     0
 .../topology/test_gnunet_daemon_topology_data.conf |     0
 src/service/topology/topology.conf                 |     5 +
 src/{ => service}/transport/.gitignore             |     0
 src/service/transport/Makefile.am                  |   460 +
 src/{ => service}/transport/NOTES                  |     0
 src/{ => service}/transport/benchmark.sh           |     0
 src/{ => service}/transport/communicator.h         |     0
 src/service/transport/gnunet-communicator-quic.c   |  1795 +++
 src/service/transport/gnunet-communicator-tcp.c    |  4083 ++++++
 src/service/transport/gnunet-communicator-udp.c    |  3444 +++++
 src/service/transport/gnunet-communicator-unix.c   |  1166 ++
 src/service/transport/gnunet-service-transport.c   | 11802 ++++++++++++++++
 .../transport/gnunet-service-transport.h           |     0
 .../gnunet-transport-certificate-creation.in       |     0
 src/{ => service}/transport/gnunet-transport.c     |     0
 src/{ => service}/transport/ieee80211_radiotap.h   |     0
 src/service/transport/meson.build                  |   261 +
 .../transport/template_cfg_peer1.conf              |     0
 .../transport/template_cfg_peer2.conf              |     0
 src/service/transport/template_tng_cfg_peer1.conf  |    34 +
 .../transport/test_communicator_basic.c            |     0
 .../test_communicator_quic_basic_peer1.conf        |     0
 .../test_communicator_quic_basic_peer2.conf        |     0
 .../test_communicator_tcp_basic_peer1.conf         |     0
 .../test_communicator_tcp_basic_peer2.conf         |     0
 .../test_communicator_tcp_bidirect_peer1.conf      |     0
 .../test_communicator_tcp_bidirect_peer2.conf      |     0
 .../test_communicator_tcp_rekey_peer1.conf         |     0
 .../test_communicator_tcp_rekey_peer2.conf         |     0
 .../test_communicator_udp_backchannel_peer1.conf   |     0
 .../test_communicator_udp_backchannel_peer2.conf   |     0
 .../test_communicator_udp_basic_peer1.conf         |     0
 .../test_communicator_udp_basic_peer2.conf         |     0
 .../test_communicator_udp_rekey_peer1.conf         |     0
 .../test_communicator_udp_rekey_peer2.conf         |     0
 .../test_communicator_unix_basic_peer1.conf        |     0
 .../test_communicator_unix_basic_peer2.conf        |     0
 src/{ => service}/transport/test_delay             |     0
 src/{ => service}/transport/test_plugin_hostkey    |   Bin
 .../transport/test_plugin_hostkey.ecc              |     0
 src/service/transport/test_tng_defaults.conf       |    14 +
 .../transport/test_transport_address_switch.c      |     0
 .../test_transport_address_switch_tcp_peer1.conf   |     0
 .../test_transport_address_switch_tcp_peer2.conf   |     0
 .../test_transport_address_switch_udp_peer1.conf   |     0
 .../test_transport_address_switch_udp_peer2.conf   |     0
 src/{ => service}/transport/test_transport_api.c   |     0
 src/{ => service}/transport/test_transport_api2.c  |     0
 .../transport/test_transport_api2_tcp_node1.conf   |    35 +
 .../transport/test_transport_api2_tcp_node2.conf   |    22 +
 .../transport/test_transport_api2_tcp_peer1.conf   |    23 +
 .../transport/test_transport_api2_tcp_peer2.conf   |    22 +
 .../transport/test_transport_api2_tng_node.conf    |    40 +
 .../transport/test_transport_api_data.conf         |     0
 .../transport/test_transport_api_monitor_peers.c   |     0
 .../test_transport_api_monitor_peers_peer1.conf    |     0
 .../test_transport_api_monitor_peers_peer2.conf    |     0
 ...est_transport_api_monitor_validation_peer1.conf |     0
 ...est_transport_api_monitor_validation_peer2.conf |     0
 .../transport/test_transport_api_multi_peer1.conf  |     0
 .../transport/test_transport_api_multi_peer2.conf  |     0
 .../test_transport_api_tcp_nat_peer1.conf          |     0
 .../test_transport_api_tcp_nat_peer2.conf          |     0
 .../transport/test_transport_api_tcp_peer1.conf    |     0
 .../transport/test_transport_api_tcp_peer2.conf    |     0
 .../test_transport_api_udp_nat_peer1.conf          |     0
 .../test_transport_api_udp_nat_peer2.conf          |     0
 .../transport/test_transport_api_udp_peer1.conf    |     0
 .../transport/test_transport_api_udp_peer2.conf    |     0
 .../transport/test_transport_api_unix_peer1.conf   |     0
 .../transport/test_transport_api_unix_peer2.conf   |     0
 .../transport/test_transport_defaults.conf         |     0
 ...test_transport_distance_vector_circle_topo.conf |     0
 ...est_transport_distance_vector_inverse_topo.conf |     0
 .../test_transport_distance_vector_topo.conf       |     0
 .../transport/test_transport_just_run_topo.conf    |     6 +
 .../transport/test_transport_nat_icmp_tcp.sh       |     0
 .../test_transport_nat_icmp_tcp_topo.conf          |     0
 .../transport/test_transport_nat_upnp.sh           |     0
 .../transport/test_transport_nat_upnp_topo.conf    |     0
 .../transport/test_transport_plugin_cmd_just_run.c |   494 +
 .../transport/test_transport_plugin_cmd_nat_upnp.c |   368 +
 .../test_transport_plugin_cmd_simple_send.c        |   377 +
 ...st_transport_plugin_cmd_simple_send_broadcast.c |   402 +
 .../test_transport_plugin_cmd_simple_send_dv.c     |   434 +
 ..._transport_plugin_cmd_simple_send_performance.c |   480 +
 .../test_transport_plugin_cmd_udp_backchannel.c    |   371 +
 .../transport/test_transport_simple_send.sh        |     0
 .../test_transport_simple_send_broadcast.sh        |     0
 .../test_transport_simple_send_broadcast_topo.conf |     0
 .../test_transport_simple_send_dv_circle.sh        |     0
 .../test_transport_simple_send_dv_inverse.sh       |     0
 .../test_transport_simple_send_performance.sh      |     0
 ...est_transport_simple_send_performance_topo.conf |     0
 .../transport/test_transport_simple_send_string.sh |     0
 .../transport/test_transport_simple_send_topo.conf |     0
 .../transport/test_transport_start_testcase.sh     |    12 +
 .../transport/test_transport_start_with_config.c   |   121 +
 ...rt_test_transport_address_switch_tcp_peer1.conf |     0
 ...rt_test_transport_address_switch_tcp_peer2.conf |     0
 .../transport/test_transport_testing_startstop.c   |     0
 .../transport/test_transport_udp_backchannel.sh    |     0
 .../test_transport_udp_backchannel_topo.conf       |     0
 src/service/transport/transport-testing-cmds.h     |   245 +
 .../transport/transport-testing-communicator.c     |  1238 ++
 .../transport/transport-testing-communicator.h     |   370 +
 .../transport/transport-testing-filenames2.c       |     0
 .../transport/transport-testing-loggers2.c         |     0
 .../transport/transport-testing-main2.c            |     0
 .../transport/transport-testing-send2.c            |     0
 src/service/transport/transport-testing2.c         |   871 ++
 src/service/transport/transport-testing2.h         |   940 ++
 src/service/transport/transport.conf.in            |    32 +
 src/service/transport/transport.h                  |   828 ++
 .../transport/transport_api2_application.c         |     0
 .../transport/transport_api2_communication.c       |  1114 ++
 src/service/transport/transport_api2_core.c        |   825 ++
 .../transport/transport_api2_monitor.c             |     0
 .../transport_api_cmd_backchannel_check.c          |   553 +
 .../transport/transport_api_cmd_connecting_peers.c |   309 +
 .../transport/transport_api_cmd_send_simple.c      |     0
 .../transport_api_cmd_send_simple_performance.c    |     0
 .../transport/transport_api_cmd_start_peer.c       |   483 +
 .../transport/transport_api_cmd_stop_peer.c        |   154 +
 src/{ => service}/transport/transport_api_traits.c |     0
 src/{ => service}/transport/upnp.sh                |     0
 src/service/util/.gitignore                        |     2 +
 src/service/util/Makefile.am                       |    50 +
 src/service/util/gnunet-service-resolver.c         |  1384 ++
 src/service/util/meson.build                       |    34 +
 src/{ => service}/util/resolver.conf.in            |     0
 src/service/util/test_resolver_api.c               |   378 +
 src/{ => service}/util/test_resolver_api_data.conf |     0
 src/{ => service}/vpn/.gitignore                   |     0
 src/service/vpn/Makefile.am                        |    53 +
 src/{ => service}/vpn/gnunet-helper-vpn.c          |     0
 src/{ => service}/vpn/gnunet-service-vpn.c         |     0
 src/service/vpn/meson.build                        |    52 +
 src/{ => service}/vpn/tests/expected               |   Bin
 src/{ => service}/vpn/tests/ping                   |   Bin
 src/{ => service}/vpn/tests/test-helper-icmp.sh    |     0
 src/{ => service}/vpn/tests/test-helper-ifaddr.sh  |     0
 src/{ => service}/vpn/vpn.conf.in                  |     0
 src/{ => service}/vpn/vpn.h                        |     0
 src/{ => service}/vpn/vpn_api.c                    |     0
 src/{ => service}/zonemaster/.gitignore            |     0
 src/service/zonemaster/Makefile.am                 |    32 +
 src/service/zonemaster/gnunet-service-zonemaster.c |  1469 ++
 src/service/zonemaster/meson.build                 |    29 +
 src/{ => service}/zonemaster/zonemaster.conf.in    |     0
 src/set/Makefile.am                                |   122 -
 src/seti/Makefile.am                               |    86 -
 src/setu/Makefile.am                               |   106 -
 src/setu/gnunet-service-setu.c                     |  5460 --------
 src/sq/Makefile.am                                 |    38 -
 src/sq/sq.c                                        |   131 -
 src/sq/sq_exec.c                                   |   113 -
 src/sq/sq_prepare.c                                |    77 -
 src/sq/test_sq.c                                   |   290 -
 src/statistics/Makefile.am                         |    98 -
 src/statistics/gnunet-statistics.c                 |   889 --
 src/template/Makefile.am                           |    48 -
 src/testbed-logger/.gitignore                      |     2 -
 src/testbed-logger/Makefile.am                     |    55 -
 src/testbed-logger/gnunet-service-testbed-logger.c |   236 -
 src/testbed-logger/test_testbed_logger_api.c       |   277 -
 src/testbed-logger/test_testbed_logger_api.conf    |     6 -
 src/testbed-logger/testbed-logger.conf.in          |   127 -
 src/testbed-logger/testbed_logger_api.c            |   338 -
 src/testbed/.gitignore                             |    37 -
 src/testbed/Makefile.am                            |   401 -
 src/testbed/barriers.README.org                    |    95 -
 src/testbed/buildvars.py.in                        |    34 -
 src/testbed/generate-underlay-topology.c           |   407 -
 src/testbed/gnunet-daemon-latency-logger.c         |   322 -
 src/testbed/gnunet-daemon-testbed-blacklist.c      |   254 -
 src/testbed/gnunet-daemon-testbed-underlay.c       |   481 -
 src/testbed/gnunet-helper-testbed-valgrind.patch   |    21 -
 src/testbed/gnunet-helper-testbed.c                |   613 -
 src/testbed/gnunet-service-test-barriers.c         |   152 -
 src/testbed/gnunet-service-testbed.c               |   981 --
 src/testbed/gnunet-service-testbed.h               |   899 --
 src/testbed/gnunet-service-testbed_barriers.c      |   929 --
 src/testbed/gnunet-service-testbed_barriers.h      |   128 -
 src/testbed/gnunet-service-testbed_cache.c         |   270 -
 .../gnunet-service-testbed_connectionpool.c        |  1045 --
 .../gnunet-service-testbed_connectionpool.h        |   172 -
 src/testbed/gnunet-service-testbed_cpustatus.c     |   664 -
 src/testbed/gnunet-service-testbed_links.c         |  1468 --
 src/testbed/gnunet-service-testbed_links.h         |   209 -
 src/testbed/gnunet-service-testbed_meminfo.c       |   279 -
 src/testbed/gnunet-service-testbed_meminfo.h       |    55 -
 src/testbed/gnunet-service-testbed_oc.c            |  1997 ---
 src/testbed/gnunet-service-testbed_peers.c         |  1552 ---
 src/testbed/gnunet-testbed-profiler.c              |   323 -
 src/testbed/gnunet_mpi_test.c                      |   108 -
 src/testbed/misc.supp                              |    49 -
 src/testbed/overlay_topology.txt                   |     5 -
 src/testbed/profile-testbed.patch                  |    43 -
 src/testbed/sample.job                             |    16 -
 src/testbed/sample_hosts.txt                       |     7 -
 src/testbed/test-underlay.sqlite                   |   Bin 3072 -> 0 bytes
 src/testbed/test_gnunet_helper_testbed.c           |   255 -
 src/testbed/test_testbed_api.c                     |   515 -
 src/testbed/test_testbed_api.conf                  |     1 -
 src/testbed/test_testbed_api_2peers_1controller.c  |   540 -
 src/testbed/test_testbed_api_3peers_3controllers.c |   964 --
 src/testbed/test_testbed_api_barriers.c            |   234 -
 src/testbed/test_testbed_api_barriers.conf.in      |   103 -
 src/testbed/test_testbed_api_barriers.h            |     4 -
 src/testbed/test_testbed_api_controllerlink.c      |   881 --
 src/testbed/test_testbed_api_hosts.c               |   183 -
 src/testbed/test_testbed_api_operations.c          |   568 -
 .../test_testbed_api_peer_reconfiguration.c        |   194 -
 .../test_testbed_api_peers_manage_services.c       |   216 -
 src/testbed/test_testbed_api_sd.c                  |   111 -
 src/testbed/test_testbed_api_statistics.c          |   205 -
 src/testbed/test_testbed_api_statistics.conf       |     9 -
 src/testbed/test_testbed_api_template.conf         |    49 -
 src/testbed/test_testbed_api_test.c                |   251 -
 src/testbed/test_testbed_api_test_timeout.c        |   126 -
 src/testbed/test_testbed_api_test_timeout.conf     |     5 -
 src/testbed/test_testbed_api_testbed_run.c         |   242 -
 ...st_testbed_api_testbed_run_topology2dtorus.conf |     5 -
 ...est_testbed_api_testbed_run_topologyclique.conf |     4 -
 ...t_testbed_api_testbed_run_topologyfromfile.conf |     5 -
 .../test_testbed_api_testbed_run_topologyline.conf |     4 -
 ...est_testbed_api_testbed_run_topologyrandom.conf |     5 -
 .../test_testbed_api_testbed_run_topologyring.conf |     4 -
 ..._testbed_api_testbed_run_topologyscalefree.conf |     6 -
 ...testbed_api_testbed_run_topologysmallworld.conf |     5 -
 ...bed_api_testbed_run_topologysmallworldring.conf |     5 -
 .../test_testbed_api_testbed_run_topologystar.conf |     4 -
 src/testbed/test_testbed_api_topology.c            |   189 -
 src/testbed/test_testbed_api_topology_clique.c     |   185 -
 src/testbed/test_testbed_underlay.c                |   174 -
 src/testbed/test_testbed_underlay.conf.in          |    13 -
 src/testbed/testbed.conf.in                        |   116 -
 src/testbed/testbed.h                              |   866 --
 src/testbed/testbed_api.c                          |  2427 ----
 src/testbed/testbed_api.h                          |   521 -
 src/testbed/testbed_api_barriers.c                 |   253 -
 src/testbed/testbed_api_hosts.c                    |  1521 ---
 src/testbed/testbed_api_hosts.h                    |   227 -
 src/testbed/testbed_api_operations.c               |  1379 --
 src/testbed/testbed_api_operations.h               |   233 -
 src/testbed/testbed_api_peers.c                    |   961 --
 src/testbed/testbed_api_peers.h                    |   311 -
 src/testbed/testbed_api_sd.c                       |   213 -
 src/testbed/testbed_api_sd.h                       |    81 -
 src/testbed/testbed_api_services.c                 |   291 -
 src/testbed/testbed_api_statistics.c               |   435 -
 src/testbed/testbed_api_test.c                     |   175 -
 src/testbed/testbed_api_testbed.c                  |  1467 --
 src/testbed/testbed_api_topology.c                 |  1598 ---
 src/testbed/testbed_api_topology.h                 |   115 -
 src/testbed/testbed_api_underlay.c                 |   260 -
 src/testbed/testbed_helper.h                       |    89 -
 src/testbed/valgrind-zlib.supp                     |     6 -
 src/testbed/x64_misc.supp                          |    34 -
 src/testing/.gitignore                             |     8 -
 src/testing/Makefile.am                            |   125 -
 src/testing/testing_api_cmd_barrier_reached.c      |   229 -
 .../testing_api_cmd_block_until_external_trigger.c |   119 -
 .../testing_api_cmd_netjail_start_cmds_helper.c    |   913 --
 src/testing/testing_api_loop.c                     |   937 --
 src/topology/Makefile.am                           |    61 -
 src/topology/friends.c                             |   246 -
 src/topology/gnunet-daemon-topology.c              |  1155 --
 src/topology/topology.conf                         |     8 -
 src/transport/Makefile.am                          |  1728 ---
 src/transport/communicator-unix.conf               |     2 -
 src/transport/gnunet-communicator-quic.c           |  1796 ---
 src/transport/gnunet-communicator-tcp.c            |  4085 ------
 src/transport/gnunet-communicator-udp.c            |  3449 -----
 src/transport/gnunet-communicator-unix.c           |  1167 --
 src/transport/gnunet-helper-transport-bluetooth.c  |  2286 ----
 src/transport/gnunet-helper-transport-wlan-dummy.c |   520 -
 src/transport/gnunet-helper-transport-wlan.c       |  2165 ---
 src/transport/gnunet-service-tng.c                 | 11613 ----------------
 src/transport/gnunet-service-transport.c           |  2778 ----
 src/transport/gnunet-service-transport_ats.c       |   906 --
 src/transport/gnunet-service-transport_ats.h       |   203 -
 src/transport/gnunet-service-transport_hello.c     |   358 -
 src/transport/gnunet-service-transport_hello.h     |   102 -
 .../gnunet-service-transport_manipulation.c        |   586 -
 .../gnunet-service-transport_manipulation.h        |   121 -
 .../gnunet-service-transport_neighbours.c          |  3947 ------
 .../gnunet-service-transport_neighbours.h          |   321 -
 src/transport/gnunet-service-transport_plugins.c   |   437 -
 src/transport/gnunet-service-transport_plugins.h   |   107 -
 .../gnunet-service-transport_validation.c          |  1819 ---
 .../gnunet-service-transport_validation.h          |   146 -
 src/transport/gnunet-transport-profiler.c          |   625 -
 src/transport/gnunet-transport-wlan-receiver.c     |   114 -
 src/transport/gnunet-transport-wlan-sender.c       |   251 -
 src/transport/perf_http_peer1.conf                 |    37 -
 src/transport/perf_http_peer2.conf                 |    40 -
 src/transport/perf_https_peer1.conf                |    37 -
 src/transport/perf_https_peer2.conf                |    40 -
 src/transport/perf_tcp_peer1.conf                  |    31 -
 src/transport/perf_tcp_peer2.conf                  |    34 -
 src/transport/perf_udp_peer1.conf                  |    43 -
 src/transport/perf_udp_peer2.conf                  |    48 -
 src/transport/perf_unix_peer1.conf                 |    52 -
 src/transport/perf_unix_peer2.conf                 |    56 -
 src/transport/plugin_transport_http.h              |   579 -
 src/transport/plugin_transport_http_client.c       |  2523 ----
 src/transport/plugin_transport_http_common.c       |   903 --
 src/transport/plugin_transport_http_common.h       |   272 -
 src/transport/plugin_transport_http_server.c       |  3603 -----
 src/transport/plugin_transport_smtp.c              |   750 --
 src/transport/plugin_transport_tcp.c               |  3967 ------
 src/transport/plugin_transport_template.c          |   565 -
 src/transport/plugin_transport_udp.c               |  3897 ------
 src/transport/plugin_transport_udp.h               |   355 -
 src/transport/plugin_transport_udp_broadcasting.c  |   647 -
 src/transport/plugin_transport_unix.c              |  1890 ---
 src/transport/plugin_transport_wlan.c              |  2405 ----
 src/transport/plugin_transport_wlan.h              |   276 -
 src/transport/profile_transport.sh                 |    18 -
 src/transport/tcp_connection_legacy.c              |  1597 ---
 src/transport/tcp_server_legacy.c                  |  1728 ---
 src/transport/tcp_server_mst_legacy.c              |   307 -
 src/transport/tcp_service_legacy.c                 |  1646 ---
 src/transport/test_http_common.c                   |   266 -
 src/transport/test_plugin_transport.c              |   797 --
 src/transport/test_plugin_transport_data.conf      |    47 -
 src/transport/test_plugin_transport_data_udp.conf  |     1 -
 src/transport/test_quota_compliance.c              |   321 -
 ...uota_compliance_bluetooth_asymmetric_peer1.conf |    12 -
 ...uota_compliance_bluetooth_asymmetric_peer2.conf |    11 -
 .../test_quota_compliance_bluetooth_peer1.conf     |    30 -
 .../test_quota_compliance_bluetooth_peer2.conf     |    29 -
 src/transport/test_quota_compliance_data.conf      |    24 -
 ...est_quota_compliance_http_asymmetric_peer1.conf |    28 -
 ...est_quota_compliance_http_asymmetric_peer2.conf |    32 -
 .../test_quota_compliance_http_peer1.conf          |    28 -
 .../test_quota_compliance_http_peer2.conf          |    32 -
 ...st_quota_compliance_https_asymmetric_peer1.conf |    28 -
 ...st_quota_compliance_https_asymmetric_peer2.conf |    31 -
 .../test_quota_compliance_https_peer1.conf         |    28 -
 .../test_quota_compliance_https_peer2.conf         |    31 -
 ...test_quota_compliance_tcp_asymmetric_peer1.conf |    32 -
 ...test_quota_compliance_tcp_asymmetric_peer2.conf |    29 -
 src/transport/test_quota_compliance_tcp_peer1.conf |    32 -
 src/transport/test_quota_compliance_tcp_peer2.conf |    29 -
 src/transport/test_quota_compliance_udp_peer1.conf |    29 -
 src/transport/test_quota_compliance_udp_peer2.conf |    30 -
 ...est_quota_compliance_unix_asymmetric_peer1.conf |    28 -
 ...est_quota_compliance_unix_asymmetric_peer2.conf |    28 -
 .../test_quota_compliance_unix_peer1.conf          |    27 -
 .../test_quota_compliance_unix_peer2.conf          |    31 -
 ...est_quota_compliance_wlan_asymmetric_peer1.conf |    29 -
 ...est_quota_compliance_wlan_asymmetric_peer2.conf |    29 -
 .../test_quota_compliance_wlan_peer1.conf          |    29 -
 .../test_quota_compliance_wlan_peer2.conf          |    29 -
 .../test_transport_address_switch_http_peer1.conf  |    26 -
 .../test_transport_address_switch_http_peer2.conf  |    26 -
 .../test_transport_address_switch_https_peer1.conf |    44 -
 .../test_transport_address_switch_https_peer2.conf |    44 -
 src/transport/test_transport_api2_tcp_node1.conf   |    35 -
 src/transport/test_transport_api2_tcp_node2.conf   |    22 -
 src/transport/test_transport_api2_tcp_peer1.conf   |    23 -
 src/transport/test_transport_api2_tcp_peer2.conf   |    22 -
 src/transport/test_transport_api_blacklisting.c    |   206 -
 .../test_transport_api_blacklisting_tcp_peer1.conf |     9 -
 .../test_transport_api_blacklisting_tcp_peer2.conf |     9 -
 .../test_transport_api_bluetooth_peer1.conf        |    10 -
 .../test_transport_api_bluetooth_peer2.conf        |    10 -
 src/transport/test_transport_api_disconnect.c      |   134 -
 .../test_transport_api_disconnect_tcp_peer1.conf   |     7 -
 .../test_transport_api_disconnect_tcp_peer2.conf   |     8 -
 src/transport/test_transport_api_http_peer1.conf   |     6 -
 src/transport/test_transport_api_http_peer2.conf   |     6 -
 .../test_transport_api_http_reverse_peer1.conf     |    11 -
 .../test_transport_api_http_reverse_peer2.conf     |    12 -
 src/transport/test_transport_api_https_peer1.conf  |    26 -
 src/transport/test_transport_api_https_peer2.conf  |    32 -
 src/transport/test_transport_api_limited_sockets.c |   132 -
 ...st_transport_api_limited_sockets_tcp_peer1.conf |     7 -
 ...st_transport_api_limited_sockets_tcp_peer2.conf |     8 -
 .../test_transport_api_manipulation_cfg.c          |   186 -
 .../test_transport_api_manipulation_cfg_peer1.conf |     8 -
 .../test_transport_api_manipulation_cfg_peer2.conf |     8 -
 .../test_transport_api_manipulation_recv_tcp.c     |   203 -
 ..._transport_api_manipulation_recv_tcp_peer1.conf |    29 -
 ..._transport_api_manipulation_recv_tcp_peer2.conf |    29 -
 .../test_transport_api_manipulation_send_tcp.c     |   199 -
 ..._transport_api_manipulation_send_tcp_peer1.conf |    29 -
 ..._transport_api_manipulation_send_tcp_peer2.conf |    29 -
 src/transport/test_transport_api_reliability.c     |   321 -
 ..._transport_api_reliability_bluetooth_peer1.conf |    33 -
 ..._transport_api_reliability_bluetooth_peer2.conf |    32 -
 .../test_transport_api_reliability_http_peer1.conf |    33 -
 .../test_transport_api_reliability_http_peer2.conf |    30 -
 ...t_transport_api_reliability_http_xhr_peer1.conf |    34 -
 ...t_transport_api_reliability_http_xhr_peer2.conf |    30 -
 ...test_transport_api_reliability_https_peer1.conf |    27 -
 ...test_transport_api_reliability_https_peer2.conf |    31 -
 ..._transport_api_reliability_https_xhr_peer1.conf |    28 -
 ..._transport_api_reliability_https_xhr_peer2.conf |    31 -
 ...st_transport_api_reliability_tcp_nat_peer1.conf |    35 -
 ...st_transport_api_reliability_tcp_nat_peer2.conf |    34 -
 .../test_transport_api_reliability_tcp_peer1.conf  |    29 -
 .../test_transport_api_reliability_tcp_peer2.conf  |    28 -
 .../test_transport_api_reliability_udp_peer1.conf  |    29 -
 .../test_transport_api_reliability_udp_peer2.conf  |    29 -
 .../test_transport_api_reliability_unix_peer1.conf |    28 -
 .../test_transport_api_reliability_unix_peer2.conf |    28 -
 .../test_transport_api_reliability_wlan_peer1.conf |    31 -
 .../test_transport_api_reliability_wlan_peer2.conf |    32 -
 .../test_transport_api_restart_1peer_peer1.conf    |     9 -
 .../test_transport_api_restart_1peer_peer2.conf    |     9 -
 .../test_transport_api_restart_2peers_peer1.conf   |     9 -
 .../test_transport_api_restart_2peers_peer2.conf   |     9 -
 .../test_transport_api_restart_reconnect.c         |   217 -
 .../test_transport_api_slow_ats_peer1.conf         |     7 -
 .../test_transport_api_slow_ats_peer2.conf         |     9 -
 src/transport/test_transport_api_timeout.c         |   164 -
 ...test_transport_api_timeout_bluetooth_peer1.conf |    35 -
 ...test_transport_api_timeout_bluetooth_peer2.conf |    34 -
 .../test_transport_api_timeout_http_peer1.conf     |    28 -
 .../test_transport_api_timeout_http_peer2.conf     |    31 -
 .../test_transport_api_timeout_https_peer1.conf    |    25 -
 .../test_transport_api_timeout_https_peer2.conf    |    31 -
 .../test_transport_api_timeout_tcp_peer1.conf      |    30 -
 .../test_transport_api_timeout_tcp_peer2.conf      |    32 -
 .../test_transport_api_timeout_udp_peer1.conf      |    33 -
 .../test_transport_api_timeout_udp_peer2.conf      |    31 -
 .../test_transport_api_timeout_unix_peer1.conf     |    28 -
 .../test_transport_api_timeout_unix_peer2.conf     |    28 -
 .../test_transport_api_timeout_wlan_peer1.conf     |    35 -
 .../test_transport_api_timeout_wlan_peer2.conf     |    34 -
 .../test_transport_api_unix_abstract_peer1.conf    |    31 -
 .../test_transport_api_unix_abstract_peer2.conf    |    31 -
 ...ransport_api_unreliability_bluetooth_peer1.conf |    30 -
 ...ransport_api_unreliability_bluetooth_peer2.conf |    29 -
 ...sport_api_unreliability_constant_udp_peer1.conf |    30 -
 ...sport_api_unreliability_constant_udp_peer2.conf |    30 -
 ...est_transport_api_unreliability_wlan_peer1.conf |    29 -
 ...est_transport_api_unreliability_wlan_peer2.conf |    29 -
 src/transport/test_transport_api_wlan_peer1.conf   |    35 -
 src/transport/test_transport_api_wlan_peer2.conf   |    34 -
 src/transport/test_transport_blacklisting.c        |   582 -
 ..._transport_blacklisting_cfg_blp_peer1_full.conf |    16 -
 ...lacklisting_cfg_blp_peer1_multiple_plugins.conf |    13 -
 ...ransport_blacklisting_cfg_blp_peer1_plugin.conf |    13 -
 ..._transport_blacklisting_cfg_blp_peer2_full.conf |    12 -
 ...lacklisting_cfg_blp_peer2_multiple_plugins.conf |    12 -
 ...ransport_blacklisting_cfg_blp_peer2_plugin.conf |    12 -
 .../test_transport_blacklisting_cfg_peer1.conf     |    29 -
 .../test_transport_blacklisting_cfg_peer2.conf     |    28 -
 src/transport/test_transport_plugin_cmd_nat_upnp.c |   405 -
 .../test_transport_plugin_cmd_simple_send.c        |   376 -
 ...st_transport_plugin_cmd_simple_send_broadcast.c |   402 -
 .../test_transport_plugin_cmd_simple_send_dv.c     |   433 -
 ..._transport_plugin_cmd_simple_send_performance.c |   517 -
 .../test_transport_plugin_cmd_udp_backchannel.c    |   370 -
 src/transport/test_transport_start_with_config.c   |   122 -
 src/transport/test_transport_testing_restart.c     |   163 -
 src/transport/transport-testing-cmds.h             |   412 -
 src/transport/transport-testing-communicator.c     |  1239 --
 src/transport/transport-testing-communicator.h     |   370 -
 src/transport/transport-testing-filenames.c        |   175 -
 src/transport/transport-testing-loggers.c          |    81 -
 src/transport/transport-testing-main.c             |   614 -
 src/transport/transport-testing-send.c             |   241 -
 src/transport/transport-testing.c                  |   932 --
 src/transport/transport-testing.h                  |   914 --
 src/transport/transport-testing2.c                 |   930 --
 src/transport/transport-testing2.h                 |   947 --
 src/transport/transport.conf.in                    |   241 -
 src/transport/transport.h                          |  1251 --
 src/transport/transport_api2_communication.c       |  1115 --
 src/transport/transport_api2_core.c                |   822 --
 src/transport/transport_api_address_to_string.c    |   264 -
 src/transport/transport_api_blacklist.c            |   197 -
 .../transport_api_cmd_backchannel_check.c          |   555 -
 src/transport/transport_api_cmd_connecting_peers.c |   288 -
 src/transport/transport_api_cmd_start_peer.c       |   483 -
 src/transport/transport_api_cmd_stop_peer.c        |   154 -
 src/transport/transport_api_core.c                 |   968 --
 src/transport/transport_api_hello_get.c            |   274 -
 src/transport/transport_api_manipulation.c         |   249 -
 src/transport/transport_api_monitor_peers.c        |   443 -
 src/transport/transport_api_monitor_plugins.c      |   463 -
 src/transport/transport_api_offer_hello.c          |   137 -
 src/util/.gitignore                                |    90 -
 src/util/Makefile.am                               |   696 -
 src/util/bio.c                                     |  1380 --
 src/util/configuration.c                           |  2576 ----
 src/util/container_heap.c                          |   501 -
 src/util/container_multihashmap.c                  |   974 --
 src/util/container_multihashmap32.c                |   606 -
 src/util/container_multipeermap.c                  |   895 --
 src/util/container_multishortmap.c                 |   904 --
 src/util/container_multiuuidmap.c                  |   902 --
 src/util/crypto_cs.c                               |   344 -
 src/util/crypto_ecc.c                              |   971 --
 src/util/crypto_ecc_gnsrecord.c                    |   453 -
 src/util/crypto_rsa.c                              |  1263 --
 src/util/gnunet-crypto-tvg.c                       |  1555 ---
 src/util/gnunet-service-resolver.c                 |  1384 --
 src/util/helper.c                                  |   673 -
 src/util/network.c                                 |  1311 --
 src/util/os_network.c                              |   444 -
 src/util/os_priority.c                             |  1057 --
 src/util/perf_crypto_rsa.c                         |   213 -
 src/util/program.c                                 |   419 -
 src/util/service.c                                 |  2449 ----
 src/util/strings.c                                 |  1994 ---
 src/util/test_crypto_cs.c                          |   610 -
 src/util/test_crypto_rsa.c                         |   149 -
 src/util/test_os_network.c                         |    92 -
 src/util/test_resolver_api.c                       |   378 -
 src/vpn/Makefile.am                                |    63 -
 src/zonemaster/Makefile.am                         |    32 -
 src/zonemaster/gnunet-service-zonemaster.c         |  1469 --
 2421 files changed, 273386 insertions(+), 408377 deletions(-)

diff --cc po/POTFILES.in
index be88491cc,1357925d0..82fd70f3c
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@@ -1,604 -1,501 +1,507 @@@
- src/abd/abd_api.c
- src/abd/abd_serialization.c
- src/abd/delegate_misc.c
- src/abd/gnunet-abd.c
- src/abd/gnunet-service-abd.c
- src/abd/plugin_gnsrecord_abd.c
- src/arm/arm_api.c
- src/arm/arm_monitor_api.c
- src/arm/gnunet-arm.c
- src/arm/gnunet-service-arm.c
- src/arm/mockup-service.c
- src/ats-tool/gnunet-ats.c
- src/ats/ats_api_connectivity.c
- src/ats/ats_api_performance.c
- src/ats/ats_api_scanner.c
- src/ats/ats_api_scheduling.c
- src/ats/gnunet-ats-solver-eval.c
- src/ats/gnunet-service-ats.c
- src/ats/gnunet-service-ats_addresses.c
- src/ats/gnunet-service-ats_connectivity.c
- src/ats/gnunet-service-ats_normalization.c
- src/ats/gnunet-service-ats_performance.c
- src/ats/gnunet-service-ats_plugins.c
- src/ats/gnunet-service-ats_preferences.c
- src/ats/gnunet-service-ats_reservations.c
- src/ats/gnunet-service-ats_scheduling.c
- src/ats/plugin_ats_proportional.c
- src/auction/gnunet-auction-create.c
- src/auction/gnunet-auction-info.c
- src/auction/gnunet-auction-join.c
- src/auction/gnunet-service-auction.c
- src/block/bg_bf.c
- src/block/block.c
- src/block/plugin_block_template.c
- src/block/plugin_block_test.c
- src/cadet/cadet_api.c
- src/cadet/cadet_api_drop_message.c
- src/cadet/cadet_api_get_channel.c
- src/cadet/cadet_api_get_path.c
- src/cadet/cadet_api_helper.c
- src/cadet/cadet_api_list_peers.c
- src/cadet/cadet_api_list_tunnels.c
- src/cadet/cadet_test_lib.c
- src/cadet/desirability_table.c
- src/cadet/gnunet-cadet-profiler.c
- src/cadet/gnunet-cadet.c
- src/cadet/gnunet-service-cadet.c
- src/cadet/gnunet-service-cadet_channel.c
- src/cadet/gnunet-service-cadet_connection.c
- src/cadet/gnunet-service-cadet_core.c
- src/cadet/gnunet-service-cadet_dht.c
- src/cadet/gnunet-service-cadet_hello.c
- src/cadet/gnunet-service-cadet_paths.c
- src/cadet/gnunet-service-cadet_peer.c
- src/cadet/gnunet-service-cadet_tunnels.c
- src/consensus/consensus_api.c
- src/consensus/gnunet-consensus-profiler.c
- src/consensus/gnunet-service-consensus.c
- src/consensus/plugin_block_consensus.c
- src/conversation/conversation_api.c
- src/conversation/conversation_api_call.c
- src/conversation/gnunet-conversation-test.c
- src/conversation/gnunet-conversation.c
- src/conversation/gnunet-helper-audio-playback-gst.c
- src/conversation/gnunet-helper-audio-playback.c
- src/conversation/gnunet-helper-audio-record-gst.c
- src/conversation/gnunet-helper-audio-record.c
- src/conversation/gnunet-service-conversation.c
- src/conversation/gnunet_gst.c
- src/conversation/gnunet_gst_test.c
- src/conversation/microphone.c
- src/conversation/plugin_gnsrecord_conversation.c
- src/conversation/speaker.c
- src/core/core_api.c
- src/core/core_api_monitor_peers.c
- src/core/gnunet-core.c
- src/core/gnunet-service-core.c
- src/core/gnunet-service-core_kx.c
- src/core/gnunet-service-core_sessions.c
- src/core/gnunet-service-core_typemap.c
- src/curl/curl.c
- src/curl/curl_reschedule.c
- src/datacache/datacache.c
- src/datacache/plugin_datacache_heap.c
- src/datacache/plugin_datacache_postgres.c
- src/datacache/plugin_datacache_sqlite.c
- src/datacache/plugin_datacache_template.c
- src/datastore/datastore_api.c
- src/datastore/gnunet-datastore.c
- src/datastore/gnunet-service-datastore.c
- src/datastore/plugin_datastore_heap.c
- src/datastore/plugin_datastore_mysql.c
- src/datastore/plugin_datastore_postgres.c
- src/datastore/plugin_datastore_sqlite.c
- src/datastore/plugin_datastore_template.c
- src/dht/dht_api.c
- src/dht/dht_test_lib.c
- src/dht/gnunet-dht-get.c
- src/dht/gnunet-dht-hello.c
- src/dht/gnunet-dht-monitor.c
- src/dht/gnunet-dht-put.c
- src/dht/gnunet-service-dht.c
- src/dht/gnunet-service-dht_clients.c
- src/dht/gnunet-service-dht_datacache.c
- src/dht/gnunet-service-dht_neighbours.c
- src/dht/gnunet-service-dht_routing.c
- src/dht/gnunet_dht_profiler.c
- src/dht/plugin_block_dht.c
- src/dhtu/plugin_dhtu_gnunet.c
- src/dhtu/plugin_dhtu_ip.c
- src/dhtu/testing_dhtu_cmd_send.c
- src/dns/dns_api.c
- src/dns/gnunet-dns-monitor.c
- src/dns/gnunet-dns-redirector.c
- src/dns/gnunet-helper-dns.c
- src/dns/gnunet-service-dns.c
- src/dns/gnunet-zonewalk.c
- src/dns/plugin_block_dns.c
- src/exit/gnunet-daemon-exit.c
- src/exit/gnunet-helper-exit.c
- src/fragmentation/defragmentation.c
- src/fragmentation/fragmentation.c
- src/fs/fs_api.c
- src/fs/fs_directory.c
- src/fs/fs_dirmetascan.c
- src/fs/fs_download.c
- src/fs/fs_file_information.c
- src/fs/fs_getopt.c
- src/fs/fs_list_indexed.c
- src/fs/fs_misc.c
- src/fs/fs_namespace.c
- src/fs/fs_publish.c
- src/fs/fs_publish_ksk.c
- src/fs/fs_publish_ublock.c
- src/fs/fs_search.c
- src/fs/fs_sharetree.c
- src/fs/fs_test_lib.c
- src/fs/fs_tree.c
- src/fs/fs_unindex.c
- src/fs/fs_uri.c
- src/fs/gnunet-auto-share.c
- src/fs/gnunet-daemon-fsprofiler.c
- src/fs/gnunet-directory.c
- src/fs/gnunet-download.c
- src/fs/gnunet-fs-profiler.c
- src/fs/gnunet-fs.c
- src/fs/gnunet-helper-fs-publish.c
- src/fs/gnunet-publish.c
- src/fs/gnunet-search.c
- src/fs/gnunet-service-fs.c
- src/fs/gnunet-service-fs_cadet_client.c
- src/fs/gnunet-service-fs_cadet_server.c
- src/fs/gnunet-service-fs_cp.c
- src/fs/gnunet-service-fs_indexing.c
- src/fs/gnunet-service-fs_pe.c
- src/fs/gnunet-service-fs_pr.c
- src/fs/gnunet-service-fs_push.c
- src/fs/gnunet-service-fs_put.c
- src/fs/gnunet-unindex.c
- src/fs/meta_data.c
- src/fs/plugin_block_fs.c
- src/gns/gns_api.c
- src/gns/gns_tld_api.c
- src/gns/gnunet-bcd.c
- src/gns/gnunet-dns2gns.c
- src/gns/gnunet-gns-benchmark.c
- src/gns/gnunet-gns-import.c
- src/gns/gnunet-gns-proxy.c
- src/gns/gnunet-gns.c
- src/gns/gnunet-service-gns.c
- src/gns/gnunet-service-gns_interceptor.c
- src/gns/gnunet-service-gns_resolver.c
- src/gns/nss/nss_gns.c
- src/gns/nss/nss_gns_query.c
- src/gns/plugin_block_gns.c
- src/gns/plugin_gnsrecord_gns.c
- src/gns/plugin_rest_gns.c
- src/gnsrecord/gnsrecord.c
- src/gnsrecord/gnsrecord_crypto.c
- src/gnsrecord/gnsrecord_misc.c
- src/gnsrecord/gnsrecord_serialization.c
- src/gnsrecord/gnunet-gnsrecord-tvg.c
- src/gnsrecord/json_gnsrecord.c
- src/gnsrecord/plugin_gnsrecord_dns.c
- src/hello/address.c
- src/hello/gnunet-hello.c
- src/hello/hello-ng.c
- src/hello/hello-uri.c
- src/hello/hello.c
- src/hostlist/gnunet-daemon-hostlist.c
- src/hostlist/gnunet-daemon-hostlist_client.c
- src/hostlist/gnunet-daemon-hostlist_server.c
- src/identity/gnunet-identity.c
- src/identity/gnunet-service-identity.c
- src/identity/identity_api.c
- src/identity/identity_api_lookup.c
- src/identity/identity_api_suffix_lookup.c
- src/identity/plugin_rest_identity.c
- src/json/json.c
- src/json/json_generator.c
- src/json/json_helper.c
- src/json/json_mhd.c
- src/json/json_pack.c
- src/messenger/gnunet-messenger.c
- src/messenger/gnunet-service-messenger.c
- src/messenger/gnunet-service-messenger_basement.c
- src/messenger/gnunet-service-messenger_ego_store.c
- src/messenger/gnunet-service-messenger_handle.c
- src/messenger/gnunet-service-messenger_list_handles.c
- src/messenger/gnunet-service-messenger_list_messages.c
- src/messenger/gnunet-service-messenger_member.c
- src/messenger/gnunet-service-messenger_member_session.c
- src/messenger/gnunet-service-messenger_member_store.c
- src/messenger/gnunet-service-messenger_message_handle.c
- src/messenger/gnunet-service-messenger_message_kind.c
- src/messenger/gnunet-service-messenger_message_recv.c
- src/messenger/gnunet-service-messenger_message_send.c
- src/messenger/gnunet-service-messenger_message_state.c
- src/messenger/gnunet-service-messenger_message_store.c
- src/messenger/gnunet-service-messenger_operation.c
- src/messenger/gnunet-service-messenger_operation_store.c
- src/messenger/gnunet-service-messenger_room.c
- src/messenger/gnunet-service-messenger_service.c
- src/messenger/gnunet-service-messenger_tunnel.c
- src/messenger/messenger_api.c
- src/messenger/messenger_api_contact.c
- src/messenger/messenger_api_contact_store.c
- src/messenger/messenger_api_handle.c
- src/messenger/messenger_api_list_tunnels.c
- src/messenger/messenger_api_message.c
- src/messenger/messenger_api_message_kind.c
- src/messenger/messenger_api_peer_store.c
- src/messenger/messenger_api_queue_messages.c
- src/messenger/messenger_api_room.c
- src/messenger/messenger_api_util.c
- src/messenger/plugin_gnsrecord_messenger.c
- src/messenger/testing_messenger_barrier.c
- src/messenger/testing_messenger_setup.c
- src/my/my.c
- src/my/my_query_helper.c
- src/my/my_result_helper.c
- src/mysql/mysql.c
- src/namecache/gnunet-namecache.c
- src/namecache/gnunet-service-namecache.c
- src/namecache/namecache_api.c
- src/namecache/plugin_namecache_flat.c
- src/namecache/plugin_namecache_postgres.c
- src/namecache/plugin_namecache_sqlite.c
- src/namestore/gnunet-namestore-dbtool.c
- src/namestore/gnunet-namestore-fcfsd.c
- src/namestore/gnunet-namestore-zonefile.c
- src/namestore/gnunet-namestore.c
- src/namestore/gnunet-service-namestore.c
- src/namestore/gnunet-zoneimport.c
- src/namestore/namestore_api.c
- src/namestore/namestore_api_monitor.c
- src/namestore/plugin_namestore_flat.c
- src/namestore/plugin_namestore_postgres.c
- src/namestore/plugin_namestore_sqlite.c
- src/namestore/plugin_rest_namestore.c
- src/nat-auto/gnunet-nat-auto.c
- src/nat-auto/gnunet-nat-auto_legacy.c
- src/nat-auto/gnunet-nat-server.c
- src/nat-auto/gnunet-service-nat-auto.c
- src/nat-auto/gnunet-service-nat-auto_legacy.c
- src/nat-auto/nat_auto_api.c
- src/nat-auto/nat_auto_api_test.c
- src/nat/gnunet-helper-nat-client.c
- src/nat/gnunet-helper-nat-server.c
- src/nat/gnunet-nat.c
- src/nat/gnunet-service-nat.c
- src/nat/gnunet-service-nat_externalip.c
- src/nat/gnunet-service-nat_helper.c
- src/nat/gnunet-service-nat_mini.c
- src/nat/gnunet-service-nat_stun.c
- src/nat/nat_api.c
- src/nat/nat_api_stun.c
- src/nse/gnunet-nse-profiler.c
- src/nse/gnunet-nse.c
- src/nse/gnunet-service-nse.c
- src/nse/nse_api.c
- src/nt/nt.c
- src/peerinfo-tool/gnunet-peerinfo.c
- src/peerinfo-tool/gnunet-peerinfo_plugins.c
- src/peerinfo-tool/plugin_rest_peerinfo.c
- src/peerinfo/gnunet-service-peerinfo.c
- src/peerinfo/peerinfo_api.c
- src/peerinfo/peerinfo_api_notify.c
- src/peerstore/gnunet-peerstore.c
- src/peerstore/gnunet-service-peerstore.c
- src/peerstore/peerstore_api.c
- src/peerstore/peerstore_common.c
- src/peerstore/plugin_peerstore_flat.c
- src/peerstore/plugin_peerstore_sqlite.c
- src/pq/pq.c
- src/pq/pq_connect.c
- src/pq/pq_eval.c
- src/pq/pq_event.c
- src/pq/pq_exec.c
- src/pq/pq_prepare.c
- src/pq/pq_query_helper.c
- src/pq/pq_result_helper.c
- src/pt/gnunet-daemon-pt.c
- src/reclaim/did_core.c
- src/reclaim/did_helper.c
- src/reclaim/did_misc.c
- src/reclaim/gnunet-did.c
- src/reclaim/gnunet-reclaim.c
- src/reclaim/gnunet-service-reclaim.c
- src/reclaim/gnunet-service-reclaim_tickets.c
- src/reclaim/json_reclaim.c
- src/reclaim/oidc_helper.c
- src/reclaim/pabc_helper.c
- src/reclaim/plugin_gnsrecord_reclaim.c
- src/reclaim/plugin_reclaim_attribute_basic.c
- src/reclaim/plugin_reclaim_credential_jwt.c
- src/reclaim/plugin_reclaim_credential_pabc.c
- src/reclaim/plugin_rest_openid_connect.c
- src/reclaim/plugin_rest_pabc.c
- src/reclaim/plugin_rest_reclaim.c
- src/reclaim/reclaim_api.c
- src/reclaim/reclaim_attribute.c
- src/reclaim/reclaim_credential.c
- src/regex/gnunet-daemon-regexprofiler.c
- src/regex/gnunet-regex-profiler.c
- src/regex/gnunet-regex-simulation-profiler.c
- src/regex/gnunet-service-regex.c
- src/regex/perf-regex.c
- src/regex/plugin_block_regex.c
- src/regex/regex_api_announce.c
- src/regex/regex_api_search.c
- src/regex/regex_block_lib.c
- src/regex/regex_internal.c
- src/regex/regex_internal_dht.c
- src/regex/regex_test_graph.c
- src/regex/regex_test_lib.c
- src/regex/regex_test_random.c
- src/rest/gnunet-rest-server.c
- src/rest/plugin_rest_config.c
- src/rest/plugin_rest_copying.c
- src/rest/rest.c
- src/revocation/gnunet-revocation-tvg.c
- src/revocation/gnunet-revocation.c
- src/revocation/gnunet-service-revocation.c
- src/revocation/plugin_block_revocation.c
- src/revocation/revocation_api.c
- src/rps/gnunet-rps-profiler.c
- src/rps/gnunet-rps.c
- src/rps/gnunet-service-rps.c
- src/rps/gnunet-service-rps_custommap.c
- src/rps/gnunet-service-rps_sampler.c
- src/rps/gnunet-service-rps_sampler_elem.c
- src/rps/gnunet-service-rps_view.c
- src/rps/rps-sampler_client.c
- src/rps/rps-sampler_common.c
- src/rps/rps-test_util.c
- src/rps/rps_api.c
- src/scalarproduct/gnunet-scalarproduct.c
- src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
- src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
- src/scalarproduct/gnunet-service-scalarproduct_alice.c
- src/scalarproduct/gnunet-service-scalarproduct_bob.c
- src/scalarproduct/scalarproduct_api.c
- src/secretsharing/gnunet-secretsharing-profiler.c
- src/secretsharing/gnunet-service-secretsharing.c
- src/secretsharing/secretsharing_api.c
- src/secretsharing/secretsharing_common.c
- src/set/gnunet-service-set.c
- src/set/gnunet-service-set_intersection.c
- src/set/gnunet-service-set_union.c
- src/set/gnunet-service-set_union_strata_estimator.c
- src/set/gnunet-set-ibf-profiler.c
- src/set/gnunet-set-profiler.c
- src/set/ibf.c
- src/set/ibf_sim.c
- src/set/plugin_block_set_test.c
- src/set/set_api.c
- src/seti/gnunet-service-seti.c
- src/seti/gnunet-seti-profiler.c
- src/seti/plugin_block_seti_test.c
- src/seti/seti_api.c
- src/setu/gnunet-service-setu.c
- src/setu/gnunet-service-setu_strata_estimator.c
- src/setu/gnunet-setu-ibf-profiler.c
- src/setu/gnunet-setu-profiler.c
- src/setu/ibf.c
- src/setu/ibf_sim.c
- src/setu/plugin_block_setu_test.c
- src/setu/setu_api.c
- src/sq/sq.c
- src/sq/sq_exec.c
- src/sq/sq_prepare.c
- src/sq/sq_query_helper.c
- src/sq/sq_result_helper.c
- src/statistics/gnunet-service-statistics.c
- src/statistics/gnunet-statistics.c
- src/statistics/statistics_api.c
- src/template/gnunet-service-template.c
- src/template/gnunet-template.c
- src/testbed-logger/gnunet-service-testbed-logger.c
- src/testbed-logger/testbed_logger_api.c
- src/testbed/generate-underlay-topology.c
- src/testbed/gnunet-daemon-latency-logger.c
- src/testbed/gnunet-daemon-testbed-blacklist.c
- src/testbed/gnunet-daemon-testbed-underlay.c
- src/testbed/gnunet-helper-testbed.c
- src/testbed/gnunet-service-test-barriers.c
- src/testbed/gnunet-service-testbed.c
- src/testbed/gnunet-service-testbed_barriers.c
- src/testbed/gnunet-service-testbed_cache.c
- src/testbed/gnunet-service-testbed_connectionpool.c
- src/testbed/gnunet-service-testbed_cpustatus.c
- src/testbed/gnunet-service-testbed_links.c
- src/testbed/gnunet-service-testbed_meminfo.c
- src/testbed/gnunet-service-testbed_oc.c
- src/testbed/gnunet-service-testbed_peers.c
- src/testbed/gnunet-testbed-profiler.c
- src/testbed/gnunet_mpi_test.c
- src/testbed/testbed_api.c
- src/testbed/testbed_api_barriers.c
- src/testbed/testbed_api_hosts.c
- src/testbed/testbed_api_operations.c
- src/testbed/testbed_api_peers.c
- src/testbed/testbed_api_sd.c
- src/testbed/testbed_api_services.c
- src/testbed/testbed_api_statistics.c
- src/testbed/testbed_api_test.c
- src/testbed/testbed_api_testbed.c
- src/testbed/testbed_api_topology.c
- src/testbed/testbed_api_underlay.c
- src/testing/gnunet-cmds-helper.c
- src/testing/gnunet-testing.c
- src/testing/list-keys.c
- src/testing/testing.c
- src/testing/testing_api_cmd_barrier.c
- src/testing/testing_api_cmd_barrier_reached.c
- src/testing/testing_api_cmd_batch.c
- src/testing/testing_api_cmd_block_until_external_trigger.c
- src/testing/testing_api_cmd_finish.c
- src/testing/testing_api_cmd_local_test_prepared.c
- src/testing/testing_api_cmd_netjail_start.c
- src/testing/testing_api_cmd_netjail_start_cmds_helper.c
- src/testing/testing_api_cmd_netjail_stop.c
- src/testing/testing_api_cmd_netjail_stop_cmds_helper.c
- src/testing/testing_api_cmd_send_peer_ready.c
- src/testing/testing_api_cmd_system_create.c
- src/testing/testing_api_cmd_system_destroy.c
- src/testing/testing_api_loop.c
- src/testing/testing_api_traits.c
- src/topology/friends.c
- src/topology/gnunet-daemon-topology.c
- src/transport/gnunet-communicator-quic.c
- src/transport/gnunet-communicator-tcp.c
- src/transport/gnunet-communicator-udp.c
- src/transport/gnunet-communicator-unix.c
- src/transport/gnunet-helper-transport-bluetooth.c
- src/transport/gnunet-helper-transport-wlan-dummy.c
- src/transport/gnunet-helper-transport-wlan.c
- src/transport/gnunet-service-tng.c
- src/transport/gnunet-service-transport.c
- src/transport/gnunet-service-transport_ats.c
- src/transport/gnunet-service-transport_hello.c
- src/transport/gnunet-service-transport_manipulation.c
- src/transport/gnunet-service-transport_neighbours.c
- src/transport/gnunet-service-transport_plugins.c
- src/transport/gnunet-service-transport_validation.c
- src/transport/gnunet-transport-profiler.c
- src/transport/gnunet-transport-wlan-receiver.c
- src/transport/gnunet-transport-wlan-sender.c
- src/transport/gnunet-transport.c
- src/transport/plugin_transport_http_client.c
- src/transport/plugin_transport_http_common.c
- src/transport/plugin_transport_http_server.c
- src/transport/plugin_transport_smtp.c
- src/transport/plugin_transport_tcp.c
- src/transport/plugin_transport_template.c
- src/transport/plugin_transport_udp.c
- src/transport/plugin_transport_udp_broadcasting.c
- src/transport/plugin_transport_unix.c
- src/transport/plugin_transport_wlan.c
- src/transport/tcp_connection_legacy.c
- src/transport/tcp_server_legacy.c
- src/transport/tcp_server_mst_legacy.c
- src/transport/tcp_service_legacy.c
- src/transport/transport-testing-communicator.c
- src/transport/transport-testing-filenames.c
- src/transport/transport-testing-filenames2.c
- src/transport/transport-testing-loggers.c
- src/transport/transport-testing-loggers2.c
- src/transport/transport-testing-main.c
- src/transport/transport-testing-main2.c
- src/transport/transport-testing-send.c
- src/transport/transport-testing-send2.c
- src/transport/transport-testing.c
- src/transport/transport-testing2.c
- src/transport/transport_api2_application.c
- src/transport/transport_api2_communication.c
- src/transport/transport_api2_core.c
- src/transport/transport_api2_monitor.c
- src/transport/transport_api_address_to_string.c
- src/transport/transport_api_blacklist.c
- src/transport/transport_api_cmd_backchannel_check.c
- src/transport/transport_api_cmd_connecting_peers.c
- src/transport/transport_api_cmd_send_simple.c
- src/transport/transport_api_cmd_send_simple_performance.c
- src/transport/transport_api_cmd_start_peer.c
- src/transport/transport_api_cmd_stop_peer.c
- src/transport/transport_api_core.c
- src/transport/transport_api_hello_get.c
- src/transport/transport_api_manipulation.c
- src/transport/transport_api_monitor_peers.c
- src/transport/transport_api_monitor_plugins.c
- src/transport/transport_api_offer_hello.c
- src/transport/transport_api_traits.c
- src/util/bandwidth.c
- src/util/benchmark.c
- src/util/bio.c
- src/util/buffer.c
- src/util/child_management.c
- src/util/client.c
- src/util/common_allocation.c
- src/util/common_endian.c
- src/util/common_logging.c
- src/util/compress.c
- src/util/configuration.c
- src/util/configuration_helper.c
- src/util/consttime_memcmp.c
- src/util/container_bloomfilter.c
- src/util/container_heap.c
- src/util/container_multihashmap.c
- src/util/container_multihashmap32.c
- src/util/container_multipeermap.c
- src/util/container_multishortmap.c
- src/util/container_multiuuidmap.c
- src/util/crypto_crc.c
- src/util/crypto_cs.c
- src/util/crypto_ecc.c
- src/util/crypto_ecc_dlog.c
- src/util/crypto_ecc_gnsrecord.c
- src/util/crypto_ecc_setup.c
- src/util/crypto_edx25519.c
- src/util/crypto_hash.c
- src/util/crypto_hash_file.c
- src/util/crypto_hkdf.c
- src/util/crypto_kdf.c
- src/util/crypto_mpi.c
- src/util/crypto_paillier.c
- src/util/crypto_pow.c
- src/util/crypto_random.c
- src/util/crypto_rsa.c
- src/util/crypto_symmetric.c
- src/util/disk.c
- src/util/dnsparser.c
- src/util/dnsstub.c
- src/util/getopt.c
- src/util/getopt_helpers.c
- src/util/gnunet-base32.c
- src/util/gnunet-config-diff.c
- src/util/gnunet-config.c
- src/util/gnunet-crypto-tvg.c
- src/util/gnunet-ecc.c
- src/util/gnunet-qr.c
- src/util/gnunet-resolver.c
- src/util/gnunet-scrypt.c
- src/util/gnunet-service-resolver.c
- src/util/gnunet-timeout.c
- src/util/gnunet-uri.c
+ src/cli/arm/gnunet-arm.c
+ src/cli/cadet/gnunet-cadet.c
+ src/cli/core/gnunet-core.c
+ src/cli/datastore/gnunet-datastore.c
+ src/cli/dht/gnunet-dht-get.c
+ src/cli/dht/gnunet-dht-hello.c
+ src/cli/dht/gnunet-dht-monitor.c
+ src/cli/dht/gnunet-dht-put.c
+ src/cli/fs/gnunet-auto-share.c
+ src/cli/fs/gnunet-directory.c
+ src/cli/fs/gnunet-download.c
+ src/cli/fs/gnunet-fs.c
+ src/cli/fs/gnunet-publish.c
+ src/cli/fs/gnunet-search.c
+ src/cli/fs/gnunet-unindex.c
+ src/cli/gns/gnunet-gns.c
+ src/cli/identity/gnunet-identity.c
+ src/cli/messenger/gnunet-messenger.c
+ src/cli/namecache/gnunet-namecache.c
+ src/cli/namestore/gnunet-namestore-dbtool.c
+ src/cli/namestore/gnunet-namestore-zonefile.c
+ src/cli/namestore/gnunet-namestore.c
+ src/cli/namestore/gnunet-zoneimport.c
+ src/cli/nat-auto/gnunet-nat-auto.c
+ src/cli/nat-auto/gnunet-nat-server.c
+ src/cli/nat/gnunet-nat.c
+ src/cli/nse/gnunet-nse.c
+ src/cli/reclaim/gnunet-did.c
+ src/cli/reclaim/gnunet-reclaim.c
+ src/cli/revocation/gnunet-revocation-tvg.c
+ src/cli/revocation/gnunet-revocation.c
+ src/cli/statistics/gnunet-statistics.c
+ src/cli/util/gnunet-base32.c
+ src/cli/util/gnunet-config-diff.c
+ src/cli/util/gnunet-config.c
+ src/cli/util/gnunet-crypto-tvg.c
+ src/cli/util/gnunet-ecc.c
+ src/cli/util/gnunet-qr.c
+ src/cli/util/gnunet-resolver.c
+ src/cli/util/gnunet-scrypt.c
+ src/cli/util/gnunet-timeout.c
+ src/cli/util/gnunet-uri.c
+ src/cli/vpn/gnunet-vpn.c
+ src/contrib/cli/template/gnunet-template.c
+ src/contrib/service/abd/abd_api.c
+ src/contrib/service/abd/abd_serialization.c
+ src/contrib/service/abd/delegate_misc.c
+ src/contrib/service/abd/gnunet-abd.c
+ src/contrib/service/abd/gnunet-service-abd.c
+ src/contrib/service/abd/plugin_gnsrecord_abd.c
+ src/contrib/service/auction/gnunet-auction-create.c
+ src/contrib/service/auction/gnunet-auction-info.c
+ src/contrib/service/auction/gnunet-auction-join.c
+ src/contrib/service/auction/gnunet-service-auction.c
+ src/contrib/service/consensus/consensus_api.c
+ src/contrib/service/consensus/gnunet-service-consensus.c
+ src/contrib/service/consensus/plugin_block_consensus.c
+ src/contrib/service/conversation/conversation_api.c
+ src/contrib/service/conversation/conversation_api_call.c
+ src/contrib/service/conversation/gnunet-conversation-test.c
+ src/contrib/service/conversation/gnunet-conversation.c
+ src/contrib/service/conversation/gnunet-helper-audio-playback-gst.c
+ src/contrib/service/conversation/gnunet-helper-audio-playback.c
+ src/contrib/service/conversation/gnunet-helper-audio-record-gst.c
+ src/contrib/service/conversation/gnunet-helper-audio-record.c
+ src/contrib/service/conversation/gnunet-service-conversation.c
+ src/contrib/service/conversation/gnunet_gst.c
+ src/contrib/service/conversation/gnunet_gst_test.c
+ src/contrib/service/conversation/microphone.c
+ src/contrib/service/conversation/plugin_gnsrecord_conversation.c
+ src/contrib/service/conversation/speaker.c
+ src/contrib/service/rps/gnunet-rps-profiler.c
+ src/contrib/service/rps/gnunet-rps.c
+ src/contrib/service/rps/gnunet-service-rps.c
+ src/contrib/service/rps/gnunet-service-rps_custommap.c
+ src/contrib/service/rps/gnunet-service-rps_sampler.c
+ src/contrib/service/rps/gnunet-service-rps_sampler_elem.c
+ src/contrib/service/rps/gnunet-service-rps_view.c
+ src/contrib/service/rps/rps-sampler_client.c
+ src/contrib/service/rps/rps-sampler_common.c
+ src/contrib/service/rps/rps-test_util.c
+ src/contrib/service/rps/rps_api.c
+ src/contrib/service/scalarproduct/gnunet-scalarproduct.c
+ src/contrib/service/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
+ src/contrib/service/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
+ src/contrib/service/scalarproduct/gnunet-service-scalarproduct_alice.c
+ src/contrib/service/scalarproduct/gnunet-service-scalarproduct_bob.c
+ src/contrib/service/scalarproduct/scalarproduct_api.c
+ src/contrib/service/secretsharing/gnunet-secretsharing-profiler.c
+ src/contrib/service/secretsharing/gnunet-service-secretsharing.c
+ src/contrib/service/secretsharing/secretsharing_api.c
+ src/contrib/service/secretsharing/secretsharing_common.c
+ src/contrib/service/set/gnunet-service-set.c
+ src/contrib/service/set/gnunet-service-set_intersection.c
+ src/contrib/service/set/gnunet-service-set_union.c
+ src/contrib/service/set/gnunet-service-set_union_strata_estimator.c
+ src/contrib/service/set/gnunet-set-ibf-profiler.c
+ src/contrib/service/set/gnunet-set-profiler.c
+ src/contrib/service/set/ibf.c
+ src/contrib/service/set/ibf_sim.c
+ src/contrib/service/set/plugin_block_set_test.c
+ src/contrib/service/set/set_api.c
+ src/contrib/service/template/gnunet-service-template.c
+ src/lib/block/bg_bf.c
+ src/lib/block/block.c
+ src/lib/curl/curl.c
+ src/lib/curl/curl_reschedule.c
+ src/lib/gnsrecord/gnsrecord.c
+ src/lib/gnsrecord/gnsrecord_crypto.c
+ src/lib/gnsrecord/gnsrecord_misc.c
+ src/lib/gnsrecord/gnsrecord_pow.c
+ src/lib/gnsrecord/gnsrecord_serialization.c
+ src/lib/gnsrecord/gnunet-gnsrecord-tvg.c
+ src/lib/gnsrecord/json_gnsrecord.c
+ src/lib/hello/gnunet-hello.c
+ src/lib/hello/hello-ng.c
+ src/lib/hello/hello-uri.c
+ src/lib/json/json.c
+ src/lib/json/json_generator.c
+ src/lib/json/json_helper.c
+ src/lib/json/json_mhd.c
+ src/lib/json/json_pack.c
+ src/lib/pq/pq.c
+ src/lib/pq/pq_connect.c
+ src/lib/pq/pq_eval.c
+ src/lib/pq/pq_event.c
+ src/lib/pq/pq_exec.c
+ src/lib/pq/pq_prepare.c
+ src/lib/pq/pq_query_helper.c
+ src/lib/pq/pq_result_helper.c
+ src/lib/sq/sq.c
+ src/lib/sq/sq_exec.c
+ src/lib/sq/sq_prepare.c
+ src/lib/sq/sq_query_helper.c
+ src/lib/sq/sq_result_helper.c
+ src/lib/util/bandwidth.c
+ src/lib/util/benchmark.c
+ src/lib/util/bio.c
+ src/lib/util/buffer.c
+ src/lib/util/child_management.c
+ src/lib/util/client.c
+ src/lib/util/common_allocation.c
+ src/lib/util/common_endian.c
+ src/lib/util/common_logging.c
+ src/lib/util/compress.c
+ src/lib/util/configuration.c
+ src/lib/util/configuration_helper.c
+ src/lib/util/consttime_memcmp.c
+ src/lib/util/container_bloomfilter.c
+ src/lib/util/container_heap.c
+ src/lib/util/container_multihashmap.c
+ src/lib/util/container_multihashmap32.c
+ src/lib/util/container_multipeermap.c
+ src/lib/util/container_multishortmap.c
+ src/lib/util/container_multiuuidmap.c
+ src/lib/util/crypto_blind_sign.c
+ src/lib/util/crypto_crc.c
+ src/lib/util/crypto_cs.c
+ src/lib/util/crypto_ecc.c
+ src/lib/util/crypto_ecc_dlog.c
+ src/lib/util/crypto_ecc_gnsrecord.c
+ src/lib/util/crypto_ecc_setup.c
+ src/lib/util/crypto_edx25519.c
+ src/lib/util/crypto_hash.c
+ src/lib/util/crypto_hash_file.c
+ src/lib/util/crypto_hkdf.c
+ src/lib/util/crypto_kdf.c
+ src/lib/util/crypto_mpi.c
+ src/lib/util/crypto_paillier.c
+ src/lib/util/crypto_pkey.c
+ src/lib/util/crypto_pow.c
+ src/lib/util/crypto_random.c
+ src/lib/util/crypto_rsa.c
+ src/lib/util/crypto_symmetric.c
+ src/lib/util/disk.c
+ src/lib/util/dnsparser.c
+ src/lib/util/dnsstub.c
+ src/lib/util/getopt.c
+ src/lib/util/getopt_helpers.c
+ src/lib/util/gnunet_error_codes.c
+ src/lib/util/helper.c
+ src/lib/util/load.c
+ src/lib/util/mq.c
+ src/lib/util/mst.c
+ src/lib/util/nc.c
+ src/lib/util/network.c
+ src/lib/util/nt.c
+ src/lib/util/op.c
+ src/lib/util/os_installation.c
+ src/lib/util/os_network.c
+ src/lib/util/os_priority.c
+ src/lib/util/peer.c
+ src/lib/util/plugin.c
+ src/lib/util/proc_compat.c
+ src/lib/util/program.c
+ src/lib/util/regex.c
+ src/lib/util/resolver_api.c
+ src/lib/util/scheduler.c
+ src/lib/util/service.c
+ src/lib/util/signal.c
+ src/lib/util/socks.c
+ src/lib/util/speedup.c
+ src/lib/util/strings.c
+ src/lib/util/time.c
+ src/lib/util/tun.c
+ src/lib/util/uri.c
+ src/plugin/block/plugin_block_template.c
+ src/plugin/block/plugin_block_test.c
+ src/plugin/datacache/plugin_datacache_heap.c
+ src/plugin/datacache/plugin_datacache_postgres.c
+ src/plugin/datacache/plugin_datacache_sqlite.c
+ src/plugin/datacache/plugin_datacache_template.c
+ src/plugin/datastore/plugin_datastore_heap.c
+ src/plugin/datastore/plugin_datastore_postgres.c
+ src/plugin/datastore/plugin_datastore_sqlite.c
+ src/plugin/datastore/plugin_datastore_template.c
+ src/plugin/dht/plugin_block_dht.c
+ src/plugin/dns/plugin_block_dns.c
+ src/plugin/fs/plugin_block_fs.c
+ src/plugin/gns/plugin_block_gns.c
+ src/plugin/gns/plugin_gnsrecord_gns.c
+ src/plugin/gnsrecord/plugin_gnsrecord_dns.c
+ src/plugin/messenger/plugin_gnsrecord_messenger.c
+ src/plugin/namecache/plugin_namecache_flat.c
+ src/plugin/namecache/plugin_namecache_postgres.c
+ src/plugin/namecache/plugin_namecache_sqlite.c
+ src/plugin/namestore/plugin_namestore_flat.c
+ src/plugin/namestore/plugin_namestore_postgres.c
+ src/plugin/namestore/plugin_namestore_sqlite.c
+ src/plugin/peerstore/plugin_peerstore_flat.c
+ src/plugin/peerstore/plugin_peerstore_sqlite.c
+ src/plugin/reclaim/pabc_helper.c
+ src/plugin/reclaim/plugin_gnsrecord_reclaim.c
+ src/plugin/reclaim/plugin_reclaim_attribute_basic.c
+ src/plugin/reclaim/plugin_reclaim_credential_jwt.c
+ src/plugin/reclaim/plugin_reclaim_credential_pabc.c
+ src/plugin/regex/plugin_block_regex.c
+ src/plugin/regex/regex_block_lib.c
+ src/plugin/revocation/plugin_block_revocation.c
+ src/plugin/seti/plugin_block_seti_test.c
+ src/plugin/setu/plugin_block_setu_test.c
+ src/service/arm/arm_api.c
+ src/service/arm/arm_monitor_api.c
+ src/service/arm/gnunet-service-arm.c
+ src/service/arm/mockup-service.c
+ src/service/cadet/cadet_api.c
+ src/service/cadet/cadet_api_drop_message.c
+ src/service/cadet/cadet_api_get_channel.c
+ src/service/cadet/cadet_api_get_path.c
+ src/service/cadet/cadet_api_helper.c
+ src/service/cadet/cadet_api_list_peers.c
+ src/service/cadet/cadet_api_list_tunnels.c
+ src/service/cadet/cadet_test_lib.c
+ src/service/cadet/desirability_table.c
+ src/service/cadet/gnunet-service-cadet.c
+ src/service/cadet/gnunet-service-cadet_channel.c
+ src/service/cadet/gnunet-service-cadet_connection.c
+ src/service/cadet/gnunet-service-cadet_core.c
+ src/service/cadet/gnunet-service-cadet_dht.c
+ src/service/cadet/gnunet-service-cadet_hello.c
+ src/service/cadet/gnunet-service-cadet_paths.c
+ src/service/cadet/gnunet-service-cadet_peer.c
+ src/service/cadet/gnunet-service-cadet_tunnels.c
+ src/service/core/core_api.c
+ src/service/core/core_api_cmd_connecting_peers.c
+ src/service/core/core_api_monitor_peers.c
+ src/service/core/gnunet-service-core.c
+ src/service/core/gnunet-service-core_kx.c
+ src/service/core/gnunet-service-core_sessions.c
+ src/service/core/gnunet-service-core_typemap.c
+ src/service/datacache/datacache.c
+ src/service/datastore/datastore_api.c
+ src/service/datastore/gnunet-service-datastore.c
+ src/service/dht/dht_api.c
+ src/service/dht/dht_test_lib.c
+ src/service/dht/gnunet-service-dht.c
+ src/service/dht/gnunet-service-dht_clients.c
+ src/service/dht/gnunet-service-dht_datacache.c
+ src/service/dht/gnunet-service-dht_neighbours.c
+ src/service/dht/gnunet-service-dht_routing.c
+ src/service/dht/gnunet_dht_profiler.c
+ src/service/dhtu/plugin_dhtu_gnunet.c
+ src/service/dhtu/plugin_dhtu_ip.c
+ src/service/dhtu/testing_dhtu_cmd_send.c
+ src/service/dns/dns_api.c
+ src/service/dns/gnunet-dns-monitor.c
+ src/service/dns/gnunet-dns-redirector.c
+ src/service/dns/gnunet-helper-dns.c
+ src/service/dns/gnunet-service-dns.c
+ src/service/dns/gnunet-zonewalk.c
+ src/service/exit/gnunet-daemon-exit.c
+ src/service/exit/gnunet-helper-exit.c
+ src/service/fs/fs_api.c
+ src/service/fs/fs_directory.c
+ src/service/fs/fs_dirmetascan.c
+ src/service/fs/fs_download.c
+ src/service/fs/fs_file_information.c
+ src/service/fs/fs_getopt.c
+ src/service/fs/fs_list_indexed.c
+ src/service/fs/fs_misc.c
+ src/service/fs/fs_namespace.c
+ src/service/fs/fs_publish.c
+ src/service/fs/fs_publish_ksk.c
+ src/service/fs/fs_publish_ublock.c
+ src/service/fs/fs_search.c
+ src/service/fs/fs_sharetree.c
+ src/service/fs/fs_test_lib.c
+ src/service/fs/fs_tree.c
+ src/service/fs/fs_unindex.c
+ src/service/fs/fs_uri.c
+ src/service/fs/gnunet-daemon-fsprofiler.c
+ src/service/fs/gnunet-fs-profiler.c
+ src/service/fs/gnunet-helper-fs-publish.c
+ src/service/fs/gnunet-service-fs.c
+ src/service/fs/gnunet-service-fs_cadet_client.c
+ src/service/fs/gnunet-service-fs_cadet_server.c
+ src/service/fs/gnunet-service-fs_cp.c
+ src/service/fs/gnunet-service-fs_indexing.c
+ src/service/fs/gnunet-service-fs_pe.c
+ src/service/fs/gnunet-service-fs_pr.c
+ src/service/fs/gnunet-service-fs_push.c
+ src/service/fs/gnunet-service-fs_put.c
+ src/service/fs/meta_data.c
+ src/service/gns/gns_api.c
+ src/service/gns/gns_tld_api.c
+ src/service/gns/gnunet-bcd.c
+ src/service/gns/gnunet-dns2gns.c
+ src/service/gns/gnunet-gns-benchmark.c
+ src/service/gns/gnunet-gns-import.c
+ src/service/gns/gnunet-gns-proxy.c
+ src/service/gns/gnunet-service-gns.c
+ src/service/gns/gnunet-service-gns_interceptor.c
+ src/service/gns/gnunet-service-gns_resolver.c
+ src/service/gns/nss/nss_gns.c
+ src/service/gns/nss/nss_gns_query.c
+ src/service/hostlist/gnunet-daemon-hostlist.c
+ src/service/hostlist/gnunet-daemon-hostlist_client.c
+ src/service/hostlist/gnunet-daemon-hostlist_server.c
+ src/service/identity/gnunet-service-identity.c
+ src/service/identity/identity_api.c
+ src/service/identity/identity_api_lookup.c
+ src/service/identity/identity_api_suffix_lookup.c
++src/service/messenger/gnunet-messenger.c
+ src/service/messenger/gnunet-service-messenger.c
+ src/service/messenger/gnunet-service-messenger_basement.c
+ src/service/messenger/gnunet-service-messenger_ego_store.c
+ src/service/messenger/gnunet-service-messenger_handle.c
+ src/service/messenger/gnunet-service-messenger_list_handles.c
+ src/service/messenger/gnunet-service-messenger_list_messages.c
+ src/service/messenger/gnunet-service-messenger_member.c
+ src/service/messenger/gnunet-service-messenger_member_session.c
+ src/service/messenger/gnunet-service-messenger_member_store.c
+ src/service/messenger/gnunet-service-messenger_message_handle.c
+ src/service/messenger/gnunet-service-messenger_message_kind.c
+ src/service/messenger/gnunet-service-messenger_message_recv.c
+ src/service/messenger/gnunet-service-messenger_message_send.c
+ src/service/messenger/gnunet-service-messenger_message_state.c
+ src/service/messenger/gnunet-service-messenger_message_store.c
+ src/service/messenger/gnunet-service-messenger_operation.c
+ src/service/messenger/gnunet-service-messenger_operation_store.c
+ src/service/messenger/gnunet-service-messenger_room.c
+ src/service/messenger/gnunet-service-messenger_service.c
+ src/service/messenger/gnunet-service-messenger_tunnel.c
+ src/service/messenger/messenger_api.c
+ src/service/messenger/messenger_api_contact.c
+ src/service/messenger/messenger_api_contact_store.c
+ src/service/messenger/messenger_api_handle.c
+ src/service/messenger/messenger_api_list_tunnels.c
+ src/service/messenger/messenger_api_message.c
++src/service/messenger/messenger_api_message_kind.c
++src/service/messenger/messenger_api_peer_store.c
++src/service/messenger/messenger_api_queue_messages.c
+ src/service/messenger/messenger_api_room.c
+ src/service/messenger/messenger_api_util.c
++src/service/messenger/plugin_gnsrecord_messenger.c
+ src/service/messenger/testing_messenger_barrier.c
+ src/service/messenger/testing_messenger_setup.c
+ src/service/namecache/gnunet-service-namecache.c
+ src/service/namecache/namecache_api.c
+ src/service/namestore/gnunet-namestore-fcfsd.c
+ src/service/namestore/gnunet-service-namestore.c
+ src/service/namestore/namestore_api.c
+ src/service/namestore/namestore_api_monitor.c
+ src/service/nat-auto/gnunet-nat-auto_legacy.c
+ src/service/nat-auto/gnunet-service-nat-auto.c
+ src/service/nat-auto/gnunet-service-nat-auto_legacy.c
+ src/service/nat-auto/nat_auto_api.c
+ src/service/nat-auto/nat_auto_api_test.c
+ src/service/nat/gnunet-helper-nat-client.c
+ src/service/nat/gnunet-helper-nat-server.c
+ src/service/nat/gnunet-service-nat.c
+ src/service/nat/gnunet-service-nat_externalip.c
+ src/service/nat/gnunet-service-nat_helper.c
+ src/service/nat/gnunet-service-nat_mini.c
+ src/service/nat/gnunet-service-nat_stun.c
+ src/service/nat/nat_api.c
+ src/service/nat/nat_api_stun.c
+ src/service/nse/gnunet-nse-profiler.c
+ src/service/nse/gnunet-service-nse.c
+ src/service/nse/nse_api.c
+ src/service/peerstore/gnunet-peerstore.c
+ src/service/peerstore/gnunet-service-peerstore.c
+ src/service/peerstore/peerstore_api.c
+ src/service/peerstore/peerstore_common.c
+ src/service/pt/gnunet-daemon-pt.c
+ src/service/reclaim/did_core.c
+ src/service/reclaim/did_helper.c
+ src/service/reclaim/did_misc.c
+ src/service/reclaim/gnunet-service-reclaim.c
+ src/service/reclaim/gnunet-service-reclaim_tickets.c
+ src/service/reclaim/reclaim_api.c
+ src/service/reclaim/reclaim_attribute.c
+ src/service/reclaim/reclaim_credential.c
+ src/service/regex/gnunet-daemon-regexprofiler.c
+ src/service/regex/gnunet-regex-profiler.c
+ src/service/regex/gnunet-regex-simulation-profiler.c
+ src/service/regex/gnunet-service-regex.c
+ src/service/regex/perf-regex.c
+ src/service/regex/regex_api_announce.c
+ src/service/regex/regex_api_search.c
+ src/service/regex/regex_internal.c
+ src/service/regex/regex_internal_dht.c
+ src/service/regex/regex_test_graph.c
+ src/service/regex/regex_test_lib.c
+ src/service/regex/regex_test_random.c
+ src/service/rest/config_plugin.c
+ src/service/rest/copying_plugin.c
+ src/service/rest/gns_plugin.c
+ src/service/rest/gnunet-rest-server.c
+ src/service/rest/identity_plugin.c
+ src/service/rest/json_reclaim.c
+ src/service/rest/namestore_plugin.c
+ src/service/rest/oidc_helper.c
+ src/service/rest/openid_plugin.c
+ src/service/rest/pabc_plugin.c
+ src/service/rest/reclaim_plugin.c
+ src/service/rest/rest.c
+ src/service/revocation/gnunet-service-revocation.c
+ src/service/revocation/revocation_api.c
+ src/service/seti/gnunet-service-seti.c
+ src/service/seti/gnunet-seti-profiler.c
+ src/service/seti/seti_api.c
+ src/service/setu/gnunet-service-setu.c
+ src/service/setu/gnunet-service-setu_strata_estimator.c
+ src/service/setu/gnunet-setu-ibf-profiler.c
+ src/service/setu/gnunet-setu-profiler.c
+ src/service/setu/ibf.c
+ src/service/setu/ibf_sim.c
+ src/service/setu/setu_api.c
+ src/service/statistics/gnunet-service-statistics.c
+ src/service/statistics/statistics_api.c
+ src/service/testing/gnunet-cmds-helper.c
+ src/service/testing/gnunet-testing.c
+ src/service/testing/list-keys.c
+ src/service/testing/testing.c
+ src/service/testing/testing_api_cmd_barrier.c
+ src/service/testing/testing_api_cmd_barrier_reached.c
+ src/service/testing/testing_api_cmd_batch.c
+ src/service/testing/testing_api_cmd_block_until_external_trigger.c
+ src/service/testing/testing_api_cmd_exec_bash_script.c
+ src/service/testing/testing_api_cmd_finish.c
+ src/service/testing/testing_api_cmd_local_test_prepared.c
+ src/service/testing/testing_api_cmd_netjail_start.c
+ src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c
+ src/service/testing/testing_api_cmd_netjail_stop.c
+ src/service/testing/testing_api_cmd_netjail_stop_cmds_helper.c
+ src/service/testing/testing_api_cmd_send_peer_ready.c
+ src/service/testing/testing_api_cmd_start_peer.c
+ src/service/testing/testing_api_cmd_stop_peer.c
+ src/service/testing/testing_api_cmd_system_create.c
+ src/service/testing/testing_api_cmd_system_destroy.c
+ src/service/testing/testing_api_loop.c
+ src/service/testing/testing_api_traits.c
+ src/service/topology/gnunet-daemon-topology.c
+ src/service/transport/gnunet-communicator-quic.c
+ src/service/transport/gnunet-communicator-tcp.c
+ src/service/transport/gnunet-communicator-udp.c
+ src/service/transport/gnunet-communicator-unix.c
+ src/service/transport/gnunet-service-transport.c
+ src/service/transport/gnunet-transport.c
+ src/service/transport/transport-testing-communicator.c
+ src/service/transport/transport-testing-filenames2.c
+ src/service/transport/transport-testing-loggers2.c
+ src/service/transport/transport-testing-main2.c
+ src/service/transport/transport-testing-send2.c
+ src/service/transport/transport-testing2.c
+ src/service/transport/transport_api2_application.c
+ src/service/transport/transport_api2_communication.c
+ src/service/transport/transport_api2_core.c
+ src/service/transport/transport_api2_monitor.c
+ src/service/transport/transport_api_cmd_backchannel_check.c
+ src/service/transport/transport_api_cmd_connecting_peers.c
+ src/service/transport/transport_api_cmd_send_simple.c
+ src/service/transport/transport_api_cmd_send_simple_performance.c
+ src/service/transport/transport_api_cmd_start_peer.c
+ src/service/transport/transport_api_cmd_stop_peer.c
+ src/service/transport/transport_api_traits.c
+ src/service/util/gnunet-service-resolver.c
+ src/service/vpn/gnunet-helper-vpn.c
+ src/service/vpn/gnunet-service-vpn.c
+ src/service/vpn/vpn_api.c
+ src/service/zonemaster/gnunet-service-zonemaster.c
 +src/util/gnunet_error_codes.c
- src/util/helper.c
- src/util/load.c
- src/util/mq.c
- src/util/mst.c
- src/util/nc.c
- src/util/network.c
- src/util/op.c
- src/util/os_installation.c
- src/util/os_network.c
- src/util/os_priority.c
- src/util/peer.c
- src/util/plugin.c
- src/util/proc_compat.c
- src/util/program.c
- src/util/regex.c
- src/util/resolver_api.c
- src/util/scheduler.c
- src/util/service.c
- src/util/signal.c
- src/util/socks.c
- src/util/speedup.c
- src/util/strings.c
- src/util/time.c
- src/util/tun.c
- src/util/uri.c
- src/vpn/gnunet-helper-vpn.c
- src/vpn/gnunet-service-vpn.c
- src/vpn/gnunet-vpn.c
- src/vpn/vpn_api.c
- src/zonemaster/gnunet-service-zonemaster.c
- src/fs/fs_api.h
  src/include/gnunet_json_lib.h
  src/include/gnunet_pq_lib.h
- src/pq/pq.h
- src/testbed/testbed_api.h
- src/testbed/testbed_api_operations.h
+ src/lib/pq/pq.h
+ src/service/fs/fs_api.h
diff --cc src/cli/messenger/Makefile.am
index 000000000,bb5e9c388..741e2b7b9
mode 000000,100644..100644
--- a/src/cli/messenger/Makefile.am
+++ b/src/cli/messenger/Makefile.am
@@@ -1,0 -1,24 +1,25 @@@
+ # This Makefile.am is in the public domain
+ AM_CPPFLAGS = -I$(top_srcdir)/src/include
+ 
+ if USE_COVERAGE
+   AM_CFLAGS = --coverage -O0
+   XLIB = -lgcov
+ endif
+ 
+ pkgcfgdir= $(pkgdatadir)/config.d/
+ 
+ libexecdir= $(pkglibdir)/libexec/
+ 
+ AM_CLFAGS = -g
+ 
+ bin_PROGRAMS = \
+  gnunet-messenger
+ 
+ gnunet_messenger_SOURCES = \
+  gnunet-messenger.c
+ gnunet_messenger_LDADD = \
+  $(top_builddir)/src/service/messenger/libgnunetmessenger.la \
++ $(top_builddir)/src/service/identity/libgnunetidentity.la \
+  $(top_builddir)/src/lib/util/libgnunetutil.la
+ gnunet_messenger_LDFLAGS = \
+   $(GN_LIBINTL)
diff --cc src/cli/messenger/gnunet-messenger.c
index 000000000,9444fa12d..6258ce712
mode 000000,100644..100644
--- a/src/cli/messenger/gnunet-messenger.c
+++ b/src/cli/messenger/gnunet-messenger.c
@@@ -1,0 -1,334 +1,409 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-messenger.c
+  * @brief Print information about messenger groups.
+  */
+ 
+ #include "platform.h"
+ #include <stdio.h>
+ 
+ #include "gnunet_util_lib.h"
+ #include "gnunet_messenger_service.h"
+ 
++const struct GNUNET_CONFIGURATION_Handle *config;
+ struct GNUNET_MESSENGER_Handle *messenger;
+ 
+ /**
+  * Function called whenever a message is received or sent.
+  *
+  * @param[in,out] cls Closure
+  * @param[in] room Room
+  * @param[in] sender Sender of message
+  * @param[in] message Message
+  * @param[in] hash Hash of message
+  * @param[in] flags Flags of message
+  */
+ void
+ on_message (void *cls,
+             struct GNUNET_MESSENGER_Room *room,
+             const struct GNUNET_MESSENGER_Contact *sender,
+             const struct GNUNET_MESSENGER_Message *message,
+             const struct GNUNET_HashCode *hash,
+             enum GNUNET_MESSENGER_MessageFlags flags)
+ {
+   const char *sender_name = GNUNET_MESSENGER_contact_get_name (sender);
+ 
 -  if (!sender_name)
++  if (! sender_name)
+     sender_name = "anonymous";
+ 
 -  printf ("[%s] ", GNUNET_sh2s(&(message->header.sender_id)));
++  printf ("[%s ->", GNUNET_h2s (&(message->header.previous)));
++  printf (" %s]", GNUNET_h2s (hash));
++  printf ("[%s] ", GNUNET_sh2s (&(message->header.sender_id)));
+ 
+   if (flags & GNUNET_MESSENGER_FLAG_PRIVATE)
+     printf ("*");
+ 
+   switch (message->header.kind)
+   {
+   case GNUNET_MESSENGER_KIND_JOIN:
+     {
+       printf ("* '%s' joined the room!\n", sender_name);
+       break;
+     }
+   case GNUNET_MESSENGER_KIND_NAME:
+     {
 -      printf ("* '%s' gets renamed to '%s'\n", sender_name, 
message->body.name.name);
++      printf ("* '%s' gets renamed to '%s'\n", sender_name,
++              message->body.name.name);
+       break;
+     }
+   case GNUNET_MESSENGER_KIND_LEAVE:
+     {
+       printf ("* '%s' leaves the room!\n", sender_name);
+       break;
+     }
+   case GNUNET_MESSENGER_KIND_PEER:
+     {
 -      printf ("* '%s' opened the room on: %s\n", sender_name, GNUNET_i2s_full 
(&(message->body.peer.peer)));
++      printf ("* '%s' opened the room on: %s\n", sender_name,
++              GNUNET_i2s_full (&(message->body.peer.peer)));
+       break;
+     }
+   case GNUNET_MESSENGER_KIND_TEXT:
+     {
+       if (flags & GNUNET_MESSENGER_FLAG_SENT)
+         printf (">");
+       else
+         printf ("<");
+ 
+       printf (" '%s' says: \"%s\"\n", sender_name, message->body.text.text);
+       break;
+     }
+   default:
+     {
 -      printf ("~ message: %s\n", 
GNUNET_MESSENGER_name_of_kind(message->header.kind));
++      printf ("~ message: %s\n",
++              GNUNET_MESSENGER_name_of_kind (message->header.kind));
+       break;
+     }
+   }
++
++  if ((GNUNET_MESSENGER_KIND_JOIN == message->header.kind) &&
++      (flags & GNUNET_MESSENGER_FLAG_SENT))
++  {
++    const char *name = GNUNET_MESSENGER_get_name (messenger);
++
++    if (! name)
++      return;
++
++    struct GNUNET_MESSENGER_Message response;
++    response.header.kind = GNUNET_MESSENGER_KIND_NAME;
++    response.body.name.name = GNUNET_strdup (name);
++
++    GNUNET_MESSENGER_send_message (room, &response, NULL);
++
++    GNUNET_free (response.body.name.name);
++  }
+ }
+ 
++
+ struct GNUNET_SCHEDULER_Task *read_task;
++struct GNUNET_IDENTITY_EgoLookup *ego_lookup;
+ 
+ /**
+  * Task to shut down this application.
+  *
+  * @param[in,out] cls Closure
+  */
+ static void
+ shutdown_hook (void *cls)
+ {
+   struct GNUNET_MESSENGER_Room *room = cls;
+ 
+   if (read_task)
+     GNUNET_SCHEDULER_cancel (read_task);
+ 
+   if (room)
+     GNUNET_MESSENGER_close_room (room);
+ 
+   if (messenger)
+     GNUNET_MESSENGER_disconnect (messenger);
++
++  if (ego_lookup)
++    GNUNET_IDENTITY_ego_lookup_cancel (ego_lookup);
+ }
+ 
++
+ static void
+ listen_stdio (void *cls);
+ 
+ #define MAX_BUFFER_SIZE 60000
+ 
+ static int
+ iterate_send_private_message (void *cls,
+                               struct GNUNET_MESSENGER_Room *room,
+                               const struct GNUNET_MESSENGER_Contact *contact)
+ {
+   struct GNUNET_MESSENGER_Message *message = cls;
+ 
 -  if (GNUNET_MESSENGER_contact_get_key(contact))
++  if (GNUNET_MESSENGER_contact_get_key (contact))
+     GNUNET_MESSENGER_send_message (room, message, contact);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ int private_mode;
+ 
+ /**
+  * Task run in stdio mode, after some data is available at stdin.
+  *
+  * @param[in,out] cls Closure
+  */
+ static void
+ read_stdio (void *cls)
+ {
+   read_task = NULL;
+ 
+   char buffer[MAX_BUFFER_SIZE];
+   ssize_t length;
+ 
+   length = read (0, buffer, MAX_BUFFER_SIZE);
+ 
+   if ((length <= 0) || (length >= MAX_BUFFER_SIZE))
+   {
+     GNUNET_SCHEDULER_shutdown ();
+     return;
+   }
+ 
+   if (buffer[length - 1] == '\n')
+     buffer[length - 1] = '\0';
+   else
+     buffer[length] = '\0';
+ 
+   struct GNUNET_MESSENGER_Room *room = cls;
+ 
+   struct GNUNET_MESSENGER_Message message;
+   message.header.kind = GNUNET_MESSENGER_KIND_TEXT;
+   message.body.text.text = buffer;
+ 
+   if (GNUNET_YES == private_mode)
 -    GNUNET_MESSENGER_iterate_members(room, iterate_send_private_message, 
&message);
++    GNUNET_MESSENGER_iterate_members (room, iterate_send_private_message,
++                                      &message);
+   else
+     GNUNET_MESSENGER_send_message (room, &message, NULL);
+ 
+   read_task = GNUNET_SCHEDULER_add_now (listen_stdio, cls);
+ }
+ 
++
+ /**
+  * Wait for input on STDIO and send it out over the #ch.
+  *
+  * @param[in,out] cls Closure
+  */
+ static void
+ listen_stdio (void *cls)
+ {
+   read_task = NULL;
+ 
+   struct GNUNET_NETWORK_FDSet *rs = GNUNET_NETWORK_fdset_create ();
+ 
+   GNUNET_NETWORK_fdset_set_native (rs, 0);
+ 
+   read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                            GNUNET_TIME_UNIT_FOREVER_REL, rs,
+                                            NULL, &read_stdio, cls);
+ 
+   GNUNET_NETWORK_fdset_destroy (rs);
+ }
+ 
++
+ /**
+  * Initial task to startup application.
+  *
+  * @param[in,out] cls Closure
+  */
+ static void
+ idle (void *cls)
+ {
+   struct GNUNET_MESSENGER_Room *room = cls;
+ 
+   printf ("* You joined the room.\n");
+ 
+   read_task = GNUNET_SCHEDULER_add_now (listen_stdio, room);
+ }
+ 
++
+ char *door_id;
+ char *ego_name;
+ char *room_key;
+ 
+ struct GNUNET_SCHEDULER_Task *shutdown_task;
+ 
+ /**
+  * Function called when an identity is retrieved.
+  *
+  * @param[in,out] cls Closure
+  * @param[in,out] handle Handle of messenger service
+  */
+ static void
+ on_identity (void *cls,
+              struct GNUNET_MESSENGER_Handle *handle)
+ {
+   struct GNUNET_HashCode key;
+   memset (&key, 0, sizeof(key));
+ 
+   if (room_key)
+     GNUNET_CRYPTO_hash (room_key, strlen (room_key), &key);
+ 
+   struct GNUNET_PeerIdentity door_peer;
+   struct GNUNET_PeerIdentity *door = NULL;
+ 
+   if ((door_id) &&
 -      (GNUNET_OK == GNUNET_CRYPTO_eddsa_public_key_from_string (door_id, 
strlen (door_id), &(door_peer.public_key))))
++      (GNUNET_OK == GNUNET_CRYPTO_eddsa_public_key_from_string (door_id,
++                                                                strlen (
++                                                                  door_id),
++                                                                &(door_peer.
++                                                                  
public_key))))
+     door = &door_peer;
+ 
+   const char *name = GNUNET_MESSENGER_get_name (handle);
+ 
 -  if (!name)
++  if (! name)
+     name = "anonymous";
+ 
+   printf ("* Welcome to the messenger, '%s'!\n", name);
+ 
+   struct GNUNET_MESSENGER_Room *room;
+ 
+   if (door)
+   {
+     printf ("* You try to entry a room...\n");
+ 
+     room = GNUNET_MESSENGER_enter_room (messenger, door, &key);
+   }
+   else
+   {
+     printf ("* You try to open a room...\n");
+ 
+     room = GNUNET_MESSENGER_open_room (messenger, &key);
+   }
+ 
+   GNUNET_SCHEDULER_cancel (shutdown_task);
+ 
+   shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, room);
+ 
 -  if (!room)
++  if (! room)
+     GNUNET_SCHEDULER_shutdown ();
+   else
+   {
 -    struct GNUNET_MESSENGER_Message message;
 -    message.header.kind = GNUNET_MESSENGER_KIND_NAME;
 -    message.body.name.name = GNUNET_strdup(name);
++    GNUNET_SCHEDULER_add_delayed_with_priority (
++      GNUNET_TIME_relative_get_zero_ (),
++      GNUNET_SCHEDULER_PRIORITY_IDLE,
++      idle, room);
++  }
++}
+ 
 -    GNUNET_MESSENGER_send_message (room, &message, NULL);
 -    GNUNET_free(message.body.name.name);
+ 
 -    GNUNET_SCHEDULER_add_delayed_with_priority 
(GNUNET_TIME_relative_get_zero_ (), GNUNET_SCHEDULER_PRIORITY_IDLE, idle,
 -                                                room);
 -  }
++static void
++on_ego_lookup (void *cls,
++               struct GNUNET_IDENTITY_Ego *ego)
++{
++  ego_lookup = NULL;
++
++  const struct GNUNET_CRYPTO_PrivateKey *key;
++  key = ego ? GNUNET_IDENTITY_ego_get_private_key (ego) : NULL;
++
++  messenger = GNUNET_MESSENGER_connect (config, ego_name, key, &on_message,
++                                        NULL);
++
++  on_identity (NULL, messenger);
+ }
+ 
++
+ /**
+  * Main function that will be run by the scheduler.
+  *
+  * @param[in/out] cls closure
+  * @param[in] args remaining command-line arguments
+  * @param[in] cfgfile name of the configuration file used (for saving, can be 
NULL!)
+  * @param[in] cfg configuration
+  */
+ static void
+ run (void *cls,
 -     char *const*args,
++     char *const *args,
+      const char *cfgfile,
+      const struct GNUNET_CONFIGURATION_Handle *cfg)
+ {
 -  messenger = GNUNET_MESSENGER_connect (cfg, ego_name, &on_identity, NULL, 
&on_message, NULL);
++  config = cfg;
++
++  if (ego_name)
++  {
++    ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &on_ego_lookup,
++                                             NULL);
++    messenger = NULL;
++  }
++  else
++  {
++    ego_lookup = NULL;
++    messenger = GNUNET_MESSENGER_connect (cfg, NULL, NULL, &on_message, NULL);
++  }
+ 
+   shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, NULL);
++
++  if (messenger)
++    on_identity (NULL, messenger);
+ }
+ 
++
+ /**
+  * The main function to obtain messenger information.
+  *
+  * @param[in] argc number of arguments from the command line
+  * @param[in] argv command line arguments
+  * @return #EXIT_SUCCESS ok, #EXIT_FAILURE on error
+  */
+ int
+ main (int argc,
+       char **argv)
+ {
 -  const char *description = "Open and connect to rooms using the MESSENGER to 
chat.";
 -
 -  struct GNUNET_GETOPT_CommandLineOption options[] =
 -  {
 -    GNUNET_GETOPT_option_string ('d', "door", "PEERIDENTITY", "peer identity 
to entry into the room", &door_id),
 -    GNUNET_GETOPT_option_string ('e', "ego", "IDENTITY", "identity to use for 
messaging", &ego_name),
 -    GNUNET_GETOPT_option_string ('r', "room", "ROOMKEY", "key of the room to 
connect to", &room_key),
 -    GNUNET_GETOPT_option_flag ('p', "private", "flag to enable private mode", 
&private_mode),
++  const char *description =
++    "Open and connect to rooms using the MESSENGER to chat.";
++
++  struct GNUNET_GETOPT_CommandLineOption options[] = {
++    GNUNET_GETOPT_option_string ('d', "door", "PEERIDENTITY",
++                                 "peer identity to entry into the room",
++                                 &door_id),
++    GNUNET_GETOPT_option_string ('e', "ego", "IDENTITY",
++                                 "identity to use for messaging",
++                                 &ego_name),
++    GNUNET_GETOPT_option_string ('r', "room", "ROOMKEY",
++                                 "key of the room to connect to",
++                                 &room_key),
++    GNUNET_GETOPT_option_flag ('p', "private", "flag to enable private mode",
++                               &private_mode),
+     GNUNET_GETOPT_OPTION_END
+   };
+ 
 -  return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-messenger\0", 
gettext_noop(description), options, &run,
 -  NULL) ? EXIT_SUCCESS : EXIT_FAILURE);
++  return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-messenger\0",
++                                           gettext_noop (description), 
options,
++                                           &run,
++                                           NULL) ? EXIT_SUCCESS : 
EXIT_FAILURE);
+ }
diff --cc src/cli/messenger/meson.build
index 000000000,69bc6af75..3a3870c9d
mode 000000,100644..100644
--- a/src/cli/messenger/meson.build
+++ b/src/cli/messenger/meson.build
@@@ -1,0 -1,8 +1,9 @@@
+ executable ('gnunet-messenger',
+             'gnunet-messenger.c',
+             dependencies: [libgnunetmessenger_dep,
++                           libgnunetidentity_dep,
+                            libgnunetutil_dep],
+             include_directories: [incdir, configuration_inc],
+             install: true,
+             install_dir: get_option('bindir'))
+ 
diff --cc src/include/gnunet_identity_service.h
index d4192a77f,4743dbf7e..270f4d26f
--- a/src/include/gnunet_identity_service.h
+++ b/src/include/gnunet_identity_service.h
@@@ -203,19 -106,9 +106,19 @@@ GNUNET_IDENTITY_ego_get_anonymous (void
   */
  void
  GNUNET_IDENTITY_ego_get_public_key (struct GNUNET_IDENTITY_Ego *ego,
-                                     struct GNUNET_IDENTITY_PublicKey *pk);
+                                     struct GNUNET_CRYPTO_PublicKey *pk);
  
  
 +/**
 + * Obtain the name associated with an ego.
 + *
 + * @param ego the ego
 + * @return associated name, valid as long as the ego is valid
 + */
 +const char*
 +GNUNET_IDENTITY_ego_get_name (const struct GNUNET_IDENTITY_Ego *ego);
 +
 +
  /**
   * Method called to inform about the egos of this peer.
   *
diff --cc src/include/gnunet_messenger_service.h
index 5b03ddecf,90004826a..0388b7fb2
--- a/src/include/gnunet_messenger_service.h
+++ b/src/include/gnunet_messenger_service.h
@@@ -610,7 -616,8 +610,7 @@@ typedef in
  struct GNUNET_MESSENGER_Handle*
  GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
                            const char *name,
-                           const struct GNUNET_IDENTITY_PrivateKey *key,
 -                          GNUNET_MESSENGER_IdentityCallback identity_callback,
 -                          void *identity_cls,
++                          const struct GNUNET_CRYPTO_PrivateKey *key,
                            GNUNET_MESSENGER_MessageCallback msg_callback,
                            void *msg_cls);
  
@@@ -647,24 -669,11 +647,24 @@@ GNUNET_MESSENGER_set_name (struct GNUNE
   * Get the public key used by the messenger or NULL if the anonymous key was 
used.
   *
   * @param[in] handle Messenger handle to use
 - * @return Used ego's public key or NULL
 + * @return Used public key or NULL
   */
- const struct GNUNET_IDENTITY_PublicKey*
+ const struct GNUNET_CRYPTO_PublicKey*
  GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle);
  
 +/**
 + * Set the private key used by the messenger or NULL if the anonymous key 
should be
 + * used instead. The currently used key will be replaced and the change will 
get signed
 + * accordingly to be verified by all contacts.
 + *
 + * @param[in,out] handle Messenger handle to use
 + * @param[in] key Private key to change to or NULL
 + * @return #GNUNET_YES on success, #GNUNET_NO on failure and #GNUNET_SYSERR 
if <i>handle</i> is NULL
 + */
 +int
 +GNUNET_MESSENGER_set_key (struct GNUNET_MESSENGER_Handle *handle,
-                           const struct GNUNET_IDENTITY_PrivateKey *key);
++                          const struct GNUNET_CRYPTO_PrivateKey *key);
 +
  /**
   * Open a room to send and receive messages. The room will use the specified 
<i>key</i> as port for the underlying cadet
   * service. Opening a room results in opening the port for incoming 
connections as possible <b>door</b>.
@@@ -773,11 -781,10 +773,10 @@@ GNUNET_MESSENGER_contact_get_name (cons
   * Get the public key used by the <i>contact</i> or NULL if the anonymous key 
was used.
   *
   * @param[in] contact Contact handle
 - * @return Public key of the ego used by <i>contact</i> or NULL
 + * @return Public key used by <i>contact</i> or NULL
   */
- const struct GNUNET_IDENTITY_PublicKey*
- GNUNET_MESSENGER_contact_get_key (const struct
-                                   GNUNET_MESSENGER_Contact *contact);
+ const struct GNUNET_CRYPTO_PublicKey*
+ GNUNET_MESSENGER_contact_get_key (const struct GNUNET_MESSENGER_Contact 
*contact);
  
  /**
   * Send a <i>message</i> into a <i>room</i>. If you opened the <i>room</i> 
all entered members will receive the
diff --cc src/service/messenger/Makefile.am
index 000000000,c2ae65a08..f169d8773
mode 000000,100644..100644
--- a/src/service/messenger/Makefile.am
+++ b/src/service/messenger/Makefile.am
@@@ -1,0 -1,99 +1,103 @@@
+ # This Makefile.am is in the public domain
+ AM_CPPFLAGS = -I$(top_srcdir)/src/include
+ 
+ if USE_COVERAGE
+   AM_CFLAGS = --coverage -O0
+   XLIB = -lgcov
+ endif
+ 
+ pkgcfgdir= $(pkgdatadir)/config.d/
+ 
+ libexecdir= $(pkglibdir)/libexec/
+ 
+ pkgcfg_DATA = \
+   messenger.conf
+ 
+ plugindir = $(libdir)/gnunet
+ 
+ AM_CLFAGS = -g
+ 
+ libexec_PROGRAMS = \
+  gnunet-service-messenger \
+  $(EXP_LIBEXEC)
+ 
+ lib_LTLIBRARIES = \
+   libgnunetmessenger.la \
+   $(EXP_LIB)
+ 
+ libgnunetmessenger_la_SOURCES = \
+   messenger_api.c \
 -  messenger_api_ego.h \
+   messenger_api_contact.c messenger_api_contact.h \
+   messenger_api_contact_store.c messenger_api_contact_store.h \
++  messenger_api_peer_store.c messenger_api_peer_store.h \
+   messenger_api_message.c messenger_api_message.h \
++  messenger_api_message_kind.c messenger_api_message_kind.h \
+   messenger_api_list_tunnels.c messenger_api_list_tunnels.h \
++  messenger_api_queue_messages.c messenger_api_queue_messages.h \
+   messenger_api_util.c messenger_api_util.h \
+   messenger_api_handle.c messenger_api_handle.h \
+   messenger_api_room.c messenger_api_room.h
+ libgnunetmessenger_la_LIBADD = \
+   $(top_builddir)/src/lib/util/libgnunetutil.la \
+   $(top_builddir)/src/service/cadet/libgnunetcadet.la \
+   $(top_builddir)/src/service/identity/libgnunetidentity.la \
+   $(XLIB) \
+   $(LTLIBINTL)
+ libgnunetmessenger_la_LDFLAGS = \
+   $(GN_LIB_LDFLAGS)  \
+   -version-info 0:0:0
+ 
+ gnunet_service_messenger_SOURCES = \
+   gnunet-service-messenger.c gnunet-service-messenger.h \
+   gnunet-service-messenger_service.c gnunet-service-messenger_service.h \
+   gnunet-service-messenger_list_handles.c 
gnunet-service-messenger_list_handles.h \
+   gnunet-service-messenger_list_messages.c 
gnunet-service-messenger_list_messages.h \
+   gnunet-service-messenger_member_session.c 
gnunet-service-messenger_member_session.h \
++  gnunet-service-messenger_sender_session.h \
+   gnunet-service-messenger_member.c gnunet-service-messenger_member.h \
+   gnunet-service-messenger_member_store.c 
gnunet-service-messenger_member_store.h \
+   gnunet-service-messenger_message_handle.c 
gnunet-service-messenger_message_handle.h \
+   gnunet-service-messenger_message_kind.c 
gnunet-service-messenger_message_kind.h \
+   gnunet-service-messenger_message_recv.c 
gnunet-service-messenger_message_recv.h \
+   gnunet-service-messenger_message_send.c 
gnunet-service-messenger_message_send.h \
+   gnunet-service-messenger_message_state.c 
gnunet-service-messenger_message_state.h \
+   gnunet-service-messenger_message_store.c 
gnunet-service-messenger_message_store.h \
+   gnunet-service-messenger_operation_store.c 
gnunet-service-messenger_operation_store.h \
+   gnunet-service-messenger_operation.c gnunet-service-messenger_operation.h \
+   gnunet-service-messenger_basement.c gnunet-service-messenger_basement.h \
 -  gnunet-service-messenger_ego_store.c gnunet-service-messenger_ego_store.h \
+   gnunet-service-messenger_handle.c gnunet-service-messenger_handle.h \
+   gnunet-service-messenger_room.c gnunet-service-messenger_room.h \
+   gnunet-service-messenger_tunnel.c gnunet-service-messenger_tunnel.h
+ gnunet_service_messenger_LDADD = \
+   libgnunetmessenger.la \
+   $(top_builddir)/src/lib/util/libgnunetutil.la \
+   $(top_builddir)/src/service/cadet/libgnunetcadet.la \
+   $(top_builddir)/src/service/identity/libgnunetidentity.la \
+   $(GN_LIBINTL)
+ 
 -check_PROGRAMS = test_messenger_anonymous
++check_PROGRAMS = \
++  test_messenger_api \
++  test_messenger_anonymous
+ 
+ if ENABLE_TEST_RUN
+ AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export 
PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset 
XDG_CONFIG_HOME;
+ TESTS = \
+  $(check_PROGRAMS)
+ endif
+ 
+ test_messenger_api_SOURCES = \
+   test_messenger.c
+ test_messenger_api_LDADD = \
+   libgnunetmessenger.la \
+   $(top_builddir)/src/service/testing/libgnunettesting.la \
+   $(top_builddir)/src/lib/util/libgnunetutil.la
+ 
+ test_messenger_anonymous_SOURCES = \
+   test_messenger_anonymous.c
+ test_messenger_anonymous_LDADD = \
+   libgnunetmessenger.la \
+   $(top_builddir)/src/service/testing/libgnunettesting.la \
+   $(top_builddir)/src/lib/util/libgnunetutil.la
+ 
+ EXTRA_DIST = \
+   test_messenger_api.conf
diff --cc src/service/messenger/gnunet-messenger.c
index 000000000,9444fa12d..6258ce712
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-messenger.c
+++ b/src/service/messenger/gnunet-messenger.c
@@@ -1,0 -1,334 +1,409 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-messenger.c
+  * @brief Print information about messenger groups.
+  */
+ 
+ #include "platform.h"
+ #include <stdio.h>
+ 
+ #include "gnunet_util_lib.h"
+ #include "gnunet_messenger_service.h"
+ 
++const struct GNUNET_CONFIGURATION_Handle *config;
+ struct GNUNET_MESSENGER_Handle *messenger;
+ 
+ /**
+  * Function called whenever a message is received or sent.
+  *
+  * @param[in,out] cls Closure
+  * @param[in] room Room
+  * @param[in] sender Sender of message
+  * @param[in] message Message
+  * @param[in] hash Hash of message
+  * @param[in] flags Flags of message
+  */
+ void
+ on_message (void *cls,
+             struct GNUNET_MESSENGER_Room *room,
+             const struct GNUNET_MESSENGER_Contact *sender,
+             const struct GNUNET_MESSENGER_Message *message,
+             const struct GNUNET_HashCode *hash,
+             enum GNUNET_MESSENGER_MessageFlags flags)
+ {
+   const char *sender_name = GNUNET_MESSENGER_contact_get_name (sender);
+ 
 -  if (!sender_name)
++  if (! sender_name)
+     sender_name = "anonymous";
+ 
 -  printf ("[%s] ", GNUNET_sh2s(&(message->header.sender_id)));
++  printf ("[%s ->", GNUNET_h2s (&(message->header.previous)));
++  printf (" %s]", GNUNET_h2s (hash));
++  printf ("[%s] ", GNUNET_sh2s (&(message->header.sender_id)));
+ 
+   if (flags & GNUNET_MESSENGER_FLAG_PRIVATE)
+     printf ("*");
+ 
+   switch (message->header.kind)
+   {
+   case GNUNET_MESSENGER_KIND_JOIN:
+     {
+       printf ("* '%s' joined the room!\n", sender_name);
+       break;
+     }
+   case GNUNET_MESSENGER_KIND_NAME:
+     {
 -      printf ("* '%s' gets renamed to '%s'\n", sender_name, 
message->body.name.name);
++      printf ("* '%s' gets renamed to '%s'\n", sender_name,
++              message->body.name.name);
+       break;
+     }
+   case GNUNET_MESSENGER_KIND_LEAVE:
+     {
+       printf ("* '%s' leaves the room!\n", sender_name);
+       break;
+     }
+   case GNUNET_MESSENGER_KIND_PEER:
+     {
 -      printf ("* '%s' opened the room on: %s\n", sender_name, GNUNET_i2s_full 
(&(message->body.peer.peer)));
++      printf ("* '%s' opened the room on: %s\n", sender_name,
++              GNUNET_i2s_full (&(message->body.peer.peer)));
+       break;
+     }
+   case GNUNET_MESSENGER_KIND_TEXT:
+     {
+       if (flags & GNUNET_MESSENGER_FLAG_SENT)
+         printf (">");
+       else
+         printf ("<");
+ 
+       printf (" '%s' says: \"%s\"\n", sender_name, message->body.text.text);
+       break;
+     }
+   default:
+     {
 -      printf ("~ message: %s\n", 
GNUNET_MESSENGER_name_of_kind(message->header.kind));
++      printf ("~ message: %s\n",
++              GNUNET_MESSENGER_name_of_kind (message->header.kind));
+       break;
+     }
+   }
++
++  if ((GNUNET_MESSENGER_KIND_JOIN == message->header.kind) &&
++      (flags & GNUNET_MESSENGER_FLAG_SENT))
++  {
++    const char *name = GNUNET_MESSENGER_get_name (messenger);
++
++    if (! name)
++      return;
++
++    struct GNUNET_MESSENGER_Message response;
++    response.header.kind = GNUNET_MESSENGER_KIND_NAME;
++    response.body.name.name = GNUNET_strdup (name);
++
++    GNUNET_MESSENGER_send_message (room, &response, NULL);
++
++    GNUNET_free (response.body.name.name);
++  }
+ }
+ 
++
+ struct GNUNET_SCHEDULER_Task *read_task;
++struct GNUNET_IDENTITY_EgoLookup *ego_lookup;
+ 
+ /**
+  * Task to shut down this application.
+  *
+  * @param[in,out] cls Closure
+  */
+ static void
+ shutdown_hook (void *cls)
+ {
+   struct GNUNET_MESSENGER_Room *room = cls;
+ 
+   if (read_task)
+     GNUNET_SCHEDULER_cancel (read_task);
+ 
+   if (room)
+     GNUNET_MESSENGER_close_room (room);
+ 
+   if (messenger)
+     GNUNET_MESSENGER_disconnect (messenger);
++
++  if (ego_lookup)
++    GNUNET_IDENTITY_ego_lookup_cancel (ego_lookup);
+ }
+ 
++
+ static void
+ listen_stdio (void *cls);
+ 
+ #define MAX_BUFFER_SIZE 60000
+ 
+ static int
+ iterate_send_private_message (void *cls,
+                               struct GNUNET_MESSENGER_Room *room,
+                               const struct GNUNET_MESSENGER_Contact *contact)
+ {
+   struct GNUNET_MESSENGER_Message *message = cls;
+ 
 -  if (GNUNET_MESSENGER_contact_get_key(contact))
++  if (GNUNET_MESSENGER_contact_get_key (contact))
+     GNUNET_MESSENGER_send_message (room, message, contact);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ int private_mode;
+ 
+ /**
+  * Task run in stdio mode, after some data is available at stdin.
+  *
+  * @param[in,out] cls Closure
+  */
+ static void
+ read_stdio (void *cls)
+ {
+   read_task = NULL;
+ 
+   char buffer[MAX_BUFFER_SIZE];
+   ssize_t length;
+ 
+   length = read (0, buffer, MAX_BUFFER_SIZE);
+ 
+   if ((length <= 0) || (length >= MAX_BUFFER_SIZE))
+   {
+     GNUNET_SCHEDULER_shutdown ();
+     return;
+   }
+ 
+   if (buffer[length - 1] == '\n')
+     buffer[length - 1] = '\0';
+   else
+     buffer[length] = '\0';
+ 
+   struct GNUNET_MESSENGER_Room *room = cls;
+ 
+   struct GNUNET_MESSENGER_Message message;
+   message.header.kind = GNUNET_MESSENGER_KIND_TEXT;
+   message.body.text.text = buffer;
+ 
+   if (GNUNET_YES == private_mode)
 -    GNUNET_MESSENGER_iterate_members(room, iterate_send_private_message, 
&message);
++    GNUNET_MESSENGER_iterate_members (room, iterate_send_private_message,
++                                      &message);
+   else
+     GNUNET_MESSENGER_send_message (room, &message, NULL);
+ 
+   read_task = GNUNET_SCHEDULER_add_now (listen_stdio, cls);
+ }
+ 
++
+ /**
+  * Wait for input on STDIO and send it out over the #ch.
+  *
+  * @param[in,out] cls Closure
+  */
+ static void
+ listen_stdio (void *cls)
+ {
+   read_task = NULL;
+ 
+   struct GNUNET_NETWORK_FDSet *rs = GNUNET_NETWORK_fdset_create ();
+ 
+   GNUNET_NETWORK_fdset_set_native (rs, 0);
+ 
+   read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                            GNUNET_TIME_UNIT_FOREVER_REL, rs,
+                                            NULL, &read_stdio, cls);
+ 
+   GNUNET_NETWORK_fdset_destroy (rs);
+ }
+ 
++
+ /**
+  * Initial task to startup application.
+  *
+  * @param[in,out] cls Closure
+  */
+ static void
+ idle (void *cls)
+ {
+   struct GNUNET_MESSENGER_Room *room = cls;
+ 
+   printf ("* You joined the room.\n");
+ 
+   read_task = GNUNET_SCHEDULER_add_now (listen_stdio, room);
+ }
+ 
++
+ char *door_id;
+ char *ego_name;
+ char *room_key;
+ 
+ struct GNUNET_SCHEDULER_Task *shutdown_task;
+ 
+ /**
+  * Function called when an identity is retrieved.
+  *
+  * @param[in,out] cls Closure
+  * @param[in,out] handle Handle of messenger service
+  */
+ static void
+ on_identity (void *cls,
+              struct GNUNET_MESSENGER_Handle *handle)
+ {
+   struct GNUNET_HashCode key;
+   memset (&key, 0, sizeof(key));
+ 
+   if (room_key)
+     GNUNET_CRYPTO_hash (room_key, strlen (room_key), &key);
+ 
+   struct GNUNET_PeerIdentity door_peer;
+   struct GNUNET_PeerIdentity *door = NULL;
+ 
+   if ((door_id) &&
 -      (GNUNET_OK == GNUNET_CRYPTO_eddsa_public_key_from_string (door_id, 
strlen (door_id), &(door_peer.public_key))))
++      (GNUNET_OK == GNUNET_CRYPTO_eddsa_public_key_from_string (door_id,
++                                                                strlen (
++                                                                  door_id),
++                                                                &(door_peer.
++                                                                  
public_key))))
+     door = &door_peer;
+ 
+   const char *name = GNUNET_MESSENGER_get_name (handle);
+ 
 -  if (!name)
++  if (! name)
+     name = "anonymous";
+ 
+   printf ("* Welcome to the messenger, '%s'!\n", name);
+ 
+   struct GNUNET_MESSENGER_Room *room;
+ 
+   if (door)
+   {
+     printf ("* You try to entry a room...\n");
+ 
+     room = GNUNET_MESSENGER_enter_room (messenger, door, &key);
+   }
+   else
+   {
+     printf ("* You try to open a room...\n");
+ 
+     room = GNUNET_MESSENGER_open_room (messenger, &key);
+   }
+ 
+   GNUNET_SCHEDULER_cancel (shutdown_task);
+ 
+   shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, room);
+ 
 -  if (!room)
++  if (! room)
+     GNUNET_SCHEDULER_shutdown ();
+   else
+   {
 -    struct GNUNET_MESSENGER_Message message;
 -    message.header.kind = GNUNET_MESSENGER_KIND_NAME;
 -    message.body.name.name = GNUNET_strdup(name);
++    GNUNET_SCHEDULER_add_delayed_with_priority (
++      GNUNET_TIME_relative_get_zero_ (),
++      GNUNET_SCHEDULER_PRIORITY_IDLE,
++      idle, room);
++  }
++}
+ 
 -    GNUNET_MESSENGER_send_message (room, &message, NULL);
 -    GNUNET_free(message.body.name.name);
+ 
 -    GNUNET_SCHEDULER_add_delayed_with_priority 
(GNUNET_TIME_relative_get_zero_ (), GNUNET_SCHEDULER_PRIORITY_IDLE, idle,
 -                                                room);
 -  }
++static void
++on_ego_lookup (void *cls,
++               struct GNUNET_IDENTITY_Ego *ego)
++{
++  ego_lookup = NULL;
++
++  const struct GNUNET_CRYPTO_PrivateKey *key;
++  key = ego ? GNUNET_IDENTITY_ego_get_private_key (ego) : NULL;
++
++  messenger = GNUNET_MESSENGER_connect (config, ego_name, key, &on_message,
++                                        NULL);
++
++  on_identity (NULL, messenger);
+ }
+ 
++
+ /**
+  * Main function that will be run by the scheduler.
+  *
+  * @param[in/out] cls closure
+  * @param[in] args remaining command-line arguments
+  * @param[in] cfgfile name of the configuration file used (for saving, can be 
NULL!)
+  * @param[in] cfg configuration
+  */
+ static void
+ run (void *cls,
 -     char *const*args,
++     char *const *args,
+      const char *cfgfile,
+      const struct GNUNET_CONFIGURATION_Handle *cfg)
+ {
 -  messenger = GNUNET_MESSENGER_connect (cfg, ego_name, &on_identity, NULL, 
&on_message, NULL);
++  config = cfg;
++
++  if (ego_name)
++  {
++    ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &on_ego_lookup,
++                                             NULL);
++    messenger = NULL;
++  }
++  else
++  {
++    ego_lookup = NULL;
++    messenger = GNUNET_MESSENGER_connect (cfg, NULL, NULL, &on_message, NULL);
++  }
+ 
+   shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, NULL);
++
++  if (messenger)
++    on_identity (NULL, messenger);
+ }
+ 
++
+ /**
+  * The main function to obtain messenger information.
+  *
+  * @param[in] argc number of arguments from the command line
+  * @param[in] argv command line arguments
+  * @return #EXIT_SUCCESS ok, #EXIT_FAILURE on error
+  */
+ int
+ main (int argc,
+       char **argv)
+ {
 -  const char *description = "Open and connect to rooms using the MESSENGER to 
chat.";
 -
 -  struct GNUNET_GETOPT_CommandLineOption options[] =
 -  {
 -    GNUNET_GETOPT_option_string ('d', "door", "PEERIDENTITY", "peer identity 
to entry into the room", &door_id),
 -    GNUNET_GETOPT_option_string ('e', "ego", "IDENTITY", "identity to use for 
messaging", &ego_name),
 -    GNUNET_GETOPT_option_string ('r', "room", "ROOMKEY", "key of the room to 
connect to", &room_key),
 -    GNUNET_GETOPT_option_flag ('p', "private", "flag to enable private mode", 
&private_mode),
++  const char *description =
++    "Open and connect to rooms using the MESSENGER to chat.";
++
++  struct GNUNET_GETOPT_CommandLineOption options[] = {
++    GNUNET_GETOPT_option_string ('d', "door", "PEERIDENTITY",
++                                 "peer identity to entry into the room",
++                                 &door_id),
++    GNUNET_GETOPT_option_string ('e', "ego", "IDENTITY",
++                                 "identity to use for messaging",
++                                 &ego_name),
++    GNUNET_GETOPT_option_string ('r', "room", "ROOMKEY",
++                                 "key of the room to connect to",
++                                 &room_key),
++    GNUNET_GETOPT_option_flag ('p', "private", "flag to enable private mode",
++                               &private_mode),
+     GNUNET_GETOPT_OPTION_END
+   };
+ 
 -  return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-messenger\0", 
gettext_noop(description), options, &run,
 -  NULL) ? EXIT_SUCCESS : EXIT_FAILURE);
++  return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-messenger\0",
++                                           gettext_noop (description), 
options,
++                                           &run,
++                                           NULL) ? EXIT_SUCCESS : 
EXIT_FAILURE);
+ }
diff --cc src/service/messenger/gnunet-service-messenger.c
index 000000000,fedaa2f60..a6bc41c78
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger.c
+++ b/src/service/messenger/gnunet-service-messenger.c
@@@ -1,0 -1,476 +1,495 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger.c
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "gnunet-service-messenger.h"
+ 
+ #include "gnunet-service-messenger_handle.h"
 -#include "gnunet-service-messenger_message_kind.h"
+ #include "gnunet-service-messenger_service.h"
+ #include "messenger_api_message.h"
++#include "messenger_api_message_kind.h"
+ 
+ struct GNUNET_MESSENGER_Client
+ {
+   struct GNUNET_SERVICE_Client *client;
+   struct GNUNET_MESSENGER_SrvHandle *handle;
+ };
+ 
+ struct GNUNET_MESSENGER_Service *messenger;
+ 
 -static int
 -check_create (void *cls,
 -              const struct GNUNET_MESSENGER_CreateMessage *msg)
 -{
 -  GNUNET_MQ_check_zero_termination (msg);
 -  return GNUNET_OK;
 -}
 -
+ static void
+ handle_create (void *cls,
+                const struct GNUNET_MESSENGER_CreateMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = cls;
+ 
 -  const char *name = ((const char*) msg) + sizeof(*msg);
 -
 -  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Handle created with name: %s\n", 
name);
 -
 -  setup_srv_handle_name (msg_client->handle, strlen (name) > 0 ? name : NULL);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Handle created\n");
+ 
+   GNUNET_SERVICE_client_continue (msg_client->client);
+ }
+ 
 -static void
 -handle_update (void *cls,
 -               const struct GNUNET_MESSENGER_UpdateMessage *msg)
 -{
 -  struct GNUNET_MESSENGER_Client *msg_client = cls;
 -
 -  update_srv_handle (msg_client->handle);
 -
 -  GNUNET_SERVICE_client_continue (msg_client->client);
 -}
+ 
+ static void
+ handle_destroy (void *cls,
+                 const struct GNUNET_MESSENGER_DestroyMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = cls;
+ 
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Handle destroyed\n");
++
+   GNUNET_SERVICE_client_drop (msg_client->client);
+ }
+ 
++
+ static int
 -check_set_name (void *cls,
 -                const struct GNUNET_MESSENGER_NameMessage *msg)
++check_room_initial_key (const struct GNUNET_MESSENGER_RoomMessage *msg)
+ {
 -  GNUNET_MQ_check_zero_termination (msg);
 -  return GNUNET_OK;
++  const uint16_t full_length = ntohs (msg->header.size);
++
++  if (full_length < sizeof(*msg))
++    return GNUNET_NO;
++
++  const uint16_t msg_length = full_length - sizeof(*msg);
++  const char *msg_buffer = ((const char*) msg) + sizeof(*msg);
++
++  if (0 == msg_length)
++    return GNUNET_OK;
++
++  struct GNUNET_CRYPTO_PublicKey key;
++  size_t key_len;
++
++  if (GNUNET_OK != GNUNET_CRYPTO_read_public_key_from_buffer (msg_buffer,
++                                                              msg_length,
++                                                              &key, &key_len))
++    return GNUNET_NO;
++
++  return key_len == msg_length ? GNUNET_OK : GNUNET_NO;
+ }
+ 
++
+ static void
 -handle_set_name (void *cls,
 -                 const struct GNUNET_MESSENGER_NameMessage *msg)
++initialize_handle_via_key (struct GNUNET_MESSENGER_SrvHandle *handle,
++                           const struct GNUNET_MESSENGER_RoomMessage *msg)
+ {
 -  struct GNUNET_MESSENGER_Client *msg_client = cls;
++  GNUNET_assert (handle);
+ 
 -  const char *name = ((const char*) msg) + sizeof(*msg);
++  const uint16_t full_length = ntohs (msg->header.size);
++  const uint16_t msg_length = full_length - sizeof(*msg);
++  const char *msg_buffer = ((const char*) msg) + sizeof(*msg);
+ 
 -  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Handles name is now: %s\n", name);
++  if (msg_length > 0)
++  {
++    struct GNUNET_CRYPTO_PublicKey key;
++    size_t key_len;
++
++    if (GNUNET_OK == GNUNET_CRYPTO_read_public_key_from_buffer (msg_buffer,
++                                                                msg_length,
++                                                                &key,
++                                                                &key_len))
++      set_srv_handle_key (handle, &key);
++    else
++      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                  "Initialization failed while reading invalid key!\n");
++  }
++  else
++    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Initialization is missing key!\n");
++}
+ 
 -  set_srv_handle_name (msg_client->handle, name);
+ 
 -  GNUNET_SERVICE_client_continue (msg_client->client);
++static int
++check_room_open (void *cls,
++                 const struct GNUNET_MESSENGER_RoomMessage *msg)
++{
++  return check_room_initial_key (msg);
+ }
+ 
++
+ static void
+ handle_room_open (void *cls,
+                   const struct GNUNET_MESSENGER_RoomMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = cls;
+ 
++  initialize_handle_via_key (msg_client->handle, msg);
++
+   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Opening room: %s\n", GNUNET_h2s (
+                 &(msg->key)));
+ 
+   if (GNUNET_YES == open_srv_handle_room (msg_client->handle, &(msg->key)))
+   {
+     const struct GNUNET_ShortHashCode *member_id = get_srv_handle_member_id (
+       msg_client->handle, &(msg->key));
+ 
+     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Opening room with member id: %s\n",
+                 GNUNET_sh2s (member_id));
+ 
+     struct GNUNET_MESSENGER_RoomMessage *response;
+     struct GNUNET_MQ_Envelope *env;
+ 
+     env = GNUNET_MQ_msg (response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN);
+     GNUNET_memcpy (&(response->key), &(msg->key), sizeof(msg->key));
+     GNUNET_MQ_send (msg_client->handle->mq, env);
+   }
+   else
+     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Opening room failed: %s\n",
+                 GNUNET_h2s (&(msg->key)));
+ 
+   GNUNET_SERVICE_client_continue (msg_client->client);
+ }
+ 
++
++static int
++check_room_entry (void *cls,
++                  const struct GNUNET_MESSENGER_RoomMessage *msg)
++{
++  return check_room_initial_key (msg);
++}
++
++
+ static void
+ handle_room_entry (void *cls,
+                    const struct GNUNET_MESSENGER_RoomMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = cls;
+ 
++  initialize_handle_via_key (msg_client->handle, msg);
++
+   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entering room: %s, %s\n", GNUNET_h2s (
+                 &(msg->key)), GNUNET_i2s (&(msg->door)));
+ 
+   if (GNUNET_YES == entry_srv_handle_room (msg_client->handle, &(msg->door),
+                                            &(msg->key)))
+   {
+     const struct GNUNET_ShortHashCode *member_id = get_srv_handle_member_id (
+       msg_client->handle, &(msg->key));
+ 
+     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entering room with member id: %s\n",
+                 GNUNET_sh2s (member_id));
+ 
+     struct GNUNET_MESSENGER_RoomMessage *response;
+     struct GNUNET_MQ_Envelope *env;
+ 
+     env = GNUNET_MQ_msg (response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY);
+     GNUNET_memcpy (&(response->door), &(msg->door), sizeof(msg->door));
+     GNUNET_memcpy (&(response->key), &(msg->key), sizeof(msg->key));
+     GNUNET_MQ_send (msg_client->handle->mq, env);
+   }
+   else
+     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Entrance into room failed: %s, 
%s\n",
+                 GNUNET_h2s (&(msg->key)),
+                 GNUNET_i2s (&(msg->door)));
+ 
+   GNUNET_SERVICE_client_continue (msg_client->client);
+ }
+ 
++
+ static void
+ handle_room_close (void *cls,
+                    const struct GNUNET_MESSENGER_RoomMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = cls;
+ 
+   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Closing room: %s\n", GNUNET_h2s (
+                 &(msg->key)));
+ 
+   if (GNUNET_YES == close_srv_handle_room (msg_client->handle, &(msg->key)))
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Closing room succeeded: %s\n",
+                 GNUNET_h2s (&(msg->key)));
+ 
+     struct GNUNET_MESSENGER_RoomMessage *response;
+     struct GNUNET_MQ_Envelope *env;
+ 
+     env = GNUNET_MQ_msg (response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE);
+     GNUNET_memcpy (&(response->key), &(msg->key), sizeof(msg->key));
+     GNUNET_MQ_send (msg_client->handle->mq, env);
+   }
+   else
+     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Closing room failed: %s\n",
+                 GNUNET_h2s (&(msg->key)));
+ 
+   GNUNET_SERVICE_client_continue (msg_client->client);
+ }
+ 
++
+ static int
+ check_send_message (void *cls,
+                     const struct GNUNET_MESSENGER_SendMessage *msg)
+ {
+   const uint16_t full_length = ntohs (msg->header.size);
+ 
+   if (full_length < sizeof(*msg))
+     return GNUNET_NO;
+ 
 -  const enum GNUNET_MESSENGER_MessageFlags flags = (
 -    (enum GNUNET_MESSENGER_MessageFlags) (msg->flags)
 -    );
 -
 -  const uint16_t length = full_length - sizeof(*msg);
 -  const char *buffer = ((const char*) msg) + sizeof(*msg);
 -  struct GNUNET_CRYPTO_PublicKey public_key;
 -
 -
 -  size_t key_length = 0;
 -
 -  if ((flags & GNUNET_MESSENGER_FLAG_PRIVATE))
 -    if (GNUNET_SYSERR ==
 -        GNUNET_CRYPTO_read_public_key_from_buffer (buffer, length,
 -                                                     &public_key,
 -                                                     &key_length))
 -      return GNUNET_NO;
 -
 -  const uint16_t msg_length = length - key_length;
 -  const char *msg_buffer = buffer + key_length;
++  const uint16_t msg_length = full_length - sizeof(*msg);
++  const char *msg_buffer = ((const char*) msg) + sizeof(*msg);
+ 
+   struct GNUNET_MESSENGER_Message message;
+ 
 -  if (length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN, 
GNUNET_NO))
++  if (msg_length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN,
++                                          GNUNET_YES))
+     return GNUNET_NO;
+ 
 -  if (GNUNET_YES != decode_message (&message, msg_length, msg_buffer, 
GNUNET_NO,
++  if (GNUNET_YES != decode_message (&message, msg_length, msg_buffer,
++                                    GNUNET_YES,
+                                     NULL))
+     return GNUNET_NO;
+ 
+   const int allowed = filter_message_sending (&message);
+ 
+   cleanup_message (&message);
 -  return GNUNET_YES == allowed? GNUNET_OK : GNUNET_NO;
++  return GNUNET_SYSERR != allowed? GNUNET_OK : GNUNET_NO;
+ }
+ 
++
+ static void
+ handle_send_message (void *cls,
+                      const struct GNUNET_MESSENGER_SendMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = cls;
+ 
 -  const enum GNUNET_MESSENGER_MessageFlags flags = (
 -    (enum GNUNET_MESSENGER_MessageFlags) (msg->flags)
 -    );
 -
+   const struct GNUNET_HashCode *key = &(msg->key);
 -  const char *buffer = ((const char*) msg) + sizeof(*msg);
 -
 -  const uint16_t length = ntohs (msg->header.size) - sizeof(*msg);
 -  size_t key_length = 0;
 -
 -  struct GNUNET_CRYPTO_PublicKey public_key;
 -
 -  if (flags & GNUNET_MESSENGER_FLAG_PRIVATE)
 -  {
 -    GNUNET_assert (GNUNET_SYSERR !=
 -                   GNUNET_CRYPTO_read_public_key_from_buffer (buffer,
 -                                                                length,
 -                                                                &public_key,
 -                                                                &key_length));
 -  }
 -  const uint16_t msg_length = length - key_length;
 -  const char*msg_buffer = buffer + key_length;
++  const char *msg_buffer = ((const char*) msg) + sizeof(*msg);
++  const uint16_t msg_length = ntohs (msg->header.size) - sizeof(*msg);
+ 
+   struct GNUNET_MESSENGER_Message message;
 -  decode_message (&message, msg_length, msg_buffer, GNUNET_NO, NULL);
++  decode_message (&message, msg_length, msg_buffer, GNUNET_YES, NULL);
+ 
 -  if ((flags & GNUNET_MESSENGER_FLAG_PRIVATE) &&
 -      (GNUNET_YES != encrypt_message (&message, &public_key)))
 -  {
 -    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 -                "Encrypting message failed: Message got dropped!\n");
 -
 -    goto end_handling;
 -  }
 -
 -  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message: %s to %s\n",
 -              GNUNET_MESSENGER_name_of_kind (message.header.kind), GNUNET_h2s 
(
 -                key));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message: %s to %s (by %s)\n",
++              GNUNET_MESSENGER_name_of_kind (message.header.kind),
++              GNUNET_h2s (key),
++              GNUNET_sh2s (&(message.header.sender_id)));
+ 
+   if (GNUNET_YES != send_srv_handle_message (msg_client->handle, key, 
&message))
+     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Sending message failed: %s to %s\n",
+                 GNUNET_MESSENGER_name_of_kind (message.header.kind),
+                 GNUNET_h2s (key));
+ 
 -  end_handling:
+   cleanup_message (&message);
+ 
+   GNUNET_SERVICE_client_continue (msg_client->client);
+ }
+ 
++
+ static void
+ callback_found_message (void *cls,
+                         struct GNUNET_MESSENGER_SrvRoom *room,
+                         const struct GNUNET_MESSENGER_Message *message,
+                         const struct GNUNET_HashCode *hash)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = cls;
+ 
+   if (! message)
+   {
 -    send_srv_room_message (room, msg_client->handle, create_message_request (
 -                             hash));
++    struct GNUNET_MESSENGER_GetMessage *response;
++    struct GNUNET_MQ_Envelope *env;
++
++    env = GNUNET_MQ_msg (response,
++                         GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE);
++    GNUNET_memcpy (&(response->key), &(room->key), sizeof(room->key));
++    GNUNET_memcpy (&(response->hash), hash, sizeof(*hash));
++    GNUNET_MQ_send (msg_client->handle->mq, env);
+     return;
+   }
+ 
 -  struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store 
(room);
++  struct GNUNET_MESSENGER_SenderSession session;
++
++  if (GNUNET_YES == is_peer_message (message))
++  {
++    struct GNUNET_MESSENGER_PeerStore *store = get_srv_room_peer_store (room);
+ 
 -  struct GNUNET_MESSENGER_Member *member = get_store_member_of (store, 
message);
++    session.peer = get_store_peer_of (store, message, hash);
+ 
 -  if (! member)
++    if (! session.peer)
++      return;
++  }
++  else
+   {
 -    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Sender of message (%s) unknown!\n",
 -                GNUNET_h2s (hash));
 -    return;
++    struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store (
++      room);
++    struct GNUNET_MESSENGER_Member *member = get_store_member_of (store,
++                                                                  message);
++
++    if (! member)
++    {
++      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Sender of message (%s) 
unknown!\n",
++                  GNUNET_h2s (hash));
++      return;
++    }
++
++    session.member = get_member_session_of (member, message, hash);
++
++    if (! session.member)
++      return;
+   }
+ 
 -  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of (
 -    member, message, hash);
 -
 -  if (session)
 -    notify_srv_handle_message (msg_client->handle, room, session, message,
 -                               hash);
++  notify_srv_handle_message (msg_client->handle, room, &session, message,
++                             hash);
+ }
+ 
++
+ static void
+ handle_get_message (void *cls,
+                     const struct GNUNET_MESSENGER_GetMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = cls;
+ 
+   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting message from room: %s\n",
+               GNUNET_h2s (&(msg->key)));
+ 
+   struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (messenger,
+                                                             &(msg->key));
+ 
+   if (! room)
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Room not found: %s\n", GNUNET_h2s (
+                   &(msg->key)));
+     goto end_handling;
+   }
+ 
+   struct GNUNET_MESSENGER_MemberStore *member_store =
+     get_srv_room_member_store (room);
+ 
+   struct GNUNET_MESSENGER_Member *member = get_store_member (member_store,
+                                                              
get_srv_handle_member_id (
+                                                                msg_client->
+                                                                handle,
+                                                                &(msg->key)
+                                                                ));
+ 
+   if (! member)
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 "Member not valid to request a message!\n");
+     goto end_handling;
+   }
+ 
++  const struct GNUNET_CRYPTO_PublicKey *pubkey = get_srv_handle_key (
++    msg_client->handle);
++
++  if (! pubkey)
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Handle needs to have a public key to request a message!\n");
++    goto end_handling;
++  }
++
+   struct GNUNET_MESSENGER_MemberSession *session = get_member_session (member,
 -                                                                       &(
 -                                                                         
get_srv_handle_ego (
 -                                                                           
msg_client
 -                                                                           ->
 -                                                                           
handle)
 -                                                                         
->pub));
++                                                                       
pubkey);
+ 
+   if (! session)
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 "Session not valid to request a message!\n");
+     goto end_handling;
+   }
+ 
+   request_srv_room_message (room, &(msg->hash), session, 
callback_found_message,
+                             msg_client);
+ 
 -  end_handling:
++end_handling:
+   GNUNET_SERVICE_client_continue (msg_client->client);
+ }
+ 
++
+ static void*
+ callback_client_connect (void *cls,
+                          struct GNUNET_SERVICE_Client *client,
+                          struct GNUNET_MQ_Handle *mq)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = GNUNET_new (struct
+                                                            
GNUNET_MESSENGER_Client);
+ 
+   msg_client->client = client;
+   msg_client->handle = add_service_handle (messenger, mq);
+ 
+   return msg_client;
+ }
+ 
++
+ static void
+ callback_client_disconnect (void *cls,
+                             struct GNUNET_SERVICE_Client *client,
+                             void *internal_cls)
+ {
+   struct GNUNET_MESSENGER_Client *msg_client = internal_cls;
+ 
+   remove_service_handle (messenger, msg_client->handle);
+ 
+   GNUNET_free (msg_client);
+ }
+ 
++
+ /**
+  * Setup MESSENGER internals.
+  *
+  * @param[in/out] cls closure
+  * @param[in] config configuration to use
+  * @param[in/out] service the initialized service
+  */
+ static void
+ run (void *cls,
+      const struct GNUNET_CONFIGURATION_Handle *config,
+      struct GNUNET_SERVICE_Handle *service)
+ {
+   messenger = create_service (config, service);
+ 
+   if (! messenger)
+     GNUNET_SCHEDULER_shutdown ();
+ }
+ 
++
+ /**
+  * Define "main" method using service macro.
+  */
+ GNUNET_SERVICE_MAIN (
+   GNUNET_MESSENGER_SERVICE_NAME,
+   GNUNET_SERVICE_OPTION_NONE,
+   &run,
+   &callback_client_connect,
+   &callback_client_disconnect,
+   NULL,
 -  GNUNET_MQ_hd_var_size (create,
 -                         GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE, 
struct
 -                         GNUNET_MESSENGER_CreateMessage, NULL),
 -  GNUNET_MQ_hd_fixed_size (update,
 -                           GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE,
++  GNUNET_MQ_hd_fixed_size (create,
++                           GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE,
+                            struct
 -                           GNUNET_MESSENGER_UpdateMessage, NULL),
++                           GNUNET_MESSENGER_CreateMessage, NULL),
+   GNUNET_MQ_hd_fixed_size (destroy,
+                            GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY,
+                            struct
+                            GNUNET_MESSENGER_DestroyMessage, NULL),
 -  GNUNET_MQ_hd_var_size (set_name,
 -                         GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME,
 -                         struct
 -                         GNUNET_MESSENGER_NameMessage, NULL),
 -  GNUNET_MQ_hd_fixed_size (room_open, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN,
 -                           struct GNUNET_MESSENGER_RoomMessage, NULL),
 -  GNUNET_MQ_hd_fixed_size (room_entry, 
GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY,
 -                           struct GNUNET_MESSENGER_RoomMessage, NULL),
++  GNUNET_MQ_hd_var_size (room_open, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN,
++                         struct GNUNET_MESSENGER_RoomMessage, NULL),
++  GNUNET_MQ_hd_var_size (room_entry, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY,
++                         struct GNUNET_MESSENGER_RoomMessage, NULL),
+   GNUNET_MQ_hd_fixed_size (room_close, 
GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE,
+                            struct GNUNET_MESSENGER_RoomMessage, NULL),
+   GNUNET_MQ_hd_var_size (send_message,
+                          GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE, 
struct
+                          GNUNET_MESSENGER_SendMessage, NULL),
+   GNUNET_MQ_hd_fixed_size (get_message,
+                            GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE,
+                            struct
+                            GNUNET_MESSENGER_GetMessage, NULL),
+   GNUNET_MQ_handler_end ());
diff --cc src/service/messenger/gnunet-service-messenger_ego_store.c
index 000000000,a1ffdddab..e7faa9eed
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_ego_store.c
+++ b/src/service/messenger/gnunet-service-messenger_ego_store.c
@@@ -1,0 -1,482 +1,527 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2022 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_ego_store.c
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "gnunet-service-messenger_ego_store.h"
+ 
+ #include "gnunet-service-messenger_handle.h"
+ 
+ static void
+ callback_update_ego (void *cls,
+                      struct GNUNET_IDENTITY_Ego *ego,
+                      void **ctx,
+                      const char *identifier)
+ {
 -  if ((!ctx) || (!identifier))
++  if ((! ctx) || (! identifier))
+     return;
+ 
+   struct GNUNET_MESSENGER_EgoStore *store = cls;
+ 
+   if (ego)
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New ego in use: '%s'\n", 
identifier);
 -    update_store_ego (store, identifier, GNUNET_IDENTITY_ego_get_private_key 
(ego));
++    update_store_ego (store, identifier,
++                      GNUNET_IDENTITY_ego_get_private_key (ego));
+   }
+   else
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego got deleted: '%s'\n", 
identifier);
+     delete_store_ego (store, identifier);
+   }
+ }
+ 
++
+ void
 -init_ego_store(struct GNUNET_MESSENGER_EgoStore *store,
 -               const struct GNUNET_CONFIGURATION_Handle *config)
++init_ego_store (struct GNUNET_MESSENGER_EgoStore *store,
++                const struct GNUNET_CONFIGURATION_Handle *config)
+ {
+   GNUNET_assert ((store) && (config));
+ 
+   store->cfg = config;
 -  store->identity = GNUNET_IDENTITY_connect (config, &callback_update_ego, 
store);
++  store->identity = GNUNET_IDENTITY_connect (config, &callback_update_ego,
++                                             store);
+   store->egos = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
+   store->handles = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
+ 
+   store->lu_start = NULL;
+   store->lu_end = NULL;
+ 
+   store->op_start = NULL;
+   store->op_end = NULL;
+ }
+ 
++
+ static int
+ iterate_destroy_egos (void *cls,
+                       const struct GNUNET_HashCode *key,
+                       void *value)
+ {
+   struct GNUNET_MESSENGER_Ego *ego = value;
 -  GNUNET_free(ego);
++  GNUNET_free (ego);
+   return GNUNET_YES;
+ }
+ 
++
+ void
 -clear_ego_store(struct GNUNET_MESSENGER_EgoStore *store)
++clear_ego_store (struct GNUNET_MESSENGER_EgoStore *store)
+ {
+   GNUNET_assert (store);
+ 
+   struct GNUNET_MESSENGER_EgoOperation *op;
+ 
+   while (store->op_start)
+   {
+     op = store->op_start;
+ 
+     GNUNET_IDENTITY_cancel (op->operation);
+     GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, op);
+ 
+     if (op->identifier)
+       GNUNET_free (op->identifier);
+ 
+     GNUNET_free (op);
+   }
+ 
+   struct GNUNET_MESSENGER_EgoLookup *lu;
+ 
+   while (store->lu_start)
+   {
+     lu = store->lu_start;
+ 
 -    GNUNET_IDENTITY_ego_lookup_cancel(lu->lookup);
++    GNUNET_IDENTITY_ego_lookup_cancel (lu->lookup);
+     GNUNET_CONTAINER_DLL_remove (store->lu_start, store->lu_end, lu);
+ 
+     if (lu->identifier)
 -      GNUNET_free(lu->identifier);
++      GNUNET_free (lu->identifier);
+ 
+     GNUNET_free (lu);
+   }
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (store->egos, iterate_destroy_egos, 
NULL);
++  GNUNET_CONTAINER_multihashmap_iterate (store->egos,
++                                         iterate_destroy_egos,
++                                         NULL);
+   GNUNET_CONTAINER_multihashmap_destroy (store->egos);
 -
+   GNUNET_CONTAINER_multihashmap_destroy (store->handles);
+ 
+   if (store->identity)
+   {
+     GNUNET_IDENTITY_disconnect (store->identity);
+ 
+     store->identity = NULL;
+   }
+ }
+ 
++
+ static int
+ iterate_create_ego (void *cls,
+                     const struct GNUNET_HashCode *key,
+                     void *value)
+ {
+   struct GNUNET_MESSENGER_SrvHandle *handle = value;
+   set_srv_handle_ego (handle, (struct GNUNET_MESSENGER_Ego*) cls);
+   return GNUNET_YES;
+ }
+ 
++
+ static void
+ callback_ego_create (void *cls,
+                      const struct GNUNET_CRYPTO_PrivateKey *key,
+                      enum GNUNET_ErrorCode ec)
+ {
+   struct GNUNET_MESSENGER_EgoOperation *element = cls;
+   struct GNUNET_MESSENGER_EgoStore *store = element->store;
+ 
+   GNUNET_assert (element->identifier);
+ 
+   /**
+    * FIXME: This is dangerous, please handle errors
+    */
+   if (GNUNET_EC_NONE != ec)
+     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n",
+                 GNUNET_ErrorCode_get_hint (ec));
+ 
+   if (key)
+   {
 -    struct GNUNET_MESSENGER_Ego *msg_ego = update_store_ego (store, 
element->identifier, key);
++    struct GNUNET_MESSENGER_Ego *msg_ego = update_store_ego (store,
++                                                             
element->identifier,
++                                                             key);
+ 
+     struct GNUNET_HashCode hash;
 -    GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), 
&hash);
++    GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier),
++                        &hash);
+ 
 -    GNUNET_CONTAINER_multihashmap_get_multiple (store->handles, &hash, 
iterate_create_ego, msg_ego);
++    GNUNET_CONTAINER_multihashmap_get_multiple (store->handles, &hash,
++                                                iterate_create_ego, msg_ego);
+   }
+   else
+     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Creating ego failed!\n");
+ 
+   GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element);
+   GNUNET_free (element->identifier);
+   GNUNET_free (element);
+ }
+ 
++
+ void
+ create_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
+                   const char *identifier)
+ {
+   GNUNET_assert ((store) && (identifier));
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store create ego: %s\n", identifier);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store create ego: %s\n", identifier);
+ 
 -  struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct 
GNUNET_MESSENGER_EgoOperation);
++  struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct
++                                                              
GNUNET_MESSENGER_EgoOperation);
+ 
+   element->store = store;
+   element->cls = NULL;
+ 
+   element->identifier = GNUNET_strdup (identifier);
+ 
+   element->operation = GNUNET_IDENTITY_create (
 -      store->identity,
 -      identifier,
 -      NULL,
 -      GNUNET_PUBLIC_KEY_TYPE_ECDSA,
 -      callback_ego_create,
 -      element
 -  );
++    store->identity,
++    identifier,
++    NULL,
++    GNUNET_PUBLIC_KEY_TYPE_ECDSA,
++    callback_ego_create,
++    element
++    );
+ 
+   GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element);
+ }
+ 
++
+ void
+ bind_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
+                 const char *identifier,
+                 void *handle)
+ {
+   GNUNET_assert ((store) && (identifier) && (handle));
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store bind ego: %s\n", identifier);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store bind ego: %s\n", identifier);
+ 
+   struct GNUNET_HashCode hash;
+   GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
+ 
 -  if (GNUNET_YES == 
GNUNET_CONTAINER_multihashmap_contains_value(store->handles, &hash, handle))
++  if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value (
++        store->handles, &hash, handle))
+     return;
+ 
 -  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->handles, &hash, 
handle,
 -                                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Putting handle binding to ego store 
failed!\n");
++  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->handles, &hash,
++                                                      handle,
++                                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Putting handle binding to ego store failed!\n");
+ }
+ 
++
+ void
+ unbind_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
+                   const char *identifier,
+                   void *handle)
+ {
+   GNUNET_assert ((store) && (identifier) && (handle));
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store unbind ego: %s\n", identifier);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store unbind ego: %s\n", identifier);
+ 
+   struct GNUNET_HashCode hash;
+   GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
+ 
 -  if (GNUNET_YES != 
GNUNET_CONTAINER_multihashmap_contains_value(store->handles, &hash, handle))
++  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains_value (
++        store->handles, &hash, handle))
+     return;
+ 
 -  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove(store->handles, 
&hash, handle))
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Removing handle binding from ego 
store failed!\n");
++  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->handles, 
&hash,
++                                                          handle))
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Removing handle binding from ego store failed!\n");
+ }
+ 
++
+ static void
+ callback_ego_lookup (void *cls,
+                      struct GNUNET_IDENTITY_Ego *ego)
+ {
+   struct GNUNET_MESSENGER_EgoLookup *element = cls;
+   struct GNUNET_MESSENGER_EgoStore *store = element->store;
+ 
+   GNUNET_assert (element->identifier);
+ 
+   struct GNUNET_MESSENGER_Ego *msg_ego = NULL;
+ 
+   if (ego)
+   {
 -    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New ego looked up: '%s'\n", 
element->identifier);
++    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New ego looked up: '%s'\n",
++                element->identifier);
+     msg_ego = update_store_ego (
 -        store,
 -        element->identifier,
 -        GNUNET_IDENTITY_ego_get_private_key(ego)
 -    );
++      store,
++      element->identifier,
++      GNUNET_IDENTITY_ego_get_private_key (ego)
++      );
+   }
+   else
+   {
+     struct GNUNET_HashCode hash;
 -    GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), 
&hash);
++    GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier),
++                        &hash);
+ 
+     if (GNUNET_CONTAINER_multihashmap_get (store->egos, &hash))
+     {
 -      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looked up ego got deleted: 
'%s'\n", element->identifier);
 -      delete_store_ego(store, element->identifier);
++      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looked up ego got deleted: 
'%s'\n",
++                  element->identifier);
++      delete_store_ego (store, element->identifier);
+     }
+   }
+ 
+   if (element->cb)
 -    element->cb(element->cls, element->identifier, msg_ego);
++    element->cb (element->cls, element->identifier, msg_ego);
+ 
+   GNUNET_CONTAINER_DLL_remove (store->lu_start, store->lu_end, element);
+   GNUNET_free (element->identifier);
+   GNUNET_free (element);
+ }
+ 
++
+ void
 -lookup_store_ego(struct GNUNET_MESSENGER_EgoStore *store,
 -                 const char *identifier,
 -                 GNUNET_MESSENGER_EgoLookupCallback lookup,
 -                 void *cls)
++lookup_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
++                  const char *identifier,
++                  GNUNET_MESSENGER_EgoLookupCallback lookup,
++                  void *cls)
+ {
+   GNUNET_assert (store);
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store lookup ego: %s\n", identifier);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store lookup ego: %s\n", identifier);
+ 
 -  if (!identifier)
++  if (! identifier)
+   {
 -    lookup(cls, identifier, NULL);
++    lookup (cls, identifier, NULL);
+     return;
+   }
+ 
 -  struct GNUNET_MESSENGER_EgoLookup *element = GNUNET_new (struct 
GNUNET_MESSENGER_EgoLookup);
++  struct GNUNET_MESSENGER_EgoLookup *element = GNUNET_new (struct
++                                                           
GNUNET_MESSENGER_EgoLookup);
+ 
+   element->store = store;
+ 
+   element->cb = lookup;
+   element->cls = cls;
+ 
+   element->identifier = GNUNET_strdup (identifier);
+ 
 -  element->lookup = GNUNET_IDENTITY_ego_lookup(store->cfg, identifier, 
callback_ego_lookup, element);
++  element->lookup = GNUNET_IDENTITY_ego_lookup (store->cfg, identifier,
++                                                callback_ego_lookup, element);
+ 
+   GNUNET_CONTAINER_DLL_insert (store->lu_start, store->lu_end, element);
+ }
+ 
++
+ struct GNUNET_MESSENGER_Ego*
+ update_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
+                   const char *identifier,
+                   const struct GNUNET_CRYPTO_PrivateKey *key)
+ {
+   GNUNET_assert ((store) && (identifier) && (key));
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store update ego: %s\n", identifier);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store update ego: %s\n", identifier);
+ 
+   struct GNUNET_HashCode hash;
+   GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
+ 
 -  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get 
(store->egos, &hash);
++  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (
++    store->egos, &hash);
+ 
 -  if (!ego)
++  if (! ego)
+   {
 -    ego = GNUNET_new(struct GNUNET_MESSENGER_Ego);
 -    GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego, 
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
++    ego = GNUNET_new (struct GNUNET_MESSENGER_Ego);
++    GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego,
++                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+   }
+ 
 -  GNUNET_memcpy(&(ego->priv), key, sizeof(*key));
++  GNUNET_memcpy (&(ego->priv), key, sizeof(*key));
+ 
+   if (GNUNET_OK != GNUNET_CRYPTO_key_get_public (key, &(ego->pub)))
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating invalid ego key 
failed!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Updating invalid ego key failed!\n");
+ 
+   return ego;
+ }
+ 
++
+ void
+ delete_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
+                   const char *identifier)
+ {
+   GNUNET_assert ((store) && (identifier));
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store delete ego: %s\n", identifier);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store delete ego: %s\n", identifier);
+ 
+   struct GNUNET_HashCode hash;
+   GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
+ 
 -  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get 
(store->egos, &hash);
++  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (
++    store->egos, &hash);
+ 
+   if (ego)
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Ego is not stored!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Ego is not stored!\n");
+     return;
+   }
+ 
 -  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash, 
ego))
++  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash,
++                                                          ego))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Removing ego from store failed!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Removing ego from store failed!\n");
+     return;
+   }
+ 
 -  GNUNET_free(ego);
++  GNUNET_free (ego);
+ }
+ 
++
+ static void
+ callback_ego_rename (void *cls,
+                      enum GNUNET_ErrorCode ec)
+ {
+   struct GNUNET_MESSENGER_EgoOperation *element = cls;
+   struct GNUNET_MESSENGER_EgoStore *store = element->store;
+ 
+   GNUNET_assert (element->identifier);
+ 
+   /**
+    * FIXME: Dangerous, handle error
+    */
+   if (GNUNET_EC_NONE != ec)
+     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n",
+                 GNUNET_ErrorCode_get_hint (ec));
+ 
+   struct GNUNET_HashCode hash;
+   GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), 
&hash);
+ 
 -  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get 
(store->egos, &hash);
++  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (
++    store->egos, &hash);
+ 
 -  if (!ego)
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Ego is not stored!\n");
++  if (! ego)
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Ego is not stored!\n");
+ 
+   char *identifier = (char*) element->cls;
+ 
 -  if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash, 
ego))
++  if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash,
++                                                          ego))
+   {
+     GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
+ 
+     GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego,
+                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+   }
+   else
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Renaming ego failed!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Renaming ego failed!\n");
+ 
+   GNUNET_free (identifier);
+ 
+   GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element);
+   GNUNET_free (element->identifier);
+   GNUNET_free (element);
+ }
+ 
++
+ void
+ rename_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
+                   const char *old_identifier,
+                   const char *new_identifier)
+ {
+   GNUNET_assert ((store) && (old_identifier) && (new_identifier));
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store rename ego: %s -> %s\n", 
old_identifier, new_identifier);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store rename ego: %s -> %s\n",
++              old_identifier, new_identifier);
+ 
 -  struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct 
GNUNET_MESSENGER_EgoOperation);
++  struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct
++                                                              
GNUNET_MESSENGER_EgoOperation);
+ 
+   element->store = store;
+   element->cls = GNUNET_strdup (new_identifier);
+ 
+   element->identifier = GNUNET_strdup (old_identifier);
+ 
+   element->operation = GNUNET_IDENTITY_rename (
 -      store->identity,
 -      old_identifier,
 -      new_identifier,
 -      callback_ego_rename,
 -      element
 -  );
++    store->identity,
++    old_identifier,
++    new_identifier,
++    callback_ego_rename,
++    element
++    );
+ 
+   GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element);
+ }
+ 
++
+ static void
+ callback_ego_delete (void *cls,
+                      enum GNUNET_ErrorCode ec)
+ {
+   struct GNUNET_MESSENGER_EgoOperation *element = cls;
+   struct GNUNET_MESSENGER_EgoStore *store = element->store;
+ 
+   GNUNET_assert (element->identifier);
+ 
+   /**
+    * FIXME: Dangerous, handle error
+    */
+   if (GNUNET_EC_NONE != ec)
+     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n",
+                 GNUNET_ErrorCode_get_hint (ec));
+ 
+   create_store_ego (store, element->identifier);
+ 
+   GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element);
+   GNUNET_free (element->identifier);
+   GNUNET_free (element);
+ }
+ 
++
+ void
+ renew_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
+                  const char *identifier)
+ {
+   GNUNET_assert ((store) && (identifier));
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store renew ego: %s\n", identifier);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store renew ego: %s\n", identifier);
+ 
 -  struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct 
GNUNET_MESSENGER_EgoOperation);
++  struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct
++                                                              
GNUNET_MESSENGER_EgoOperation);
+ 
+   element->store = store;
+   element->cls = NULL;
+ 
+   element->identifier = GNUNET_strdup (identifier);
+ 
 -  element->operation = GNUNET_IDENTITY_delete(
 -      store->identity,
 -      identifier,
 -      callback_ego_delete,
 -      element
 -  );
++  element->operation = GNUNET_IDENTITY_delete (
++    store->identity,
++    identifier,
++    callback_ego_delete,
++    element
++    );
+ 
+   GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element);
+ }
diff --cc src/service/messenger/gnunet-service-messenger_handle.c
index 000000000,764331c4a..84b89f431
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_handle.c
+++ b/src/service/messenger/gnunet-service-messenger_handle.c
@@@ -1,0 -1,712 +1,571 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2022 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_handle.c
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "gnunet-service-messenger_handle.h"
+ 
+ #include "gnunet-service-messenger.h"
 -#include "gnunet-service-messenger_message_kind.h"
 -
++#include "messenger_api_message_kind.h"
+ #include "messenger_api_util.h"
+ 
++struct GNUNET_MESSENGER_NextMemberId
++{
++  struct GNUNET_ShortHashCode id;
++  enum GNUNET_GenericReturnValue reset;
++};
++
+ struct GNUNET_MESSENGER_SrvHandle*
+ create_srv_handle (struct GNUNET_MESSENGER_Service *service,
+                    struct GNUNET_MQ_Handle *mq)
+ {
 -  GNUNET_assert((service) && (mq));
++  GNUNET_assert ((service) && (mq));
+ 
 -  struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new(struct 
GNUNET_MESSENGER_SrvHandle);
++  struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new (struct
++                                                          
GNUNET_MESSENGER_SrvHandle);
+ 
+   handle->service = service;
+   handle->mq = mq;
+ 
 -  handle->name = NULL;
 -  handle->ego = NULL;
 -
+   handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
++  handle->next_ids = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
++
++  handle->notify = NULL;
+ 
+   return handle;
+ }
+ 
++
+ int
+ iterate_free_member_ids (void *cls,
+                          const struct GNUNET_HashCode *key,
+                          void *value)
+ {
 -  GNUNET_free(value);
++  GNUNET_free (value);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ void
+ destroy_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
+ {
 -  GNUNET_assert(handle);
++  GNUNET_assert (handle);
+ 
 -  if (handle->service->dir)
 -    save_srv_handle_configuration (handle);
++  if (handle->notify)
++    GNUNET_SCHEDULER_cancel (handle->notify);
+ 
 -  if (handle->name)
 -  {
 -    struct GNUNET_MESSENGER_EgoStore *store = 
get_service_ego_store(handle->service);
++  GNUNET_CONTAINER_multihashmap_iterate (handle->next_ids,
++                                         iterate_free_member_ids, NULL);
++  GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids,
++                                         iterate_free_member_ids, NULL);
++
++  GNUNET_CONTAINER_multihashmap_destroy (handle->next_ids);
++  GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids);
++
++  GNUNET_free (handle);
++}
+ 
 -    unbind_store_ego(store, handle->name, handle);
+ 
 -    GNUNET_free(handle->name);
++void
++set_srv_handle_key (struct GNUNET_MESSENGER_SrvHandle *handle,
++                    const struct GNUNET_CRYPTO_PublicKey *key)
++{
++  GNUNET_assert (handle);
++
++  if ((handle->key) && (! key))
++  {
++    GNUNET_free (handle->key);
++    handle->key = NULL;
+   }
++  else if (! handle->key)
++    handle->key = GNUNET_new (struct GNUNET_CRYPTO_PublicKey);
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, 
iterate_free_member_ids, NULL);
 -  GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids);
++  if (key)
++    memcpy (handle->key, key, sizeof(struct GNUNET_CRYPTO_PublicKey));
++}
+ 
 -  GNUNET_free(handle);
++
++const struct GNUNET_CRYPTO_PublicKey*
++get_srv_handle_key (const struct GNUNET_MESSENGER_SrvHandle *handle)
++{
++  GNUNET_assert (handle);
++
++  return handle->key;
+ }
+ 
++
+ void
+ get_srv_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle,
+                             const char *name,
+                             char **dir)
+ {
 -  GNUNET_assert((handle) && (dir));
++  GNUNET_assert ((handle) && (dir));
+ 
+   if (name)
+     GNUNET_asprintf (dir, "%s%s%c%s%c", handle->service->dir, "identities",
+                      DIR_SEPARATOR, name, DIR_SEPARATOR);
+   else
+     GNUNET_asprintf (dir, "%s%s%c", handle->service->dir, "anonymous",
+                      DIR_SEPARATOR);
+ }
+ 
++
+ static int
+ create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle,
+                          const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (key));
++  GNUNET_assert ((handle) && (key));
+ 
 -  struct GNUNET_ShortHashCode *random_id = GNUNET_new(struct 
GNUNET_ShortHashCode);
++  struct GNUNET_ShortHashCode *random_id = GNUNET_new (struct
++                                                       GNUNET_ShortHashCode);
+ 
 -  if (!random_id)
++  if (! random_id)
+     return GNUNET_NO;
+ 
+   generate_free_member_id (random_id, NULL);
+ 
 -  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, 
key, random_id,
++  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key,
++                                                      random_id,
+                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+   {
 -    GNUNET_free(random_id);
++    GNUNET_free (random_id);
+     return GNUNET_NO;
+   }
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Created a new member id (%s) for room: 
%s\n", GNUNET_sh2s (random_id),
 -             GNUNET_h2s (key));
++  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
++              "Created a new member id (%s) for room: %s\n", GNUNET_sh2s (
++                random_id),
++              GNUNET_h2s (key));
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ const struct GNUNET_ShortHashCode*
+ get_srv_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle,
+                           const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (key));
++  GNUNET_assert ((handle) && (key));
+ 
+   return GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key);
+ }
+ 
++
+ int
+ change_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle,
+                              const struct GNUNET_HashCode *key,
+                              const struct GNUNET_ShortHashCode *unique_id)
+ {
 -  GNUNET_assert((handle) && (key) && (unique_id));
++  GNUNET_assert ((handle) && (key) && (unique_id));
+ 
 -  struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get 
(handle->member_ids, key);
++  struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get (
++    handle->member_ids, key);
+ 
 -  if (!member_id)
++  if (! member_id)
+   {
 -    member_id = GNUNET_new(struct GNUNET_ShortHashCode);
 -    GNUNET_memcpy(member_id, unique_id, sizeof(*member_id));
++    member_id = GNUNET_new (struct GNUNET_ShortHashCode);
++    GNUNET_memcpy (member_id, unique_id, sizeof(*member_id));
+ 
 -    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, 
key, member_id,
++    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, 
key,
++                                                        member_id,
+                                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+     {
 -      GNUNET_free(member_id);
++      GNUNET_free (member_id);
+       return GNUNET_SYSERR;
+     }
+   }
+ 
 -  if (0 == GNUNET_memcmp(unique_id, member_id))
 -    goto send_message_to_client;
 -
 -  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Change a member id (%s) for room 
(%s).\n", GNUNET_sh2s (member_id),
 -             GNUNET_h2s (key));
 -
 -  GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id));
 -
 -  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Member id changed to (%s).\n", 
GNUNET_sh2s (unique_id));
 -
 -  struct GNUNET_MESSENGER_MemberMessage *msg;
 -  struct GNUNET_MQ_Envelope *env;
 -
 -send_message_to_client:
++  if (0 == GNUNET_memcmp (unique_id, member_id))
++    return GNUNET_OK;
+ 
 -  env = GNUNET_MQ_msg(msg, 
GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID);
++  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
++              "Change a member id (%s) for room (%s).\n", GNUNET_sh2s (
++                member_id),
++              GNUNET_h2s (key));
+ 
 -  GNUNET_memcpy(&(msg->key), key, sizeof(*key));
 -  GNUNET_memcpy(&(msg->id), member_id, sizeof(*member_id));
++  GNUNET_memcpy (member_id, unique_id, sizeof(*unique_id));
+ 
 -  GNUNET_MQ_send (handle->mq, env);
++  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Member id changed to (%s).\n",
++              GNUNET_sh2s (unique_id));
+   return GNUNET_OK;
+ }
+ 
 -static void
 -change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
 -                    const char *name)
 -{
 -  GNUNET_assert(handle);
 -
 -  if (handle->name)
 -    GNUNET_free(handle->name);
+ 
 -  handle->name = name ? GNUNET_strdup(name) : NULL;
 -
 -  const uint16_t name_len = handle->name ? strlen (handle->name) : 0;
 -
 -  struct GNUNET_MESSENGER_NameMessage *msg;
 -  struct GNUNET_MQ_Envelope *env;
 -
 -  env = GNUNET_MQ_msg_extra(msg, name_len + 1, 
GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME);
 -
 -  char *extra = ((char*) msg) + sizeof(*msg);
 -
 -  if (name_len)
 -    GNUNET_memcpy(extra, handle->name, name_len);
 -
 -  extra[name_len] = '\0';
 -
 -  GNUNET_MQ_send (handle->mq, env);
 -}
 -
 -static void
 -change_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle,
 -                   const struct GNUNET_MESSENGER_Ego *ego)
 -{
 -  GNUNET_assert(handle);
 -
 -  handle->ego = ego;
 -
 -  ego = get_srv_handle_ego (handle);
 -
 -  const uint16_t length = GNUNET_CRYPTO_public_key_get_length(&(ego->pub));
 -
 -  struct GNUNET_MESSENGER_KeyMessage *msg;
 -  struct GNUNET_MQ_Envelope *env;
 -
 -  env = GNUNET_MQ_msg_extra(msg, length, 
GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY);
 -
 -  char *extra = ((char*) msg) + sizeof(*msg);
 -
 -  if (GNUNET_CRYPTO_write_public_key_to_buffer(&(ego->pub), extra, length) < 
0)
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Could not write key to buffer.\n");
 -
 -  GNUNET_MQ_send (handle->mq, env);
 -}
 -
 -struct GNUNET_MESSENGER_MessageHandle
++struct RoomInitializationClosure
+ {
+   struct GNUNET_MESSENGER_SrvHandle *handle;
 -  struct GNUNET_MESSENGER_Message *message;
++  const struct GNUNET_HashCode *key;
++  const struct GNUNET_CRYPTO_PublicKey *pubkey;
+ };
+ 
+ static int
 -iterate_send_message (void *cls,
 -                      const struct GNUNET_HashCode *key,
 -                      void *value)
++find_member_session_in_room (void *cls,
++                             const struct GNUNET_CRYPTO_PublicKey *public_key,
++                             struct GNUNET_MESSENGER_MemberSession *session)
+ {
 -  struct GNUNET_MESSENGER_MessageHandle *msg_handle = cls;
++  struct RoomInitializationClosure *init = cls;
+ 
 -  send_srv_handle_message (msg_handle->handle, key, msg_handle->message);
++  if (! public_key)
++    return GNUNET_YES;
+ 
 -  return GNUNET_YES;
 -}
++  const struct GNUNET_CRYPTO_PublicKey *pubkey = get_srv_handle_key (
++    init->handle);
+ 
 -void
 -set_srv_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle,
 -                    const struct GNUNET_MESSENGER_Ego *ego)
 -{
 -  GNUNET_assert((handle) && (ego));
 -
 -  struct GNUNET_MESSENGER_MessageHandle msg_handle;
 -
 -  msg_handle.handle = handle;
 -  msg_handle.message = create_message_key (&(ego->priv));
++  if (0 != GNUNET_memcmp (pubkey, public_key))
++    return GNUNET_YES;
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, 
iterate_send_message, &msg_handle);
 -
 -  destroy_message (msg_handle.message);
 -
 -  change_handle_ego (handle, ego);
 -}
++  const struct GNUNET_ShortHashCode *id = get_member_session_id (session);
+ 
 -const struct GNUNET_MESSENGER_Ego*
 -get_srv_handle_ego (const struct GNUNET_MESSENGER_SrvHandle *handle)
 -{
 -  GNUNET_assert(handle);
 -
 -  static struct GNUNET_MESSENGER_Ego anonymous;
 -  static int read_keys = 0;
 -
 -  if (handle->ego)
 -    return handle->ego;
 -
 -  if (!read_keys)
++  if (! id)
+   {
 -    struct GNUNET_IDENTITY_Ego *ego = GNUNET_IDENTITY_ego_get_anonymous ();
 -    GNUNET_memcpy(&(anonymous.priv), GNUNET_IDENTITY_ego_get_private_key 
(ego), sizeof(anonymous.priv));
 -    GNUNET_IDENTITY_ego_get_public_key (ego, &(anonymous.pub));
 -    read_keys = 1;
++    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initialitation: Missing member 
id!");
++    return GNUNET_NO;
+   }
+ 
 -  return &anonymous;
 -}
++  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
++              "Initialitation: Matching member found (%s)!\n",
++              GNUNET_sh2s (id));
+ 
 -static void
 -callback_setup_handle_name (void *cls,
 -                            const char *name,
 -                            const struct GNUNET_MESSENGER_Ego *ego)
 -{
 -  struct GNUNET_MESSENGER_SrvHandle *handle = cls;
 -
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Setting up handle...\n");
 -
 -  change_handle_name (handle, name);
 -  change_handle_ego (handle, ego);
 -
 -  if (handle->service->dir)
 -    load_srv_handle_configuration (handle);
++  change_srv_handle_member_id (init->handle, init->key, id);
++  return GNUNET_NO;
+ }
+ 
 -void
 -setup_srv_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
 -                       const char *name)
 -{
 -  GNUNET_assert(handle);
 -
 -  struct GNUNET_MESSENGER_EgoStore *store = 
get_service_ego_store(handle->service);
 -
 -  lookup_store_ego (store, name, callback_setup_handle_name, handle);
 -}
+ 
+ static void
 -callback_update_handle (void *cls,
 -                        const char *name,
 -                        const struct GNUNET_MESSENGER_Ego *ego)
 -{
 -  struct GNUNET_MESSENGER_SrvHandle *handle = cls;
 -
 -  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating handle...\n");
 -
 -  struct GNUNET_MESSENGER_EgoStore *store = 
get_service_ego_store(handle->service);
 -
 -  bind_store_ego(store, handle->name, handle);
 -
 -  if (!ego)
 -    create_store_ego (store, handle->name);
 -  else
 -    renew_store_ego (store, handle->name);
 -}
 -
 -void
 -update_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
++initialize_srv_handle_via_matching_member (struct
++                                           GNUNET_MESSENGER_SrvHandle *handle,
++                                           const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert (handle);
 -
 -  if (!handle->name)
 -  {
 -    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Updating handle failed: Name is 
required!\n");
++  struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service,
++                                                            key);
++  if (! room)
+     return;
 -  }
+ 
 -  struct GNUNET_MESSENGER_EgoStore *store = 
get_service_ego_store(handle->service);
 -
 -  lookup_store_ego (store, handle->name, callback_update_handle, handle);
 -}
 -
 -static void
 -callback_set_handle_name (void *cls,
 -                          const char *name,
 -                          const struct GNUNET_MESSENGER_Ego *ego)
 -{
 -  struct GNUNET_MESSENGER_SrvHandle *handle = cls;
 -
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Renaming handle...\n");
 -
 -  if (ego)
 -  {
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is 
occupied! (%s)\n", name);
++  struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store 
(room);
++  if (! store)
+     return;
 -  }
 -
 -  struct GNUNET_MESSENGER_EgoStore *store = 
get_service_ego_store(handle->service);
 -
 -  char *old_dir;
 -  get_srv_handle_data_subdir (handle, handle->name, &old_dir);
 -
 -  char *new_dir;
 -  get_srv_handle_data_subdir (handle, name, &new_dir);
 -
 -  if ((GNUNET_YES == GNUNET_DISK_directory_test (new_dir, GNUNET_NO)) &&
 -      (GNUNET_OK != GNUNET_DISK_directory_remove(new_dir)))
 -    goto free_dirs;
+ 
 -  if (GNUNET_YES == GNUNET_DISK_directory_test (old_dir, GNUNET_YES))
 -  {
 -    GNUNET_DISK_directory_create_for_file (new_dir);
 -
 -    if (0 != rename (old_dir, new_dir))
 -      goto free_dirs;
 -  }
 -
 -  if (handle->ego)
 -    rename_store_ego(store, handle->name, name);
++  const struct GNUNET_CRYPTO_PublicKey *pubkey = get_srv_handle_key (handle);
++  if ((! pubkey) || (0 == GNUNET_memcmp (pubkey, get_anonymous_public_key 
())))
++    return;
+ 
 -  struct GNUNET_MESSENGER_MessageHandle msg_handle;
 -  msg_handle.handle = handle;
 -  msg_handle.message = create_message_name (name);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Initialize member id of handle via matching member in 
room!\n");
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, 
iterate_send_message, &msg_handle);
 -  destroy_message (msg_handle.message);
 -  change_handle_name (handle, name);
++  struct RoomInitializationClosure init;
++  init.handle = handle;
++  init.key = key;
++  init.pubkey = pubkey;
+ 
 -free_dirs:
 -  GNUNET_free(old_dir);
 -  GNUNET_free(new_dir);
++  iterate_store_members (store, find_member_session_in_room, &init);
+ }
+ 
 -void
 -set_srv_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
 -                     const char *name)
 -{
 -  GNUNET_assert(handle);
 -
 -  if (!name)
 -  {
 -    if (handle->ego)
 -      GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is 
required!\n");
 -    else
 -      change_handle_name (handle, name);
 -
 -    return;
 -  }
 -
 -  struct GNUNET_MESSENGER_EgoStore *store = 
get_service_ego_store(handle->service);
 -
 -  lookup_store_ego (store, name, callback_set_handle_name, handle);
 -}
+ 
+ int
+ open_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
+                       const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (key));
++  GNUNET_assert ((handle) && (key));
+ 
 -  if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != 
create_handle_member_id (handle, key)))
++  initialize_srv_handle_via_matching_member (handle, key);
++
++  if ((! get_srv_handle_member_id (handle, key)) && (GNUNET_YES !=
++                                                     create_handle_member_id (
++                                                       handle, key)))
+     return GNUNET_NO;
+ 
+   return open_service_room (handle->service, handle, key);
+ }
+ 
++
+ int
+ entry_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
+                        const struct GNUNET_PeerIdentity *door,
+                        const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (door) && (key));
++  GNUNET_assert ((handle) && (door) && (key));
+ 
 -  if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != 
create_handle_member_id (handle, key)))
++  initialize_srv_handle_via_matching_member (handle, key);
++
++  if ((! get_srv_handle_member_id (handle, key)) && (GNUNET_YES !=
++                                                     create_handle_member_id (
++                                                       handle, key)))
+     return GNUNET_NO;
+ 
+   return entry_service_room (handle->service, handle, door, key);
+ }
+ 
++
+ int
+ close_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
+                        const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (key));
++  GNUNET_assert ((handle) && (key));
++
++  GNUNET_CONTAINER_multihashmap_get_multiple (handle->next_ids, key,
++                                              iterate_free_member_ids, NULL);
++  GNUNET_CONTAINER_multihashmap_remove_all (handle->next_ids, key);
+ 
 -  if (!get_srv_handle_member_id (handle, key))
++  if ((handle->notify) && (0 == GNUNET_CONTAINER_multihashmap_size (
++                             handle->next_ids)))
++  {
++    GNUNET_SCHEDULER_cancel (handle->notify);
++    handle->notify = NULL;
++  }
++
++  if (! get_srv_handle_member_id (handle, key))
+     return GNUNET_NO;
+ 
+   return close_service_room (handle->service, handle, key);
+ }
+ 
++
+ int
+ send_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
+                          const struct GNUNET_HashCode *key,
+                          const struct GNUNET_MESSENGER_Message *message)
+ {
 -  GNUNET_assert((handle) && (key) && (message));
++  GNUNET_assert ((handle) && (key) && (message));
+ 
 -  const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id (handle, 
key);
++  const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id (handle,
++                                                                    key);
+ 
 -  if (!id)
++  if (! id)
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "It is required to be a member of a 
room to send messages!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "It is required to be a member of a room to send 
messages!\n");
+     return GNUNET_NO;
+   }
+ 
 -  struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, 
key);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message with member id: %s\n",
++              GNUNET_sh2s (id));
+ 
 -  if (!room)
++  if (0 != GNUNET_memcmp (id, &(message->header.sender_id)))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "The room (%s) is unknown!\n", 
GNUNET_h2s (key));
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Member id does not match with handle!\n");
+     return GNUNET_NO;
+   }
+ 
 -  struct GNUNET_MESSENGER_Message *msg = copy_message(message);
++  struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service,
++                                                            key);
+ 
 -  GNUNET_memcpy(&(msg->header.sender_id), id, sizeof(*id));
++  if (! room)
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "The room (%s) is unknown!\n",
++                GNUNET_h2s (key));
++    return GNUNET_NO;
++  }
+ 
++  struct GNUNET_MESSENGER_Message *msg = copy_message (message);
+   return send_srv_room_message (room, handle, msg);
+ }
+ 
++
+ static const struct GNUNET_HashCode*
 -get_next_member_session_contect(const struct GNUNET_MESSENGER_MemberSession 
*session)
++get_next_member_session_context (const struct
++                                 GNUNET_MESSENGER_MemberSession *session)
+ {
+   if (session->next)
 -    return get_next_member_session_contect (session->next);
++    return get_next_member_session_context (session->next);
+   else
 -    return get_member_session_context(session);
++    return get_member_session_context (session);
+ }
+ 
++
+ static const struct GNUNET_MESSENGER_MemberSession*
+ get_handle_member_session (struct GNUNET_MESSENGER_SrvHandle *handle,
+                            struct GNUNET_MESSENGER_SrvRoom *room,
+                            const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (room) && (key) && (handle->service));
++  GNUNET_assert ((handle) && (room) && (key) && (handle->service));
+ 
 -  const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id(handle, 
key);
++  const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id (handle,
++                                                                    key);
+ 
 -  if (!id)
++  if (! id)
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Handle is missing a member id for its member session! 
(%s)\n",
++                GNUNET_h2s (key));
+     return NULL;
++  }
+ 
 -  struct GNUNET_MESSENGER_MemberStore *store = 
get_srv_room_member_store(room);
 -  struct GNUNET_MESSENGER_Member *member = get_store_member(store, id);
++  struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store 
(room);
++  struct GNUNET_MESSENGER_Member *member = get_store_member (store, id);
+ 
 -  const struct GNUNET_MESSENGER_Ego *ego = get_srv_handle_ego(handle);
++  const struct GNUNET_CRYPTO_PublicKey *pubkey = get_srv_handle_key (handle);
+ 
 -  if (!ego)
++  if (! pubkey)
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Handle is missing a public key for its member session! 
(%s)\n",
++                GNUNET_h2s (key));
+     return NULL;
++  }
+ 
 -  return get_member_session(member, &(ego->pub));
++  return get_member_session (member, pubkey);
+ }
+ 
++
+ void
+ notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
+                            struct GNUNET_MESSENGER_SrvRoom *room,
 -                           const struct GNUNET_MESSENGER_MemberSession 
*session,
++                           const struct GNUNET_MESSENGER_SenderSession 
*session,
+                            const struct GNUNET_MESSENGER_Message *message,
+                            const struct GNUNET_HashCode *hash)
+ {
 -  GNUNET_assert((handle) && (room) && (session) && (message) && (hash));
++  GNUNET_assert ((handle) && (room) && (session) && (message) && (hash));
+ 
 -  const struct GNUNET_HashCode *key = get_srv_room_key(room);
++  const struct GNUNET_HashCode *key = get_srv_room_key (room);
+ 
 -  if ((!handle->mq) || (!get_srv_handle_member_id (handle, key)))
++  if ((! handle->mq) || (! get_srv_handle_member_id (handle, key)))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notifying client about message 
requires membership!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Notifying client about message requires membership!\n");
+     return;
+   }
+ 
 -  const struct GNUNET_CRYPTO_PublicKey *pubkey = 
get_contact_key(session->contact);
 -
+   struct GNUNET_HashCode sender;
 -  GNUNET_CRYPTO_hash(pubkey, sizeof(*pubkey), &sender);
 -
 -  const struct GNUNET_HashCode *context = get_next_member_session_contect 
(session);
++  const struct GNUNET_HashCode *context = NULL;
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying client about message: %s\n", 
GNUNET_h2s (hash));
 -
 -  struct GNUNET_MESSENGER_Message *private_message = NULL;
++  if (GNUNET_YES == is_peer_message (message))
++  {
++    const struct GNUNET_PeerIdentity *identity = session->peer;
++    GNUNET_CRYPTO_hash (identity, sizeof(*identity), &sender);
+ 
 -  if (GNUNET_MESSENGER_KIND_PRIVATE == message->header.kind)
++    context = &sender;
++  }
++  else
+   {
 -    private_message = copy_message(message);
++    const struct GNUNET_CRYPTO_PublicKey *pubkey = get_contact_key (
++      session->member->contact);
++    GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &sender);
+ 
 -    if (GNUNET_YES != decrypt_message(private_message, 
&(get_srv_handle_ego(handle)->priv)))
 -    {
 -      destroy_message(private_message);
 -      private_message = NULL;
 -    }
 -    else
 -      message = private_message;
++    context = get_next_member_session_context (session->member);
+   }
+ 
++  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Notifying client about message: %s\n",
++              GNUNET_h2s (hash));
++
+   struct GNUNET_MESSENGER_RecvMessage *msg;
+   struct GNUNET_MQ_Envelope *env;
+ 
+   uint16_t length = get_message_size (message, GNUNET_YES);
+ 
 -  env = GNUNET_MQ_msg_extra(msg, length, 
GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE);
++  env = GNUNET_MQ_msg_extra (msg, length,
++                             GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE);
+ 
 -  GNUNET_memcpy(&(msg->key), key, sizeof(msg->key));
 -  GNUNET_memcpy(&(msg->sender), &sender, sizeof(msg->sender));
 -  GNUNET_memcpy(&(msg->context), context, sizeof(msg->context));
 -  GNUNET_memcpy(&(msg->hash), hash, sizeof(msg->hash));
++  GNUNET_memcpy (&(msg->key), key, sizeof(msg->key));
++  GNUNET_memcpy (&(msg->sender), &sender, sizeof(msg->sender));
++  GNUNET_memcpy (&(msg->context), context, sizeof(msg->context));
++  GNUNET_memcpy (&(msg->hash), hash, sizeof(msg->hash));
+ 
+   msg->flags = (uint32_t) GNUNET_MESSENGER_FLAG_NONE;
+ 
 -  if (get_handle_member_session(handle, room, key) == session)
++  if (GNUNET_YES == is_peer_message (message))
++    msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_PEER;
++  else if (get_handle_member_session (handle, room, key) == session->member)
+     msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_SENT;
+ 
 -  if (private_message)
 -    msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_PRIVATE;
 -
+   char *buffer = ((char*) msg) + sizeof(*msg);
+   encode_message (message, length, buffer, GNUNET_YES);
+ 
 -  if (private_message)
 -    destroy_message(private_message);
 -
+   GNUNET_MQ_send (handle->mq, env);
+ }
+ 
++
+ static int
 -callback_scan_for_rooms (void *cls,
 -                         const char *filename)
++iterate_next_member_ids (void *cls,
++                         const struct GNUNET_HashCode *key,
++                         void *value)
+ {
+   struct GNUNET_MESSENGER_SrvHandle *handle = cls;
++  struct GNUNET_MESSENGER_NextMemberId *next = value;
+ 
 -  if ((strlen(filename) <= 4) || (0 != strcmp(filename + strlen(filename) - 
4, ".cfg")))
 -    return GNUNET_OK;
 -
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load room configuration of handle: 
%s\n", filename);
++  struct GNUNET_MESSENGER_MemberMessage *msg;
++  struct GNUNET_MQ_Envelope *env;
+ 
 -  struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
++  env = GNUNET_MQ_msg (msg, 
GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID);
+ 
 -  if ((GNUNET_YES == GNUNET_DISK_file_test (filename)) && (GNUNET_OK == 
GNUNET_CONFIGURATION_parse (cfg, filename)))
 -  {
 -    struct GNUNET_HashCode key;
 -    struct GNUNET_ShortHashCode member_id;
++  GNUNET_memcpy (&(msg->key), key, sizeof(*key));
++  GNUNET_memcpy (&(msg->id), &(next->id), sizeof(next->id));
++  msg->reset = (uint32_t) next->reset;
+ 
 -    if ((GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "key", 
&key, sizeof(key))) &&
 -        (GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", 
"member_id", &member_id, sizeof(member_id))))
 -      change_srv_handle_member_id (handle, &key, &member_id);
 -  }
++  GNUNET_MQ_send (handle->mq, env);
+ 
 -  GNUNET_CONFIGURATION_destroy (cfg);
 -  return GNUNET_OK;
++  GNUNET_free (next);
++  return GNUNET_YES;
+ }
+ 
 -void
 -load_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle)
 -{
 -  GNUNET_assert(handle);
 -
 -  char *id_dir;
 -  get_srv_handle_data_subdir (handle, handle->name, &id_dir);
+ 
 -  if (GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_YES))
 -  {
 -    char *scan_dir;
 -    GNUNET_asprintf (&scan_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR);
 -
 -    if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES))
 -      GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_rooms, handle);
 -
 -    GNUNET_free(scan_dir);
 -  }
 -
 -  GNUNET_free(id_dir);
 -}
 -
 -static int
 -iterate_save_rooms (void *cls,
 -                    const struct GNUNET_HashCode *key,
 -                    void *value)
++static void
++task_notify_srv_handle_member_id (void *cls)
+ {
+   struct GNUNET_MESSENGER_SrvHandle *handle = cls;
 -  struct GNUNET_ShortHashCode *member_id = value;
 -
 -  char *id_dir;
 -  get_srv_handle_data_subdir (handle, handle->name, &id_dir);
 -
 -  char *filename;
 -  GNUNET_asprintf (&filename, "%s%s%c%s.cfg", id_dir, "rooms", DIR_SEPARATOR, 
GNUNET_h2s (key));
 -  GNUNET_free(id_dir);
 -
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save room configuration of handle: 
%s\n", filename);
 -
 -  struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
++  handle->notify = NULL;
+ 
 -  char *key_data = GNUNET_STRINGS_data_to_string_alloc (key, sizeof(*key));
 -
 -  if (key_data)
 -  {
 -    GNUNET_CONFIGURATION_set_value_string (cfg, "room", "key", key_data);
++  GNUNET_CONTAINER_multihashmap_iterate (handle->next_ids,
++                                         iterate_next_member_ids, handle);
++  GNUNET_CONTAINER_multihashmap_clear (handle->next_ids);
++}
+ 
 -    GNUNET_free(key_data);
 -  }
+ 
 -  char *member_id_data = GNUNET_STRINGS_data_to_string_alloc (member_id, 
sizeof(*member_id));
++void
++notify_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle,
++                             struct GNUNET_MESSENGER_SrvRoom *room,
++                             const struct GNUNET_ShortHashCode *member_id,
++                             enum GNUNET_GenericReturnValue reset)
++{
++  GNUNET_assert ((handle) && (room) && (member_id));
+ 
 -  if (member_id_data)
++  struct GNUNET_MESSENGER_NextMemberId *next = GNUNET_new (struct
++                                                           
GNUNET_MESSENGER_NextMemberId);
++  if (! next)
+   {
 -    GNUNET_CONFIGURATION_set_value_string (cfg, "room", "member_id", 
member_id_data);
 -
 -    GNUNET_free(member_id_data);
++    return;
+   }
+ 
 -  GNUNET_CONFIGURATION_write (cfg, filename);
 -  GNUNET_CONFIGURATION_destroy (cfg);
++  GNUNET_memcpy (&(next->id), member_id, sizeof(next->id));
++  next->reset = reset;
+ 
 -  GNUNET_free(filename);
++  const struct GNUNET_HashCode *key = get_srv_room_key (room);
+ 
 -  return GNUNET_YES;
 -}
 -
 -void
 -save_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle)
 -{
 -  GNUNET_assert(handle);
 -
 -  char *id_dir;
 -  get_srv_handle_data_subdir (handle, handle->name, &id_dir);
 -
 -  if ((GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_NO)) || 
(GNUNET_OK
 -      == GNUNET_DISK_directory_create (id_dir)))
++  struct GNUNET_MESSENGER_NextMemberId *prev =
++    GNUNET_CONTAINER_multihashmap_get (handle->next_ids, key);
++  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_put (handle->next_ids, key,
++                                                       next,
++                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE))
+   {
 -    char *save_dir;
 -    GNUNET_asprintf (&save_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR);
 -
 -    if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
 -        (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
 -      GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, 
iterate_save_rooms, handle);
 -
 -    GNUNET_free(save_dir);
++    return;
+   }
+ 
 -  GNUNET_free(id_dir);
++  if (prev)
++    GNUNET_free (prev);
++
++  if (! handle->notify)
++    handle->notify = GNUNET_SCHEDULER_add_now 
(task_notify_srv_handle_member_id,
++                                               handle);
+ }
diff --cc src/service/messenger/gnunet-service-messenger_handle.h
index 000000000,edcd2ccd0..4963d9247
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_handle.h
+++ b/src/service/messenger/gnunet-service-messenger_handle.h
@@@ -1,0 -1,249 +1,213 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2022 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_handle.h
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_SERVICE_MESSENGER_HANDLE_H
+ #define GNUNET_SERVICE_MESSENGER_HANDLE_H
+ 
+ #include "platform.h"
+ #include "gnunet_cadet_service.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ 
+ #include "gnunet-service-messenger_service.h"
 -#include "gnunet-service-messenger_member_session.h"
++#include "gnunet-service-messenger_sender_session.h"
+ 
 -#include "messenger_api_ego.h"
+ #include "messenger_api_message.h"
+ 
+ struct GNUNET_MESSENGER_SrvHandle
+ {
+   struct GNUNET_MESSENGER_Service *service;
+   struct GNUNET_MQ_Handle *mq;
+ 
 -  char *name;
 -
 -  const struct GNUNET_MESSENGER_Ego *ego;
++  struct GNUNET_CRYPTO_PublicKey *key;
+ 
+   struct GNUNET_CONTAINER_MultiHashMap *member_ids;
++  struct GNUNET_CONTAINER_MultiHashMap *next_ids;
++
++  struct GNUNET_SCHEDULER_Task *notify;
+ };
+ 
+ /**
+  * Creates and allocates a new handle related to a <i>service</i> and using a 
given <i>mq</i> (message queue).
+  *
+  * @param[in,out] service MESSENGER Service
+  * @param[in,out] mq Message queue
+  * @return New handle
+  */
+ struct GNUNET_MESSENGER_SrvHandle*
+ create_srv_handle (struct GNUNET_MESSENGER_Service *service,
+                    struct GNUNET_MQ_Handle *mq);
+ 
+ /**
+  * Destroys a handle and frees its memory fully.
+  *
+  * @param[in,out] handle Handle
+  */
+ void
+ destroy_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle);
+ 
++/**
++ * Sets the public key from the EGO of a given <i>handle</i>.
++ *
++ * @param[out] handle Handle
++ * @param[in] key Public key of EGO
++ */
++void
++set_srv_handle_key (struct GNUNET_MESSENGER_SrvHandle *handle,
++                    const struct GNUNET_CRYPTO_PublicKey *key);
++
++/**
++ * Returns the public key from the EGO of a given <i>handle</i>.
++ *
++ * @param[in] handle Handle
++ * @return Public key of handles EGO
++ */
++const struct GNUNET_CRYPTO_PublicKey*
++get_srv_handle_key (const struct GNUNET_MESSENGER_SrvHandle *handle);
++
+ /**
+  * Writes the path of the directory for a given <i>handle</i> using a 
specific <i>name</i> to the parameter
+  * <i>dir</i>. This directory will be used to store data regarding the handle 
and its messages.
+  *
+  * @param[in] handle Handle
+  * @param[in] name Potential name of the handle
+  * @param[out] dir Path to store data
+  */
+ void
+ get_srv_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle,
 -                        const char *name,
 -                        char **dir);
++                            const char *name,
++                            char **dir);
+ 
+ /**
+  * Returns the member id of a given <i>handle</i> in a specific <i>room</i>.
+  *
+  * If the handle is not a member of the specific <i>room</i>, NULL gets 
returned.
+  *
+  * @param[in] handle Handle
+  * @param[in] key Key of a room
+  * @return Member id or NULL
+  */
+ const struct GNUNET_ShortHashCode*
+ get_srv_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle,
+                           const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Changes the member id of a given <i>handle</i> in a specific <i>room</i> 
to match a <i>unique_id</i>
+  * and returns GNUNET_OK on success.
+  *
+  * The client connected to the <i>handle</i> will be informed afterwards 
automatically.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] key Key of a room
+  * @param[in] unique_id Unique member id
+  * @return GNUNET_OK on success, otherwise GNUNET_SYSERR
+  */
+ int
+ change_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle,
+                              const struct GNUNET_HashCode *key,
+                              const struct GNUNET_ShortHashCode *unique_id);
+ 
 -/**
 - * Sets the EGO used by a given <i>handle</i>.
 - *
 - * @param[in,out] handle Handle
 - * @param[in] ego EGO key pair
 - */
 -void
 -set_srv_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle,
 -                    const struct GNUNET_MESSENGER_Ego *ego);
 -
 -/**
 - * Returns the EGO used by a given <i>handle</i>.
 - *
 - * @param[in] handle Handle
 - * @return EGO key pair
 - */
 -const struct GNUNET_MESSENGER_Ego*
 -get_srv_handle_ego (const struct GNUNET_MESSENGER_SrvHandle *handle);
 -
 -/**
 - * Tries to set the name and EGO key of a <i>handle</i> initially by looking 
up a specific <i>name</i>.
 - *
 - * @param[in,out] handle Handle
 - * @param[in] name Name (optionally: valid EGO name)
 - */
 -void
 -setup_srv_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
 -                       const char *name);
 -
 -/**
 - * Tries to change the key pair of an EGO of a <i>handle</i> under the same 
name and informs all rooms
 - * about the change automatically.
 - *
 - * @param[in,out] handle Handle
 - */
 -void
 -update_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle);
 -
 -/**
 - * Tries to rename the handle which implies renaming the EGO its using and 
moving all related data into
 - * the directory fitting to the changed <i>name</i>.
 - *
 - * The client connected to the <i>handle</i> will be informed afterwards 
automatically.
 - *
 - * @param[in,out] handle Handle
 - * @param[in] name New name
 - */
 -void
 -set_srv_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
 -                     const char *name);
 -
+ /**
+  * Makes a given <i>handle</i> a member of the room using a specific 
<i>key</i> and opens the
+  * room from the handles service.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] key Key of a room
+  * @return #GNUNET_YES on success, otherwise #GNUNET_NO
+  */
+ int
+ open_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
+                       const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Makes a given <i>handle</i> a member of the room using a specific 
<i>key</i> and enters the room
+  * through a tunnel to a peer identified by a given <i>door</i> (peer 
identity).
+  *
+  * @param[in,out] handle Handle
+  * @param[in] door Peer identity
+  * @param[in] key Key of a room
+  * @return #GNUNET_YES on success, otherwise #GNUNET_NO
+  */
+ int
+ entry_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
+                        const struct GNUNET_PeerIdentity *door,
+                        const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Removes the membership of the room using a specific <i>key</i> and closes 
it if no other handle
+  * from this service is still a member of it.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] key Key of a room
+  * @return #GNUNET_YES on success, otherwise #GNUNET_NO
+  */
+ int
+ close_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
+                        const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Sends a <i>message</i> from a given <i>handle</i> to the room using a 
specific <i>key</i>.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] key Key of a room
+  * @param[in] message Message
+  * @return #GNUNET_YES on success, #GNUNET_NO or #GNUNET_SYSERR otherwise.
+  */
+ int
+ send_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
+                          const struct GNUNET_HashCode *key,
+                          const struct GNUNET_MESSENGER_Message *message);
+ 
+ /**
+  * Notifies the handle that a new message was received or sent.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] room Room of the message
 - * @param[in] session Member session
++ * @param[in] session Sender session
+  * @param[in] message Message
+  * @param[in] hash Hash of message
+  */
+ void
+ notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
+                            struct GNUNET_MESSENGER_SrvRoom *room,
 -                           const struct GNUNET_MESSENGER_MemberSession 
*session,
++                           const struct GNUNET_MESSENGER_SenderSession 
*session,
+                            const struct GNUNET_MESSENGER_Message *message,
+                            const struct GNUNET_HashCode *hash);
+ 
+ /**
 - * Loads member ids and other potential configuration from a given 
<i>handle</i> which
 - * depends on the given name the <i>handle</i> uses.
++ * Notifies the handle that a new member id needs to be used.
+  *
 - * @param[out] handle Handle
 - */
 -void
 -load_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle);
 -
 -/**
 - * Saves member ids and other potential configuration from a given 
<i>handle</i> which
 - * depends on the given name the <i>handle</i> uses.
 - *
 - * @param[in] handle Handle
++ * @param[in,out] handle Handle
++ * @param[in] room Room of the member
++ * @param[in] member_id Member id
++ * @param[in] reset Reset member session with join message
+  */
+ void
 -save_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle);
++notify_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle,
++                             struct GNUNET_MESSENGER_SrvRoom *room,
++                             const struct GNUNET_ShortHashCode *member_id,
++                             enum GNUNET_GenericReturnValue reset);
+ 
+ #endif //GNUNET_SERVICE_MESSENGER_HANDLE_H
diff --cc src/service/messenger/gnunet-service-messenger_member.c
index 000000000,96b26cfb9..c57daa062
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_member.c
+++ b/src/service/messenger/gnunet-service-messenger_member.c
@@@ -1,0 -1,416 +1,460 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_member.c
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "gnunet-service-messenger_member.h"
+ 
+ #include "gnunet-service-messenger_member_session.h"
+ 
+ struct GNUNET_MESSENGER_Member*
+ create_member (struct GNUNET_MESSENGER_MemberStore *store,
+                const struct GNUNET_ShortHashCode *id)
+ {
+   GNUNET_assert (store);
+ 
 -  struct GNUNET_MESSENGER_Member *member = GNUNET_new(struct 
GNUNET_MESSENGER_Member);
++  struct GNUNET_MESSENGER_Member *member = GNUNET_new (struct
++                                                       
GNUNET_MESSENGER_Member);
+ 
+   member->store = store;
+ 
+   if (id)
 -    GNUNET_memcpy(&(member->id), id, sizeof(member->id));
 -  else if (GNUNET_YES != generate_free_member_id(&(member->id), 
store->members))
++    GNUNET_memcpy (&(member->id), id, sizeof(member->id));
++  else if (GNUNET_YES != generate_free_member_id (&(member->id),
++                                                  store->members))
+   {
+     GNUNET_free (member);
+     return NULL;
+   }
+ 
 -  member->sessions = GNUNET_CONTAINER_multihashmap_create(2, GNUNET_NO);
++  member->sessions = GNUNET_CONTAINER_multihashmap_create (2, GNUNET_NO);
+ 
+   return member;
+ }
+ 
++
+ static int
+ iterate_destroy_session (void *cls,
+                          const struct GNUNET_HashCode *key,
+                          void *value)
+ {
+   struct GNUNET_MESSENGER_MemberSession *session = value;
 -  destroy_member_session(session);
++  destroy_member_session (session);
+   return GNUNET_YES;
+ }
+ 
++
+ void
+ destroy_member (struct GNUNET_MESSENGER_Member *member)
+ {
 -  GNUNET_assert((member) && (member->sessions));
++  GNUNET_assert ((member) && (member->sessions));
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (member->sessions, 
iterate_destroy_session, NULL);
++  GNUNET_CONTAINER_multihashmap_iterate (member->sessions,
++                                         iterate_destroy_session, NULL);
+   GNUNET_CONTAINER_multihashmap_destroy (member->sessions);
+ 
+   GNUNET_free (member);
+ }
+ 
++
+ const struct GNUNET_ShortHashCode*
+ get_member_id (const struct GNUNET_MESSENGER_Member *member)
+ {
+   GNUNET_assert (member);
+ 
+   return &(member->id);
+ }
+ 
++
+ static int
+ callback_scan_for_sessions (void *cls,
+                             const char *filename)
+ {
+   struct GNUNET_MESSENGER_Member *member = cls;
+ 
+   if (GNUNET_YES == GNUNET_DISK_directory_test (filename, GNUNET_YES))
+   {
+     char *directory;
+ 
+     GNUNET_asprintf (&directory, "%s%c", filename, DIR_SEPARATOR);
+ 
 -    load_member_session(member, directory);
++    load_member_session (member, directory);
+     GNUNET_free (directory);
+   }
+ 
+   return GNUNET_OK;
+ }
+ 
++
+ void
+ load_member (struct GNUNET_MESSENGER_MemberStore *store,
+              const char *directory)
+ {
+   GNUNET_assert ((store) && (directory));
+ 
+   char *config_file;
+   GNUNET_asprintf (&config_file, "%s%s", directory, "member.cfg");
+ 
+   struct GNUNET_MESSENGER_Member *member = NULL;
+ 
+   if (GNUNET_YES != GNUNET_DISK_file_test (config_file))
+     goto free_config;
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load member configuration: %s\n", 
config_file);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Load member configuration: %s\n",
++              config_file);
+ 
+   struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
+ 
+   if (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, config_file))
+   {
+     struct GNUNET_ShortHashCode id;
+ 
 -    if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "member", "id", &id, 
sizeof(id)))
++    if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "member", "id", &id,
++                                                    sizeof(id)))
+       goto destroy_config;
+ 
 -    member = add_store_member(store, &id);
++    member = add_store_member (store, &id);
+   }
+ 
+ destroy_config:
+ 
+   GNUNET_CONFIGURATION_destroy (cfg);
+ 
+ free_config:
 -  GNUNET_free(config_file);
++  GNUNET_free (config_file);
+ 
 -  if (!member)
++  if (! member)
+     return;
+ 
+   char *scan_dir;
+   GNUNET_asprintf (&scan_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
+ 
+   if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES))
+     GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_sessions, member);
+ 
 -  GNUNET_free(scan_dir);
++  GNUNET_free (scan_dir);
+ }
+ 
++
+ static int
+ iterate_load_next_session (void *cls,
+                            const struct GNUNET_HashCode *key,
+                            void *value)
+ {
 -  const char* sessions_directory = cls;
++  const char *sessions_directory = cls;
+ 
 -  char* load_dir;
 -  GNUNET_asprintf (&load_dir, "%s%s%c", sessions_directory, GNUNET_h2s(key), 
DIR_SEPARATOR);
++  char *load_dir;
++  GNUNET_asprintf (&load_dir, "%s%s%c", sessions_directory, GNUNET_h2s (key),
++                   DIR_SEPARATOR);
+ 
+   struct GNUNET_MESSENGER_MemberSession *session = value;
+ 
+   if (GNUNET_YES == GNUNET_DISK_directory_test (load_dir, GNUNET_YES))
+     load_member_session_next (session, load_dir);
+ 
+   GNUNET_free (load_dir);
+   return GNUNET_YES;
+ }
+ 
++
+ void
+ load_member_next_sessions (const struct GNUNET_MESSENGER_Member *member,
+                            const char *directory)
+ {
+   GNUNET_assert ((member) && (directory));
+ 
 -  char* load_dir;
++  char *load_dir;
+   GNUNET_asprintf (&load_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (member->sessions, 
iterate_load_next_session, load_dir);
++  GNUNET_CONTAINER_multihashmap_iterate (member->sessions,
++                                         iterate_load_next_session, load_dir);
+ 
 -  GNUNET_free(load_dir);
++  GNUNET_free (load_dir);
+ }
+ 
++
+ static int
+ iterate_save_session (void *cls,
+                       const struct GNUNET_HashCode *key,
+                       void *value)
+ {
 -  const char* sessions_directory = cls;
++  const char *sessions_directory = cls;
+ 
 -  char* save_dir;
 -  GNUNET_asprintf (&save_dir, "%s%s%c", sessions_directory, GNUNET_h2s(key), 
DIR_SEPARATOR);
++  char *save_dir;
++  GNUNET_asprintf (&save_dir, "%s%s%c", sessions_directory, GNUNET_h2s (key),
++                   DIR_SEPARATOR);
+ 
+   struct GNUNET_MESSENGER_MemberSession *session = value;
+ 
+   if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
+       (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
+     save_member_session (session, save_dir);
+ 
+   GNUNET_free (save_dir);
+   return GNUNET_YES;
+ }
+ 
++
+ void
+ save_member (struct GNUNET_MESSENGER_Member *member,
+              const char *directory)
+ {
+   GNUNET_assert ((member) && (directory));
+ 
+   char *config_file;
+   GNUNET_asprintf (&config_file, "%s%s", directory, "member.cfg");
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save member configuration: %s\n", 
config_file);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Save member configuration: %s\n",
++              config_file);
+ 
+   struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
+ 
 -  char *id_data = GNUNET_STRINGS_data_to_string_alloc (&(member->id), 
sizeof(member->id));
++  char *id_data = GNUNET_STRINGS_data_to_string_alloc (&(member->id),
++                                                       sizeof(member->id));
+ 
+   if (id_data)
+   {
+     GNUNET_CONFIGURATION_set_value_string (cfg, "member", "id", id_data);
+ 
 -    GNUNET_free(id_data);
++    GNUNET_free (id_data);
+   }
+ 
+   GNUNET_CONFIGURATION_write (cfg, config_file);
+   GNUNET_CONFIGURATION_destroy (cfg);
+ 
 -  GNUNET_free(config_file);
++  GNUNET_free (config_file);
+ 
 -  char* save_dir;
++  char *save_dir;
+   GNUNET_asprintf (&save_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
+ 
+   if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
+       (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
 -    GNUNET_CONTAINER_multihashmap_iterate (member->sessions, 
iterate_save_session, save_dir);
++    GNUNET_CONTAINER_multihashmap_iterate (member->sessions,
++                                           iterate_save_session, save_dir);
+ 
 -  GNUNET_free(save_dir);
++  GNUNET_free (save_dir);
+ }
+ 
++
+ static void
+ sync_session_contact_from_next (struct GNUNET_MESSENGER_MemberSession 
*session,
+                                 struct GNUNET_MESSENGER_MemberSession *next)
+ {
 -  GNUNET_assert((session) && (next));
++  GNUNET_assert ((session) && (next));
+ 
+   if (session == next)
+     return;
+ 
+   if (next->next)
+     sync_session_contact_from_next (session, next->next);
+   else
+     session->contact = next->contact;
+ }
+ 
++
+ static int
+ iterate_sync_session_contact (void *cls,
+                               const struct GNUNET_HashCode *key,
+                               void *value)
+ {
+   struct GNUNET_MESSENGER_MemberSession *session = value;
+ 
+   if (session->next)
+     sync_session_contact_from_next (session, session->next);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ void
+ sync_member_contacts (struct GNUNET_MESSENGER_Member *member)
+ {
+   GNUNET_assert ((member) && (member->sessions));
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (member->sessions, 
iterate_sync_session_contact, NULL);
++  GNUNET_CONTAINER_multihashmap_iterate (member->sessions,
++                                         iterate_sync_session_contact, NULL);
+ }
+ 
++
+ struct GNUNET_MESSENGER_MemberSession*
+ get_member_session (const struct GNUNET_MESSENGER_Member *member,
+                     const struct GNUNET_CRYPTO_PublicKey *public_key)
+ {
+   GNUNET_assert ((member) && (public_key));
+ 
+   struct GNUNET_HashCode hash;
 -  GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash);
++  GNUNET_CRYPTO_hash (public_key, sizeof(*public_key), &hash);
+ 
 -  return GNUNET_CONTAINER_multihashmap_get(member->sessions, &hash);
++  return GNUNET_CONTAINER_multihashmap_get (member->sessions, &hash);
+ }
+ 
 -struct GNUNET_MESSENGER_ClosureSearchSession {
++
++struct GNUNET_MESSENGER_ClosureSearchSession
++{
+   const struct GNUNET_MESSENGER_Message *message;
+   const struct GNUNET_HashCode *hash;
+ 
+   struct GNUNET_MESSENGER_MemberSession *match;
+ };
+ 
+ static int
+ iterate_search_session (void *cls,
+                         const struct GNUNET_HashCode *key,
+                         void *value)
+ {
 -  struct GNUNET_MESSENGER_ClosureSearchSession* search = cls;
++  struct GNUNET_MESSENGER_ClosureSearchSession *search = cls;
+   struct GNUNET_MESSENGER_MemberSession *session = value;
+ 
 -  if (GNUNET_OK != verify_member_session_as_sender(session, search->message, 
search->hash))
++  if (GNUNET_OK != verify_member_session_as_sender (session, search->message,
++                                                    search->hash))
+     return GNUNET_YES;
+ 
+   search->match = session;
+   return GNUNET_NO;
+ }
+ 
++
+ static struct GNUNET_MESSENGER_MemberSession*
+ try_member_session (struct GNUNET_MESSENGER_Member *member,
+                     const struct GNUNET_CRYPTO_PublicKey *public_key)
+ {
 -  struct GNUNET_MESSENGER_MemberSession* session = get_member_session(member, 
public_key);
++  struct GNUNET_MESSENGER_MemberSession *session = get_member_session (member,
++                                                                       
public_key);
+ 
+   if (session)
+     return session;
+ 
 -  session = create_member_session(member, public_key);
++  session = create_member_session (member, public_key);
+ 
+   if (session)
 -    add_member_session(member, session);
++    add_member_session (member, session);
+ 
+   return session;
+ }
+ 
++
+ struct GNUNET_MESSENGER_MemberSession*
+ get_member_session_of (struct GNUNET_MESSENGER_Member *member,
+                        const struct GNUNET_MESSENGER_Message *message,
+                        const struct GNUNET_HashCode *hash)
+ {
+   GNUNET_assert ((member) && (message) && (hash) &&
 -                 (0 == GNUNET_memcmp(&(member->id), 
&(message->header.sender_id))));
++                 (0 == GNUNET_memcmp (&(member->id),
++                                      &(message->header.sender_id))));
+ 
 -  if (GNUNET_MESSENGER_KIND_INFO == message->header.kind)
 -    return try_member_session(member, &(message->body.info.host_key));
 -  else if (GNUNET_MESSENGER_KIND_JOIN == message->header.kind)
 -    return try_member_session(member, &(message->body.join.key));
++  if (GNUNET_MESSENGER_KIND_JOIN == message->header.kind)
++    return try_member_session (member, &(message->body.join.key));
+ 
+   struct GNUNET_MESSENGER_ClosureSearchSession search;
+ 
+   search.message = message;
+   search.hash = hash;
+ 
+   search.match = NULL;
 -  GNUNET_CONTAINER_multihashmap_iterate(member->sessions, 
iterate_search_session, &search);
++  GNUNET_CONTAINER_multihashmap_iterate (member->sessions,
++                                         iterate_search_session, &search);
+ 
+   return search.match;
+ }
+ 
++
+ void
+ add_member_session (struct GNUNET_MESSENGER_Member *member,
+                     struct GNUNET_MESSENGER_MemberSession *session)
+ {
 -  if (!session)
++  if (! session)
+     return;
+ 
 -  GNUNET_assert((member) && (session->member == member));
++  GNUNET_assert ((member) && (session->member == member));
+ 
 -  const struct GNUNET_CRYPTO_PublicKey *public_key = 
get_member_session_public_key(session);
++  const struct GNUNET_CRYPTO_PublicKey *public_key =
++    get_member_session_public_key (session);
+ 
+   struct GNUNET_HashCode hash;
 -  GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash);
 -
 -  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
 -      member->sessions, &hash, session,
 -      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Adding a member session failed: 
%s\n",
 -               GNUNET_h2s(&hash));
++  GNUNET_CRYPTO_hash (public_key, sizeof(*public_key), &hash);
++
++  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (
++        member->sessions, &hash, session,
++        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Adding a member session failed: %s\n",
++                GNUNET_h2s (&hash));
+ }
+ 
++
+ void
+ remove_member_session (struct GNUNET_MESSENGER_Member *member,
+                        struct GNUNET_MESSENGER_MemberSession *session)
+ {
+   GNUNET_assert ((member) && (session) && (session->member == member));
+ 
 -  const struct GNUNET_CRYPTO_PublicKey *public_key = 
get_member_session_public_key(session);
++  const struct GNUNET_CRYPTO_PublicKey *public_key =
++    get_member_session_public_key (session);
+ 
+   struct GNUNET_HashCode hash;
 -  GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash);
++  GNUNET_CRYPTO_hash (public_key, sizeof(*public_key), &hash);
+ 
 -  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove(member->sessions, 
&hash, session))
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Removing a member session failed: 
%s\n",
 -               GNUNET_h2s(&hash));
++  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (member->sessions,
++                                                          &hash, session))
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Removing a member session failed: %s\n",
++                GNUNET_h2s (&hash));
+ }
+ 
 -struct GNUNET_MESSENGER_ClosureIterateSessions {
++
++struct GNUNET_MESSENGER_ClosureIterateSessions
++{
+   GNUNET_MESSENGER_MemberIteratorCallback it;
+   void *cls;
+ };
+ 
+ static int
+ iterate_member_sessions_it (void *cls,
+                             const struct GNUNET_HashCode *key,
+                             void *value)
+ {
+   struct GNUNET_MESSENGER_ClosureIterateSessions *iterate = cls;
+   struct GNUNET_MESSENGER_MemberSession *session = value;
+ 
 -  return iterate->it (iterate->cls, get_member_session_public_key(session), 
session);
++  return iterate->it (iterate->cls, get_member_session_public_key (session),
++                      session);
+ }
+ 
++
+ int
+ iterate_member_sessions (struct GNUNET_MESSENGER_Member *member,
+                          GNUNET_MESSENGER_MemberIteratorCallback it,
+                          void *cls)
+ {
+   GNUNET_assert ((member) && (member->sessions) && (it));
+ 
+   struct GNUNET_MESSENGER_ClosureIterateSessions iterate;
+ 
+   iterate.it = it;
+   iterate.cls = cls;
+ 
 -  return GNUNET_CONTAINER_multihashmap_iterate(member->sessions, 
iterate_member_sessions_it, &iterate);
++  return GNUNET_CONTAINER_multihashmap_iterate (member->sessions,
++                                                iterate_member_sessions_it,
++                                                &iterate);
+ }
diff --cc src/service/messenger/gnunet-service-messenger_member.h
index 000000000,c06be1df7..e456554a6
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_member.h
+++ b/src/service/messenger/gnunet-service-messenger_member.h
@@@ -1,0 -1,180 +1,180 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_member.h
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_SERVICE_MESSENGER_MEMBER_H
+ #define GNUNET_SERVICE_MESSENGER_MEMBER_H
+ 
+ #include "messenger_api_contact.h"
+ 
+ #include "gnunet-service-messenger_list_messages.h"
+ #include "gnunet-service-messenger_member_store.h"
+ #include "messenger_api_message.h"
+ #include "messenger_api_util.h"
+ 
+ struct GNUNET_MESSENGER_Member
+ {
+   struct GNUNET_MESSENGER_MemberStore *store;
+   struct GNUNET_ShortHashCode id;
+ 
+   struct GNUNET_CONTAINER_MultiHashMap *sessions;
+ };
+ 
+ /**
+  * Creates and allocates a new member of a <i>room</i> with an optionally 
defined or
+  * random <i>id</i>.
+  *
+  * If the creation fails, NULL gets returned.
+  *
+  * @param[in,out] store Member store
+  * @param[in] id Member id or NULL
+  * @return New member or NULL
+  */
+ struct GNUNET_MESSENGER_Member*
+ create_member (struct GNUNET_MESSENGER_MemberStore *store,
+                const struct GNUNET_ShortHashCode *id);
+ 
+ /**
+  * Destroys a member and frees its memory fully.
+  *
+  * @param[in,out] member Member
+  */
+ void
+ destroy_member (struct GNUNET_MESSENGER_Member *member);
+ 
+ /**
+  * Returns the current id of a given <i>member</i>.
+  *
+  * @param[in] member Member
+  * @return Member id
+  */
+ const struct GNUNET_ShortHashCode*
+ get_member_id (const struct GNUNET_MESSENGER_Member *member);
+ 
+ /**
+  * Loads data from a <i>directory</i> into a new allocated and created member
+  * of a <i>store</i> if the required information can be read from the content
+  * of the given directory.
+  *
+  * @param[out] store Member store
+  * @param[in] directory Path to a directory
+  */
+ void
+ load_member (struct GNUNET_MESSENGER_MemberStore *store,
+              const char *directory);
+ 
+ /**
+  * Loads data about next sessions from a <i>directory</i> into an empty loaded
+  * <i>member</i> which does not contain a fully built session graph yet.
+  *
+  * @param[in,out] member Member
+  * @param[in] directory Path to a directory
+  */
+ void
+ load_member_next_sessions (const struct GNUNET_MESSENGER_Member *member,
+                            const char *directory);
+ 
+ /**
+  * Saves data from a <i>member</i> into a directory which
+  * can be load to restore the member completely.
+  *
+  * @param[in] member Member
+  * @param[in] directory Path to a directory
+  */
+ void
+ save_member (struct GNUNET_MESSENGER_Member *member,
+              const char *directory);
+ 
+ /**
+  * Synchronizes contacts between all sessions from a given <i>member</i>
+  * and other sessions which are linked to them.
+  *
+  * @param[in,out] member Member
+  */
+ void
+ sync_member_contacts (struct GNUNET_MESSENGER_Member *member);
+ 
+ /**
+  * Returns the member session of a <i>member</i> identified by a given public 
key.
+  * If the member does not provide a session with the given key, NULL gets 
returned.
+  *
+  * @param[in] member Member
+  * @param[in] public_key Public key of EGO
+  * @return Member session
+  */
+ struct GNUNET_MESSENGER_MemberSession*
+ get_member_session (const struct GNUNET_MESSENGER_Member *member,
+                     const struct GNUNET_CRYPTO_PublicKey *public_key);
+ 
+ /**
+  * Returns the member session of a <i>member</i> using a public key which can 
verify
+  * the signature of a given <i>message</i> and its <i>hash</i>. If the member 
does
+  * not provide a matching session, NULL gets returned.
+  *
+  * @param[in] member Member
+  * @param[in] message Message
+  * @param[in] hash Hash of message
+  * @return Member session
+  */
+ struct GNUNET_MESSENGER_MemberSession*
+ get_member_session_of (struct GNUNET_MESSENGER_Member *member,
+                        const struct GNUNET_MESSENGER_Message *message,
+                        const struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Adds a given member <i>session</i> to its <i>member</i>.
+  *
+  * @param[in,out] member Member
+  * @param[in,out] session Member session
+  */
+ void
+ add_member_session (struct GNUNET_MESSENGER_Member *member,
+                     struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Removes a given member <i>session</i> from its <i>member</i>.
+  *
+  * @param[in,out] member Member
+  * @param[in,out] session Member session
+  */
+ void
+ remove_member_session (struct GNUNET_MESSENGER_Member *member,
+                        struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Iterate through all member sessions currently connected to a given 
<i>member</i>
+  * and call the provided iterator callback with a selected closure. The 
function
+  * will return the amount of member sessions it iterated through.
+  *
+  * @param[in,out] member Member
+  * @param[in] it Iterator callback
+  * @param[in,out] cls Closure
+  * @return Amount of sessions iterated through
+  */
+ int
+ iterate_member_sessions (struct GNUNET_MESSENGER_Member *member,
+                          GNUNET_MESSENGER_MemberIteratorCallback it,
 -                         void* cls);
++                         void *cls);
+ 
+ #endif //GNUNET_SERVICE_MESSENGER_MEMBER_H
diff --cc src/service/messenger/gnunet-service-messenger_member_session.c
index 000000000,8ae1244c4..8b369d2c4
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_member_session.c
+++ b/src/service/messenger/gnunet-service-messenger_member_session.c
@@@ -1,0 -1,766 +1,857 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2021--2022 GNUnet e.V.
++   Copyright (C) 2021--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_member_session.c
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "gnunet-service-messenger_member_session.h"
+ 
+ #include "gnunet-service-messenger_room.h"
+ #include "gnunet-service-messenger_message_store.h"
+ 
+ #include "messenger_api_contact_store.h"
+ 
+ struct GNUNET_MESSENGER_MemberSession*
+ create_member_session (struct GNUNET_MESSENGER_Member *member,
+                        const struct GNUNET_CRYPTO_PublicKey *pubkey)
+ {
 -  if ((!member) || (!pubkey) || (!(member->store)))
++  if ((! member) || (! pubkey) || (! (member->store)))
+     return NULL;
+ 
 -  struct GNUNET_MESSENGER_MemberSession *session = GNUNET_new(struct 
GNUNET_MESSENGER_MemberSession);
++  struct GNUNET_MESSENGER_MemberSession *session = GNUNET_new (struct
++                                                               
GNUNET_MESSENGER_MemberSession);
+   session->member = member;
+ 
 -  GNUNET_memcpy(&(session->public_key), pubkey, sizeof(session->public_key));
++  GNUNET_memcpy (&(session->public_key), pubkey, sizeof(session->public_key));
+ 
+   get_context_from_member (
 -      get_member_session_key (session),
 -      get_member_session_id (session),
 -      &(session->context)
 -  );
++    get_member_session_key (session),
++    get_member_session_id (session),
++    &(session->context)
++    );
+ 
 -  struct GNUNET_MESSENGER_ContactStore *store = 
get_member_contact_store(session->member->store);
++  struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store (
++    session->member->store);
+ 
 -  session->contact = get_store_contact(
 -      store,
 -      get_member_session_context (session),
 -      get_member_session_public_key (session)
 -  );
++  session->contact = get_store_contact (
++    store,
++    get_member_session_context (session),
++    get_member_session_public_key (session)
++    );
+ 
 -  if (!(session->contact))
++  if (! (session->contact))
+   {
 -    GNUNET_free(session);
++    GNUNET_free (session);
+     return NULL;
+   }
+ 
+   increase_contact_rc (session->contact);
+ 
 -  session->history = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
++  session->history = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
+ 
 -  init_list_messages(&(session->messages));
++  init_list_messages (&(session->messages));
+ 
+   session->prev = NULL;
+   session->next = NULL;
+ 
 -  session->start = GNUNET_TIME_absolute_get();
++  session->start = GNUNET_TIME_absolute_get ();
+ 
+   session->closed = GNUNET_NO;
+   session->completed = GNUNET_NO;
+ 
+   return session;
+ }
+ 
++
+ static void
+ check_member_session_completion (struct GNUNET_MESSENGER_MemberSession 
*session)
+ {
+   GNUNET_assert (session);
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Check session history (%s) for 
completion.\n",
 -             GNUNET_sh2s(get_member_session_id(session)));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Check session history (%s) for completion.\n",
++              GNUNET_sh2s (get_member_session_id (session)));
+ 
 -  if (!session->messages.tail)
++  if (! session->messages.tail)
+   {
+     session->completed = GNUNET_YES;
+     goto completion;
+   }
+ 
 -  const struct GNUNET_HashCode* start = &(session->messages.head->hash);
 -  const struct GNUNET_HashCode* end = &(session->messages.tail->hash);
++  const struct GNUNET_HashCode *start = &(session->messages.head->hash);
++  const struct GNUNET_HashCode *end = &(session->messages.tail->hash);
+ 
+   struct GNUNET_MESSENGER_ListMessages level;
 -  init_list_messages(&level);
++  init_list_messages (&level);
+ 
 -  add_to_list_messages(&level, end);
++  add_to_list_messages (&level, end);
+ 
 -  struct GNUNET_MESSENGER_MessageStore *store = 
get_srv_room_message_store(session->member->store->room);
++  struct GNUNET_MESSENGER_MessageStore *store = get_srv_room_message_store (
++    session->member->store->room);
+ 
+   struct GNUNET_MESSENGER_ListMessages list;
 -  init_list_messages(&list);
++  init_list_messages (&list);
+ 
+   while (level.head)
+   {
+     struct GNUNET_MESSENGER_ListMessage *element;
+ 
+     for (element = level.head; element; element = element->next)
+     {
 -      const struct GNUNET_MESSENGER_MessageLink *link = 
get_store_message_link(
 -          store, &(element->hash), GNUNET_NO
 -      );
++      const struct GNUNET_MESSENGER_MessageLink *link = 
get_store_message_link (
++        store, &(element->hash), GNUNET_NO
++        );
+ 
 -      if (!link)
++      if (! link)
+         continue;
+ 
 -      add_to_list_messages(&list, &(link->first));
++      add_to_list_messages (&list, &(link->first));
+ 
+       if (GNUNET_YES == link->multiple)
 -        add_to_list_messages(&list, &(link->second));
++        add_to_list_messages (&list, &(link->second));
+     }
+ 
 -    clear_list_messages(&level);
++    clear_list_messages (&level);
+ 
+     for (element = list.head; element; element = element->next)
 -      if (GNUNET_YES == check_member_session_history(session, 
&(element->hash), GNUNET_YES))
++      if (GNUNET_YES == check_member_session_history (session, 
&(element->hash),
++                                                      GNUNET_YES))
+         break;
+ 
+     if (element)
 -      if (0 != GNUNET_CRYPTO_hash_cmp(&(element->hash), start))
 -        add_to_list_messages(&level, &(element->hash));
++      if (0 != GNUNET_CRYPTO_hash_cmp (&(element->hash), start))
++        add_to_list_messages (&level, &(element->hash));
+       else
+         session->completed = GNUNET_YES;
+     else
 -      copy_list_messages(&level, &list);
++      copy_list_messages (&level, &list);
+ 
 -    clear_list_messages(&list);
++    clear_list_messages (&list);
+   }
+ 
+ completion:
 -  if (GNUNET_YES == is_member_session_completed(session))
++  if (GNUNET_YES == is_member_session_completed (session))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Completed session history (%s)\n",
 -               GNUNET_sh2s(get_member_session_id(session)));
++    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Completed session history (%s)\n",
++                GNUNET_sh2s (get_member_session_id (session)));
+ 
+     GNUNET_CONTAINER_multihashmap_clear (session->history);
+ 
 -    struct GNUNET_MESSENGER_ContactStore *store = 
get_member_contact_store(session->member->store);
++    struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store (
++      session->member->store);
+ 
 -    if ((session->contact) && (GNUNET_YES == decrease_contact_rc 
(session->contact)))
++    if ((session->contact) && (GNUNET_YES == decrease_contact_rc (
++                                 session->contact)))
+       remove_store_contact (
 -          store,
 -          session->contact,
 -          get_member_session_context(session)
 -      );
++        store,
++        session->contact,
++        get_member_session_context (session)
++        );
+ 
+     session->contact = NULL;
+   }
+ }
+ 
++
+ static int
+ iterate_copy_history (void *cls,
+                       const struct GNUNET_HashCode *key,
+                       void *value)
+ {
+   struct GNUNET_MESSENGER_MemberSession *next = cls;
+ 
 -  GNUNET_CONTAINER_multihashmap_put(next->history, key, (value? next : NULL),
 -                                    
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
++  GNUNET_CONTAINER_multihashmap_put (next->history, key, (value? next : NULL),
++                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ struct GNUNET_MESSENGER_MemberSession*
+ switch_member_session (struct GNUNET_MESSENGER_MemberSession *session,
+                        const struct GNUNET_MESSENGER_Message *message,
+                        const struct GNUNET_HashCode *hash)
+ {
 -  if ((!session) || (!message) || (!hash))
++  if ((! session) || (! message) || (! hash))
+     return NULL;
+ 
 -  GNUNET_assert((GNUNET_MESSENGER_KIND_ID == message->header.kind) ||
 -                (GNUNET_MESSENGER_KIND_KEY == message->header.kind));
++  GNUNET_assert ((GNUNET_MESSENGER_KIND_ID == message->header.kind) ||
++                 (GNUNET_MESSENGER_KIND_KEY == message->header.kind));
+ 
 -  struct GNUNET_MESSENGER_MemberSession *next = GNUNET_new(struct 
GNUNET_MESSENGER_MemberSession);
++  struct GNUNET_MESSENGER_MemberSession *next = GNUNET_new (struct
++                                                            
GNUNET_MESSENGER_MemberSession);
+ 
+   if (GNUNET_MESSENGER_KIND_ID == message->header.kind)
 -    next->member = add_store_member(session->member->store, 
&(message->body.id.id));
++    next->member = add_store_member (session->member->store,
++                                     &(message->body.id.id));
+   else
+     next->member = session->member;
+ 
+   if (GNUNET_MESSENGER_KIND_KEY == message->header.kind)
 -    GNUNET_memcpy(&(next->public_key), &(message->body.key.key), 
sizeof(next->public_key));
++    GNUNET_memcpy (&(next->public_key), &(message->body.key.key),
++                   sizeof(next->public_key));
+   else
 -    GNUNET_memcpy(&(next->public_key), 
get_member_session_public_key(session), sizeof(next->public_key));
++    GNUNET_memcpy (&(next->public_key), get_member_session_public_key 
(session),
++                   sizeof(next->public_key));
+ 
+   get_context_from_member (
 -      get_member_session_key (next),
 -      get_member_session_id (next),
 -      &(next->context)
 -  );
 -
 -  update_store_contact(
 -      get_member_contact_store(next->member->store),
 -      get_member_session_contact(session),
 -      get_member_session_context(session),
 -      get_member_session_context(next),
 -      get_member_session_public_key(next)
 -  );
 -
 -  next->contact = get_member_session_contact(session);
 -
 -  if (!(next->contact))
++    get_member_session_key (next),
++    get_member_session_id (next),
++    &(next->context)
++    );
++
++  update_store_contact (
++    get_member_contact_store (next->member->store),
++    get_member_session_contact (session),
++    get_member_session_context (session),
++    get_member_session_context (next),
++    get_member_session_public_key (next)
++    );
++
++  next->contact = get_member_session_contact (session);
++
++  if (! (next->contact))
+   {
 -    GNUNET_free(next);
++    GNUNET_free (next);
+     return NULL;
+   }
+ 
+   increase_contact_rc (next->contact);
+ 
 -  next->history = GNUNET_CONTAINER_multihashmap_create(
 -      GNUNET_CONTAINER_multihashmap_size(session->history), GNUNET_NO
 -  );
++  next->history = GNUNET_CONTAINER_multihashmap_create (
++    GNUNET_CONTAINER_multihashmap_size (session->history), GNUNET_NO
++    );
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate(session->history, 
iterate_copy_history, next);
++  GNUNET_CONTAINER_multihashmap_iterate (session->history, 
iterate_copy_history,
++                                         next);
+ 
 -  init_list_messages(&(next->messages));
 -  copy_list_messages(&(next->messages), &(session->messages));
++  init_list_messages (&(next->messages));
++  copy_list_messages (&(next->messages), &(session->messages));
+ 
+   session->next = next;
+   next->prev = session;
+   next->next = NULL;
+ 
 -  next->start = GNUNET_TIME_absolute_get();
++  next->start = GNUNET_TIME_absolute_get ();
+ 
+   session->closed = GNUNET_YES;
+   next->closed = GNUNET_NO;
+   next->completed = GNUNET_NO;
+ 
+   check_member_session_completion (session);
+ 
+   return next;
+ }
+ 
++
+ void
 -destroy_member_session(struct GNUNET_MESSENGER_MemberSession* session)
++destroy_member_session (struct GNUNET_MESSENGER_MemberSession *session)
+ {
+   GNUNET_assert (session);
+ 
+   GNUNET_CONTAINER_multihashmap_destroy (session->history);
+ 
+   clear_list_messages (&(session->messages));
+ 
 -  struct GNUNET_MESSENGER_Contact *contact = get_member_session_contact 
(session);
++  struct GNUNET_MESSENGER_Contact *contact = get_member_session_contact (
++    session);
+ 
+   if ((contact) && (GNUNET_YES == decrease_contact_rc (contact)))
+     remove_store_contact (
 -        get_member_contact_store(session->member->store),
 -        contact,
 -        get_member_session_context(session)
 -    );
++      get_member_contact_store (session->member->store),
++      contact,
++      get_member_session_context (session)
++      );
+ 
 -  GNUNET_free(session);
++  GNUNET_free (session);
+ }
+ 
++
+ int
 -reset_member_session (struct GNUNET_MESSENGER_MemberSession* session,
++reset_member_session (struct GNUNET_MESSENGER_MemberSession *session,
+                       const struct GNUNET_HashCode *hash)
+ {
+   GNUNET_assert ((session) && (hash));
+ 
 -  struct GNUNET_MESSENGER_ContactStore *store = 
get_member_contact_store(session->member->store);
 -  struct GNUNET_MESSENGER_Contact *contact = get_store_contact(
 -      store,
 -      get_member_session_context (session),
 -      get_member_session_public_key (session)
 -  );
++  struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store (
++    session->member->store);
++  struct GNUNET_MESSENGER_Contact *contact = get_store_contact (
++    store,
++    get_member_session_context (session),
++    get_member_session_public_key (session)
++    );
+ 
 -  if (!contact)
++  if (! contact)
+     return GNUNET_SYSERR;
+ 
+   if (contact == session->contact)
+     goto clear_messages;
+ 
+   session->contact = contact;
+   increase_contact_rc (session->contact);
+ 
+ clear_messages:
 -  clear_list_messages(&(session->messages));
 -  add_to_list_messages(&(session->messages), hash);
++  clear_list_messages (&(session->messages));
++  add_to_list_messages (&(session->messages), hash);
+ 
+   session->next = NULL;
+   session->closed = GNUNET_NO;
+   session->completed = GNUNET_NO;
+ 
+   return GNUNET_OK;
+ }
+ 
++
+ void
 -close_member_session (struct GNUNET_MESSENGER_MemberSession* session)
++close_member_session (struct GNUNET_MESSENGER_MemberSession *session)
+ {
+   GNUNET_assert (session);
+ 
+   session->closed = GNUNET_YES;
+   check_member_session_completion (session);
+ }
+ 
++
+ int
 -is_member_session_closed (const struct GNUNET_MESSENGER_MemberSession* 
session)
++is_member_session_closed (const struct GNUNET_MESSENGER_MemberSession 
*session)
+ {
 -  GNUNET_assert(session);
++  GNUNET_assert (session);
+ 
+   return session->closed;
+ }
+ 
++
+ int
 -is_member_session_completed (const struct GNUNET_MESSENGER_MemberSession* 
session)
++is_member_session_completed (const struct
++                             GNUNET_MESSENGER_MemberSession *session)
+ {
 -  GNUNET_assert(session);
++  GNUNET_assert (session);
+ 
+   return session->completed;
+ }
+ 
++
+ struct GNUNET_TIME_Absolute
 -get_member_session_start (const struct GNUNET_MESSENGER_MemberSession* 
session)
++get_member_session_start (const struct GNUNET_MESSENGER_MemberSession 
*session)
+ {
 -  GNUNET_assert(session);
++  GNUNET_assert (session);
+ 
+   if (session->prev)
 -    return get_member_session_start(session->prev);
++    return get_member_session_start (session->prev);
+ 
+   return session->start;
+ }
+ 
++
+ const struct GNUNET_HashCode*
 -get_member_session_key (const struct GNUNET_MESSENGER_MemberSession* session)
++get_member_session_key (const struct GNUNET_MESSENGER_MemberSession *session)
+ {
 -  GNUNET_assert((session) && (session->member));
++  GNUNET_assert ((session) && (session->member));
+ 
 -  return get_member_store_key(session->member->store);
++  return get_member_store_key (session->member->store);
+ }
+ 
++
+ const struct GNUNET_ShortHashCode*
 -get_member_session_id (const struct GNUNET_MESSENGER_MemberSession* session)
++get_member_session_id (const struct GNUNET_MESSENGER_MemberSession *session)
+ {
 -  GNUNET_assert(session);
++  GNUNET_assert (session);
+ 
 -  return get_member_id(session->member);
++  return get_member_id (session->member);
+ }
+ 
++
+ const struct GNUNET_CRYPTO_PublicKey*
 -get_member_session_public_key (const struct GNUNET_MESSENGER_MemberSession* 
session)
++get_member_session_public_key (const struct
++                               GNUNET_MESSENGER_MemberSession *session)
+ {
 -  GNUNET_assert(session);
++  GNUNET_assert (session);
+ 
+   return &(session->public_key);
+ }
+ 
++
+ const struct GNUNET_HashCode*
 -get_member_session_context (const struct GNUNET_MESSENGER_MemberSession* 
session)
++get_member_session_context (const struct
++                            GNUNET_MESSENGER_MemberSession *session)
+ {
 -  GNUNET_assert(session);
++  GNUNET_assert (session);
+ 
+   return &(session->context);
+ }
+ 
++
+ struct GNUNET_MESSENGER_Contact*
 -get_member_session_contact (struct GNUNET_MESSENGER_MemberSession* session)
++get_member_session_contact (struct GNUNET_MESSENGER_MemberSession *session)
+ {
+   GNUNET_assert (session);
+ 
+   return session->contact;
+ }
+ 
 -int verify_member_session_as_sender (const struct 
GNUNET_MESSENGER_MemberSession *session,
 -                                     const struct GNUNET_MESSENGER_Message 
*message,
 -                                     const struct GNUNET_HashCode *hash)
++
++int
++verify_member_session_as_sender (const struct
++                                 GNUNET_MESSENGER_MemberSession *session,
++                                 const struct GNUNET_MESSENGER_Message 
*message,
++                                 const struct GNUNET_HashCode *hash)
+ {
 -  GNUNET_assert((session) && (message) && (hash));
++  GNUNET_assert ((session) && (message) && (hash));
+ 
 -  if (GNUNET_YES == is_member_session_completed(session))
++  if (GNUNET_YES == is_member_session_completed (session))
+     return GNUNET_SYSERR;
+ 
 -  if (0 != GNUNET_memcmp(get_member_session_id(session), 
&(message->header.sender_id)))
++  if (0 != GNUNET_memcmp (get_member_session_id (session),
++                          &(message->header.sender_id)))
+     return GNUNET_SYSERR;
+ 
 -  return verify_message(message, hash, 
get_member_session_public_key(session));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Check message (%s) using key: %s\n",
++              GNUNET_h2s (hash),
++              GNUNET_CRYPTO_public_key_to_string (
++                get_member_session_public_key (session)));
++
++  return verify_message (message, hash, get_member_session_public_key (
++                           session));
+ }
+ 
++
+ int
 -check_member_session_history (const struct GNUNET_MESSENGER_MemberSession 
*session,
++check_member_session_history (const struct
++                              GNUNET_MESSENGER_MemberSession *session,
+                               const struct GNUNET_HashCode *hash, int 
ownership)
+ {
 -  GNUNET_assert((session) && (hash));
++  GNUNET_assert ((session) && (hash));
+ 
+   if (GNUNET_YES == ownership)
 -    return (NULL != GNUNET_CONTAINER_multihashmap_get(session->history, 
hash)? GNUNET_YES : GNUNET_NO);
++    return (NULL != GNUNET_CONTAINER_multihashmap_get (session->history, 
hash)?
++            GNUNET_YES : GNUNET_NO);
+   else
 -    return GNUNET_CONTAINER_multihashmap_contains(session->history, hash);
++    return GNUNET_CONTAINER_multihashmap_contains (session->history, hash);
+ }
+ 
++
+ static void
+ update_member_chain_history (struct GNUNET_MESSENGER_MemberSession *session,
+                              const struct GNUNET_HashCode *hash, int 
ownership)
+ {
+   GNUNET_assert ((session) && (hash));
+ 
 -  if ((GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(session->history, hash, 
(GNUNET_YES == ownership? session : NULL),
 -                                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) && (session->next))
++  if ((GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (session->history, hash,
++                                                       (GNUNET_YES == 
ownership?
++                                                        session : NULL),
++                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
++      && (session->next))
+     update_member_chain_history (session->next, hash, ownership);
+ }
+ 
++
+ void
+ update_member_session_history (struct GNUNET_MESSENGER_MemberSession *session,
+                                const struct GNUNET_MESSENGER_Message *message,
+                                const struct GNUNET_HashCode *hash)
+ {
 -  GNUNET_assert((session) && (message) && (hash));
++  GNUNET_assert ((session) && (message) && (hash));
+ 
 -  if (GNUNET_YES == is_member_session_completed(session))
++  if (GNUNET_YES == is_member_session_completed (session))
+     return;
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Updating sessions history (%s) += 
(%s)\n",
 -             GNUNET_sh2s(get_member_session_id(session)), GNUNET_h2s(hash));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Updating sessions history (%s) += (%s)\n",
++              GNUNET_sh2s (get_member_session_id (session)), GNUNET_h2s 
(hash));
+ 
+   if (GNUNET_OK == verify_member_session_as_sender (session, message, hash))
+   {
+     if (GNUNET_YES == is_message_session_bound (message))
 -      add_to_list_messages(&(session->messages), hash);
++      add_to_list_messages (&(session->messages), hash);
+ 
+     update_member_chain_history (session, hash, GNUNET_YES);
+   }
+   else
+     update_member_chain_history (session, hash, GNUNET_NO);
+ 
+   if (GNUNET_YES == session->closed)
 -    check_member_session_completion(session);
++    check_member_session_completion (session);
+ }
+ 
++
+ static void
+ clear_member_chain_history (struct GNUNET_MESSENGER_MemberSession *session,
+                             const struct GNUNET_HashCode *hash)
+ {
+   GNUNET_assert ((session) && (hash));
+ 
 -  if ((0 < GNUNET_CONTAINER_multihashmap_remove_all(session->history, hash)) 
&& (session->next))
 -    clear_member_session_history(session->next, hash);
++  if ((0 < GNUNET_CONTAINER_multihashmap_remove_all (session->history, hash)) 
&&
++      (session->next))
++    clear_member_session_history (session->next, hash);
+ }
+ 
++
+ void
+ clear_member_session_history (struct GNUNET_MESSENGER_MemberSession *session,
+                               const struct GNUNET_HashCode *hash)
+ {
 -  GNUNET_assert((session) && (hash));
++  GNUNET_assert ((session) && (hash));
+ 
+   clear_member_chain_history (session, hash);
+ }
+ 
++
+ struct GNUNET_MESSENGER_MemberSessionHistoryEntry
+ {
+   struct GNUNET_HashCode hash;
+   unsigned char ownership;
+ };
+ 
+ static void
+ load_member_session_history (struct GNUNET_MESSENGER_MemberSession *session,
+                              const char *path)
+ {
 -  GNUNET_assert((session) && (path));
++  GNUNET_assert ((session) && (path));
+ 
+   if (GNUNET_YES != GNUNET_DISK_file_test (path))
+     return;
+ 
 -  enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ 
| GNUNET_DISK_PERM_USER_WRITE);
++  enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ
++                                                   | 
GNUNET_DISK_PERM_USER_WRITE);
+ 
 -  struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open(
 -      path, GNUNET_DISK_OPEN_READ, permission
 -  );
++  struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open (
++    path, GNUNET_DISK_OPEN_READ, permission
++    );
+ 
 -  if (!handle)
++  if (! handle)
+     return;
+ 
 -  GNUNET_DISK_file_seek(handle, 0, GNUNET_DISK_SEEK_SET);
++  GNUNET_DISK_file_seek (handle, 0, GNUNET_DISK_SEEK_SET);
+ 
+   struct GNUNET_MESSENGER_MemberSessionHistoryEntry entry;
+   ssize_t len;
+ 
+   int status;
+ 
+   do {
 -    len = GNUNET_DISK_file_read(handle, &(entry.hash), sizeof(entry.hash));
++    len = GNUNET_DISK_file_read (handle, &(entry.hash), sizeof(entry.hash));
+ 
+     if (len != sizeof(entry.hash))
+       break;
+ 
 -    len = GNUNET_DISK_file_read(handle, &(entry.ownership), 
sizeof(entry.ownership));
++    len = GNUNET_DISK_file_read (handle, &(entry.ownership),
++                                 sizeof(entry.ownership));
+ 
+     if (len != sizeof(entry.ownership))
+       break;
+ 
 -    status = GNUNET_CONTAINER_multihashmap_put(session->history, 
&(entry.hash), (entry.ownership? session : NULL),
 -                                               
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
++    status = GNUNET_CONTAINER_multihashmap_put (session->history, 
&(entry.hash),
++                                                (entry.ownership? session :
++                                                 NULL),
++                                                
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+   } while (status == GNUNET_OK);
+ 
 -  GNUNET_DISK_file_close(handle);
++  GNUNET_DISK_file_close (handle);
+ }
+ 
++
+ void
+ load_member_session (struct GNUNET_MESSENGER_Member *member,
+                      const char *directory)
+ {
+   GNUNET_assert ((member) && (directory));
+ 
+   char *config_file;
+   GNUNET_asprintf (&config_file, "%s%s", directory, "session.cfg");
+ 
+   struct GNUNET_MESSENGER_MemberSession *session = NULL;
+ 
+   if (GNUNET_YES != GNUNET_DISK_file_test (config_file))
+     goto free_config;
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load session configuration of member: 
%s\n", config_file);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Load session configuration of member: %s\n", config_file);
+ 
+   struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
+ 
+   if (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, config_file))
+   {
+     char *key_data;
+ 
 -    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "session", 
"key", &key_data))
++    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "session",
++                                                            "key", &key_data))
+       goto destroy_config;
+ 
+     struct GNUNET_CRYPTO_PublicKey key;
+ 
 -    enum GNUNET_GenericReturnValue key_return = 
GNUNET_CRYPTO_public_key_from_string(key_data, &key);
++    enum GNUNET_GenericReturnValue key_return =
++      GNUNET_CRYPTO_public_key_from_string (key_data, &key);
+ 
 -    GNUNET_free(key_data);
++    GNUNET_free (key_data);
+ 
+     if (GNUNET_OK != key_return)
+       goto destroy_config;
+ 
 -    session = create_member_session(member, &key);
++    session = create_member_session (member, &key);
+ 
+     unsigned long long numeric_value;
+ 
 -    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "session", 
"start", &numeric_value))
++    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "session",
++                                                            "start",
++                                                            &numeric_value))
+       session->start.abs_value_us = numeric_value;
+ 
 -    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "session", 
"closed", &numeric_value))
++    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "session",
++                                                            "closed",
++                                                            &numeric_value))
+       session->closed = (GNUNET_YES == numeric_value? GNUNET_YES : GNUNET_NO);
+ 
 -    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "session", 
"completed", &numeric_value))
 -      session->completed = (GNUNET_YES == numeric_value? GNUNET_YES : 
GNUNET_NO);
++    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "session",
++                                                            "completed",
++                                                            &numeric_value))
++      session->completed = (GNUNET_YES == numeric_value? GNUNET_YES :
++                            GNUNET_NO);
+   }
+ 
+ destroy_config:
+   GNUNET_CONFIGURATION_destroy (cfg);
+ 
+ free_config:
 -  GNUNET_free(config_file);
++  GNUNET_free (config_file);
+ 
 -  if (!session)
++  if (! session)
+     return;
+ 
+   char *history_file;
+   GNUNET_asprintf (&history_file, "%s%s", directory, "history.map");
+ 
+   load_member_session_history (session, history_file);
 -  GNUNET_free(history_file);
++  GNUNET_free (history_file);
+ 
+   char *messages_file;
+   GNUNET_asprintf (&messages_file, "%s%s", directory, "messages.list");
+ 
 -  load_list_messages(&(session->messages), messages_file);
 -  GNUNET_free(messages_file);
++  load_list_messages (&(session->messages), messages_file);
++  GNUNET_free (messages_file);
+ 
 -  add_member_session(member, session);
++  add_member_session (member, session);
+ }
+ 
++
+ static struct GNUNET_MESSENGER_MemberSession*
+ get_cycle_safe_next_session (struct GNUNET_MESSENGER_MemberSession *session,
+                              struct GNUNET_MESSENGER_MemberSession *next)
+ {
 -  if (!next)
++  if (! next)
+     return NULL;
+ 
+   struct GNUNET_MESSENGER_MemberSession *check = next;
+ 
+   do {
+     if (check == session)
+       return NULL;
+ 
+     check = check->next;
+   } while (check);
+ 
+   return next;
+ }
+ 
++
+ void
+ load_member_session_next (struct GNUNET_MESSENGER_MemberSession *session,
+                           const char *directory)
+ {
+   GNUNET_assert ((session) && (directory));
+ 
+   char *config_file;
+   GNUNET_asprintf (&config_file, "%s%s", directory, "session.cfg");
+ 
+   if (GNUNET_YES != GNUNET_DISK_file_test (config_file))
+     goto free_config;
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load next session configuration of 
member: %s\n", config_file);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Load next session configuration of member: %s\n", config_file);
+ 
+   struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
+ 
+   if (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, config_file))
+   {
+     char *key_data;
+ 
 -    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "session", 
"next_key", &key_data))
++    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "session",
++                                                            "next_key",
++                                                            &key_data))
+       goto destroy_config;
+ 
+     struct GNUNET_CRYPTO_PublicKey next_key;
+ 
 -    enum GNUNET_GenericReturnValue key_return = 
GNUNET_CRYPTO_public_key_from_string(key_data, &next_key);
++    enum GNUNET_GenericReturnValue key_return =
++      GNUNET_CRYPTO_public_key_from_string (key_data, &next_key);
+ 
 -    GNUNET_free(key_data);
++    GNUNET_free (key_data);
+ 
+     if (GNUNET_OK != key_return)
+       goto destroy_config;
+ 
+     struct GNUNET_ShortHashCode next_id;
+ 
 -    if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "session", 
"next_id", &next_id, sizeof(next_id)))
++    if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "session", "next_id",
++                                                    &next_id, 
sizeof(next_id)))
+       goto destroy_config;
+ 
 -    struct GNUNET_MESSENGER_Member *member = 
get_store_member(session->member->store, &next_id);
++    struct GNUNET_MESSENGER_Member *member = get_store_member (
++      session->member->store, &next_id);
+ 
 -    session->next = get_cycle_safe_next_session(
 -        session, member? get_member_session (member, &next_key) : NULL
 -    );
++    session->next = get_cycle_safe_next_session (
++      session, member? get_member_session (member, &next_key) : NULL
++      );
+ 
+     if (session->next)
+       session->next->prev = session;
+   }
+ 
+ destroy_config:
+   GNUNET_CONFIGURATION_destroy (cfg);
+ 
+ free_config:
 -  GNUNET_free(config_file);
++  GNUNET_free (config_file);
+ }
+ 
++
+ static int
+ iterate_save_member_session_history_hentries (void *cls,
+                                               const struct GNUNET_HashCode 
*key,
+                                               void *value)
+ {
+   struct GNUNET_DISK_FileHandle *handle = cls;
+   unsigned char ownership = value? GNUNET_YES : GNUNET_NO;
+ 
 -  GNUNET_DISK_file_write(handle, key, sizeof(*key));
 -  GNUNET_DISK_file_write(handle, &ownership, sizeof(ownership));
++  GNUNET_DISK_file_write (handle, key, sizeof(*key));
++  GNUNET_DISK_file_write (handle, &ownership, sizeof(ownership));
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ static void
+ save_member_session_history (struct GNUNET_MESSENGER_MemberSession *session,
+                              const char *path)
+ {
 -  GNUNET_assert((session) && (path));
++  GNUNET_assert ((session) && (path));
+ 
 -  enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ 
| GNUNET_DISK_PERM_USER_WRITE);
++  enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ
++                                                   | 
GNUNET_DISK_PERM_USER_WRITE);
+ 
 -  struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open(
 -      path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission
 -  );
++  struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open (
++    path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission
++    );
+ 
 -  if (!handle)
++  if (! handle)
+     return;
+ 
 -  GNUNET_DISK_file_seek(handle, 0, GNUNET_DISK_SEEK_SET);
++  GNUNET_DISK_file_seek (handle, 0, GNUNET_DISK_SEEK_SET);
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate(
 -      session->history,
 -      iterate_save_member_session_history_hentries,
 -      handle
 -  );
++  GNUNET_CONTAINER_multihashmap_iterate (
++    session->history,
++    iterate_save_member_session_history_hentries,
++    handle
++    );
+ 
 -  GNUNET_DISK_file_sync(handle);
 -  GNUNET_DISK_file_close(handle);
++  GNUNET_DISK_file_sync (handle);
++  GNUNET_DISK_file_close (handle);
+ }
+ 
++
+ void
+ save_member_session (struct GNUNET_MESSENGER_MemberSession *session,
+                      const char *directory)
+ {
+   GNUNET_assert ((session) && (directory));
+ 
+   char *config_file;
+   GNUNET_asprintf (&config_file, "%s%s", directory, "session.cfg");
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save session configuration of member: 
%s\n", config_file);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Save session configuration of member: %s\n", config_file);
+ 
+   struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
+ 
 -  char *key_data = 
GNUNET_CRYPTO_public_key_to_string(get_member_session_public_key(session));
++  char *key_data = GNUNET_CRYPTO_public_key_to_string (
++    get_member_session_public_key (session));
+ 
+   if (key_data)
+   {
+     GNUNET_CONFIGURATION_set_value_string (cfg, "session", "key", key_data);
+ 
 -    GNUNET_free(key_data);
++    GNUNET_free (key_data);
+   }
+ 
+   if (session->next)
+   {
 -    const struct GNUNET_ShortHashCode *next_id = 
get_member_session_id(session->next);
++    const struct GNUNET_ShortHashCode *next_id = get_member_session_id (
++      session->next);
+ 
 -    char *next_id_data = GNUNET_STRINGS_data_to_string_alloc (next_id, 
sizeof(*next_id));
++    char *next_id_data = GNUNET_STRINGS_data_to_string_alloc (next_id,
++                                                              
sizeof(*next_id));
+ 
+     if (next_id_data)
+     {
 -      GNUNET_CONFIGURATION_set_value_string (cfg, "session", "next_id", 
next_id_data);
++      GNUNET_CONFIGURATION_set_value_string (cfg, "session", "next_id",
++                                             next_id_data);
+ 
 -      GNUNET_free(next_id_data);
++      GNUNET_free (next_id_data);
+     }
+ 
 -    key_data = 
GNUNET_CRYPTO_public_key_to_string(get_member_session_public_key(session->next));
++    key_data = GNUNET_CRYPTO_public_key_to_string (
++      get_member_session_public_key (session->next));
+ 
+     if (key_data)
+     {
 -      GNUNET_CONFIGURATION_set_value_string (cfg, "session", "next_key", 
key_data);
++      GNUNET_CONFIGURATION_set_value_string (cfg, "session", "next_key",
++                                             key_data);
+ 
 -      GNUNET_free(key_data);
++      GNUNET_free (key_data);
+     }
+   }
+ 
 -  GNUNET_CONFIGURATION_set_value_number(cfg, "session", "start", 
session->start.abs_value_us);
++  GNUNET_CONFIGURATION_set_value_number (cfg, "session", "start",
++                                         session->start.abs_value_us);
+ 
 -  GNUNET_CONFIGURATION_set_value_number (cfg, "session", "closed", 
session->closed);
 -  GNUNET_CONFIGURATION_set_value_number (cfg, "session", "completed", 
session->completed);
++  GNUNET_CONFIGURATION_set_value_number (cfg, "session", "closed",
++                                         session->closed);
++  GNUNET_CONFIGURATION_set_value_number (cfg, "session", "completed",
++                                         session->completed);
+ 
+   GNUNET_CONFIGURATION_write (cfg, config_file);
+   GNUNET_CONFIGURATION_destroy (cfg);
+ 
 -  GNUNET_free(config_file);
++  GNUNET_free (config_file);
+ 
+   char *history_file;
+   GNUNET_asprintf (&history_file, "%s%s", directory, "history.map");
+ 
+   save_member_session_history (session, history_file);
 -  GNUNET_free(history_file);
++  GNUNET_free (history_file);
+ 
+   char *messages_file;
+   GNUNET_asprintf (&messages_file, "%s%s", directory, "messages.list");
+ 
 -  save_list_messages(&(session->messages), messages_file);
 -  GNUNET_free(messages_file);
++  save_list_messages (&(session->messages), messages_file);
++  GNUNET_free (messages_file);
+ }
diff --cc src/service/messenger/gnunet-service-messenger_member_session.h
index 000000000,fad1ab041..a039cc781
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_member_session.h
+++ b/src/service/messenger/gnunet-service-messenger_member_session.h
@@@ -1,0 -1,291 +1,297 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2021 GNUnet e.V.
++   Copyright (C) 2021, 2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_member_session.h
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_SERVICE_MESSENGER_MEMBER_SESSION_H
+ #define GNUNET_SERVICE_MESSENGER_MEMBER_SESSION_H
+ 
+ #include "platform.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ #include "gnunet_time_lib.h"
+ 
+ #include "gnunet-service-messenger_member.h"
+ 
+ #include "messenger_api_contact.h"
+ 
 -struct GNUNET_MESSENGER_MemberSession {
++struct GNUNET_MESSENGER_MemberSession
++{
+   struct GNUNET_MESSENGER_Member *member;
+ 
+   struct GNUNET_CRYPTO_PublicKey public_key;
+   struct GNUNET_HashCode context;
+ 
+   struct GNUNET_MESSENGER_Contact *contact;
+ 
+   struct GNUNET_CONTAINER_MultiHashMap *history;
+   struct GNUNET_MESSENGER_ListMessages messages;
+ 
 -  struct GNUNET_MESSENGER_MemberSession* prev;
 -  struct GNUNET_MESSENGER_MemberSession* next;
++  struct GNUNET_MESSENGER_MemberSession *prev;
++  struct GNUNET_MESSENGER_MemberSession *next;
+ 
+   struct GNUNET_TIME_Absolute start;
+ 
+   int closed;
+   int completed;
+ };
+ 
+ /**
+  * Creates and allocates a new member session of a <i>member</i> with a given
+  * public key.
+  *
+  * If the creation fails, NULL gets returned.
+  *
+  * @param[in,out] member Member
+  * @param[in] pubkey Public key of EGO
+  * @return New member session
+  */
+ struct GNUNET_MESSENGER_MemberSession*
+ create_member_session (struct GNUNET_MESSENGER_Member *member,
+                        const struct GNUNET_CRYPTO_PublicKey *pubkey);
+ 
+ /**
+  * Creates and allocates a new member session closing and replacing a given
+  * other <i>session</i> of the same member. The new session could have 
significant
+  * changes to the members public key or its member id depending on the used
+  * <i>message</i> to switch session. The new session will be linked to the old
+  * one.
+  *
+  * @param[in,out] session Old member session
+  * @param[in] message Message
+  * @param[in] hash Hash of message
+  * @return New member session
+  */
+ struct GNUNET_MESSENGER_MemberSession*
+ switch_member_session (struct GNUNET_MESSENGER_MemberSession *session,
+                        const struct GNUNET_MESSENGER_Message *message,
+                        const struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Destroys a member session and frees its memory fully.
+  *
+  * @param[in,out] session Member session
+  */
+ void
 -destroy_member_session(struct GNUNET_MESSENGER_MemberSession* session);
++destroy_member_session (struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Resets a given member <i>session</i> which re-opens a member
+  * session for new usage. Every connection to other sessions will be
+  * be dropped. The member sessions messages will be cleared but old
+  * history from uncompleted sessions however can be reused!
+  *
+  * @param[in,out] session Member session
+  * @param[in] hash Hash of initial message (JOIN message!)
+  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+  */
+ int
 -reset_member_session (struct GNUNET_MESSENGER_MemberSession* session,
++reset_member_session (struct GNUNET_MESSENGER_MemberSession *session,
+                       const struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Closes a given member <i>session</i> which opens the request
+  * for completion of the given member session.
+  *
+  * Closing a session may complete a session and can't be used without
+  * a reset! ( @see #reset_member_session() )
+  *
+  * @param[in,out] session Member session
+  */
+ void
 -close_member_session (struct GNUNET_MESSENGER_MemberSession* session);
++close_member_session (struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Returns if the given member <i>session</i> has been closed.
+  *
+  * @param[in] session Member session
+  * @return #GNUNET_YES or #GNUNET_NO
+  */
+ int
 -is_member_session_closed (const struct GNUNET_MESSENGER_MemberSession* 
session);
++is_member_session_closed (const struct GNUNET_MESSENGER_MemberSession 
*session);
+ 
+ /**
+  * Returns if the given member <i>session</i> has been completed.
+  *
+  * A completed member session can't verify any message as its own and
+  * it won't add any message to its history.
+  *
+  * @param[in] session Member session
+  * @return #GNUNET_YES or #GNUNET_NO
+  */
+ int
 -is_member_session_completed (const struct GNUNET_MESSENGER_MemberSession* 
session);
++is_member_session_completed (const struct
++                             GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Returns the timestamp of the member <i>session</i>'s start.
+  *
+  * @param[in] session Member session
+  * @return Absolute timestamp
+  */
+ struct GNUNET_TIME_Absolute
 -get_member_session_start (const struct GNUNET_MESSENGER_MemberSession* 
session);
++get_member_session_start (const struct GNUNET_MESSENGER_MemberSession 
*session);
+ 
+ /**
+  * Returns the key of the room a given member <i>session</i> belongs to.
+  *
+  * @param[in] session Member session
+  * @return Key of room
+  */
+ const struct GNUNET_HashCode*
 -get_member_session_key (const struct GNUNET_MESSENGER_MemberSession* session);
++get_member_session_key (const struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Returns the member id of a given member <i>session</i>.
+  *
+  * @param[in] session Member session
+  * @return Member id
+  */
+ const struct GNUNET_ShortHashCode*
 -get_member_session_id (const struct GNUNET_MESSENGER_MemberSession* session);
++get_member_session_id (const struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Returns the public key from an EGO of a given member <i>session</i>.
+  *
+  * @param[in] session Member session
+  * @return Public key of EGO
+  */
+ const struct GNUNET_CRYPTO_PublicKey*
 -get_member_session_public_key (const struct GNUNET_MESSENGER_MemberSession* 
session);
++get_member_session_public_key (const struct
++                               GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Returns the member context of a given member <i>session</i>.
+  *
+  * @param[in] session Member session
+  * @return Member context as hash
+  */
+ const struct GNUNET_HashCode*
 -get_member_session_context (const struct GNUNET_MESSENGER_MemberSession* 
session);
++get_member_session_context (const struct
++                            GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Returns the contact which is connected to a given member <i>session</i>.
+  *
+  * @param[in] session Member session
+  * @return Contact
+  */
+ struct GNUNET_MESSENGER_Contact*
 -get_member_session_contact (struct GNUNET_MESSENGER_MemberSession* session);
++get_member_session_contact (struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Verifies a given member <i>session</i> as sender of a selected 
<i>message</i> and
+  * its <i>hash</i>. The function returns #GNUNET_OK if the message session is 
verified
+  * as sender, otherwise #GNUNET_SYSERR.
+  *
+  * @see #is_member_session_completed() for verification.
+  *
+  * @param[in] session Member session
+  * @param[in] message Message
+  * @param[in] hash Hash of message
+  * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR
+  */
+ int
 -verify_member_session_as_sender (const struct GNUNET_MESSENGER_MemberSession 
*session,
++verify_member_session_as_sender (const struct
++                                 GNUNET_MESSENGER_MemberSession *session,
+                                  const struct GNUNET_MESSENGER_Message 
*message,
+                                  const struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Checks the history of a <i>session</i> for a specific message which is 
identified
+  * by its <i>hash</i> and if the <i>ownership</i> flag is set, if the message 
is
+  * owned by the sessions contact.
+  *
+  * @param[in] session Member session
+  * @param[in] hash Hash of message
+  * @param[in] ownership Ownership flag
+  * @return #GNUNET_YES if found, otherwise #GNUNET_NO
+  */
+ int
 -check_member_session_history (const struct GNUNET_MESSENGER_MemberSession 
*session,
++check_member_session_history (const struct
++                              GNUNET_MESSENGER_MemberSession *session,
+                               const struct GNUNET_HashCode *hash,
+                               int ownership);
+ 
+ /**
+  * Adds a given <i>message</i> to the history of a <i>session</i> using the 
messages
+  * <i>hash</i>. The ownership will be set automatically.
+  *
+  * @see #is_member_session_completed() for updating a history.
+  *
+  * @param[in,out] session Member session
+  * @param[in] message Message
+  * @param[in] hash Hash of message
+  */
+ void
+ update_member_session_history (struct GNUNET_MESSENGER_MemberSession *session,
+                                const struct GNUNET_MESSENGER_Message *message,
+                                const struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Removes a message from the history of a <i>session</i> using the messages
+  * <i>hash</i>.
+  *
+  * @param[in,out] session Member session
+  * @param[in] hash Hash of message
+  */
+ void
+ clear_member_session_history (struct GNUNET_MESSENGER_MemberSession *session,
+                               const struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Loads data from a <i>directory</i> into a new allocated and created member
+  * session of a <i>member</i> if the required information can be read from the
+  * content of the given directory.
+  *
+  * @param[out] member Member
+  * @param[in] directory Path to a directory
+  */
+ void
+ load_member_session (struct GNUNET_MESSENGER_Member *member,
+                      const char *directory);
+ 
+ /**
+  * Loads the connection from one <i>session</i> to another through the
+  * next attribute. Necessary information will be loaded from a configuration
+  * file inside of a given <i>directory</i>.
+  *
+  * @param[in,out] session Member session
+  * @param[in] directory Path to a directory
+  */
+ void
+ load_member_session_next (struct GNUNET_MESSENGER_MemberSession *session,
+                           const char *directory);
+ 
+ /**
+  * Saves data from a member <i>session</i> into a <i>directory</i> which can 
be
+  * load to restore the member session completely.
+  *
+  * @param[in] session Member session
+  * @param[in] directory Path to a directory
+  */
+ void
+ save_member_session (struct GNUNET_MESSENGER_MemberSession *session,
+                      const char *directory);
+ 
+ #endif //GNUNET_SERVICE_MESSENGER_MEMBER_SESSION_H
diff --cc src/service/messenger/gnunet-service-messenger_member_store.h
index 000000000,337ddcf78..0acb8ef9c
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_member_store.h
+++ b/src/service/messenger/gnunet-service-messenger_member_store.h
@@@ -1,0 -1,157 +1,159 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_member_store.h
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_SERVICE_MESSENGER_MEMBER_STORE_H
+ #define GNUNET_SERVICE_MESSENGER_MEMBER_STORE_H
+ 
+ #include "platform.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ #include "messenger_api_message.h"
+ 
+ struct GNUNET_MESSENGER_SrvRoom;
+ 
+ struct GNUNET_MESSENGER_Member;
+ struct GNUNET_MESSENGER_MemberSession;
+ 
+ struct GNUNET_MESSENGER_MemberStore
+ {
+   struct GNUNET_MESSENGER_SrvRoom *room;
+ 
+   struct GNUNET_CONTAINER_MultiShortmap *members;
+ };
+ 
+ typedef int (*GNUNET_MESSENGER_MemberIteratorCallback) (
 -    void *cls,
 -    const struct GNUNET_CRYPTO_PublicKey *public_key,
 -    struct GNUNET_MESSENGER_MemberSession *session);
++  void *cls,
++  const struct GNUNET_CRYPTO_PublicKey *public_key,
++  struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ /**
+  * Initializes a member <i>store</i> as fully empty connected to a 
<i>room</i>.
+  *
+  * @param[out] store Member store
+  * @param room Room
+  */
+ void
+ init_member_store (struct GNUNET_MESSENGER_MemberStore *store,
+                    struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Clears a member <i>store</i>, wipes its content and deallocates its memory.
+  *
+  * @param[in,out] store Member store
+  */
+ void
+ clear_member_store (struct GNUNET_MESSENGER_MemberStore *store);
+ 
+ /**
+  * Returns the used contact store of a given member <i>store</i>.
+  *
+  * @param[in,out] store Member store
+  * @return Contact store
+  */
+ struct GNUNET_MESSENGER_ContactStore*
+ get_member_contact_store (struct GNUNET_MESSENGER_MemberStore *store);
+ 
+ /**
+  * Returns the shared secret you need to access a room of the <i>store</i>.
+  *
+  * @param[in] store Member store
+  * @return Shared secret
+  */
+ const struct GNUNET_HashCode*
+ get_member_store_key (const struct GNUNET_MESSENGER_MemberStore *store);
+ 
+ /**
+  * Loads members from a directory into a member <i>store</i>.
+  *
+  * @param[out] store Member store
+  * @param[in] directory Path to a directory
+  */
+ void
+ load_member_store (struct GNUNET_MESSENGER_MemberStore *store,
+                    const char *directory);
+ 
+ /**
+  * Saves members from a member <i>store</i> into a directory.
+  *
+  * @param[in] store Member store
+  * @param[in] directory Path to a directory
+  */
+ void
+ save_member_store (struct GNUNET_MESSENGER_MemberStore *store,
+                    const char *directory);
+ 
+ /**
+  * Returns the member in a <i>store</i> identified by a given <i>id</i>. If 
the <i>store</i>
+  * does not contain a member with the given <i>id</i>, NULL gets returned.
+  *
+  * @param[in] store Member store
+  * @param[in] id Member id
+  * @return Member or NULL
+  */
+ struct GNUNET_MESSENGER_Member*
+ get_store_member (const struct GNUNET_MESSENGER_MemberStore *store,
+                   const struct GNUNET_ShortHashCode *id);
+ 
+ /**
+  * Returns the member of a <i>store</i> using a sender id of a given 
<i>message</i>.
 - * If the member does not provide a matching session, NULL gets returned.
++ *
++ * If the message is a peer message or the member does not provide a matching 
session,
++ * NULL gets returned.
+  *
+  * @param[in,out] store Member store
+  * @param[in] message Message
+  * @return Member or NULL
+  */
+ struct GNUNET_MESSENGER_Member*
+ get_store_member_of (struct GNUNET_MESSENGER_MemberStore *store,
+                      const struct GNUNET_MESSENGER_Message *message);
+ 
+ /**
+  * Adds a member to a <i>store</i> under a specific <i>id</i> and returns it 
on success.
+  *
+  * @param[in,out] store Member store
+  * @param[in] id Member id
+  * @return Member or NULL
+  */
+ struct GNUNET_MESSENGER_Member*
+ add_store_member (struct GNUNET_MESSENGER_MemberStore *store,
+                   const struct GNUNET_ShortHashCode *id);
+ 
+ /**
+  * Iterate through all member sessions currently connected to the members of 
the given
+  * member <i>store</i> and call the provided iterator callback with a 
selected closure.
+  * The function will return the amount of members it iterated through.
+  *
+  * @param[in,out] store Member store
+  * @param[in] it Iterator callback
+  * @param[in,out] cls Closure
+  * @return Amount of members iterated through
+  */
+ int
+ iterate_store_members (struct GNUNET_MESSENGER_MemberStore *store,
+                        GNUNET_MESSENGER_MemberIteratorCallback it,
 -                       void* cls);
++                       void *cls);
+ 
+ #endif //GNUNET_SERVICE_MESSENGER_MEMBER_STORE_H
diff --cc src/service/messenger/gnunet-service-messenger_message_recv.c
index 000000000,d660d0115..9c4a69acd
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_message_recv.c
+++ b/src/service/messenger/gnunet-service-messenger_message_recv.c
@@@ -1,0 -1,186 +1,229 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2022 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_message_recv.c
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "gnunet-service-messenger_message_recv.h"
+ 
++#include "gnunet-service-messenger_message_kind.h"
+ #include "gnunet-service-messenger_operation.h"
+ 
+ static void
+ forward_about_members (struct GNUNET_MESSENGER_SrvRoom *room,
+                        struct GNUNET_MESSENGER_SrvTunnel *tunnel,
+                        struct GNUNET_MESSENGER_MemberSession *session,
+                        struct GNUNET_CONTAINER_MultiHashMap *map)
+ {
+   if (session->prev)
+     forward_about_members (room, tunnel, session->prev, map);
+ 
 -  struct GNUNET_MESSENGER_MessageStore *message_store = 
get_srv_room_message_store(room);
++  struct GNUNET_MESSENGER_MessageStore *message_store =
++    get_srv_room_message_store (room);
+   struct GNUNET_MESSENGER_ListMessage *element;
+ 
+   for (element = session->messages.head; element; element = element->next)
+   {
 -    if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(map, 
&(element->hash)))
++    if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (map,
++                                                              
&(element->hash)))
+       continue;
+ 
 -    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(map, &(element->hash), 
NULL,
 -                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
 -      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Forwarding of session message 
could be duplicated!\n");
++    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &(element->hash),
++                                                        NULL,
++                                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
++      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                  "Forwarding of session message could be duplicated!\n");
+ 
 -    const struct GNUNET_MESSENGER_Message *message = 
get_store_message(message_store, &(element->hash));
++    const struct GNUNET_MESSENGER_Message *message = get_store_message (
++      message_store, &(element->hash));
+ 
+     if (message)
 -      forward_tunnel_message(tunnel, message, &(element->hash));
++      forward_tunnel_message (tunnel, message, &(element->hash));
+   }
+ }
+ 
++
+ static int
+ iterate_forward_members (void *cls,
+                          const struct GNUNET_CRYPTO_PublicKey *public_key,
+                          struct GNUNET_MESSENGER_MemberSession *session)
+ {
+   struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
+ 
 -  if (GNUNET_YES == is_member_session_completed(session))
++  if (GNUNET_YES == is_member_session_completed (session))
+     return GNUNET_YES;
+ 
 -  struct GNUNET_CONTAINER_MultiHashMap *map = 
GNUNET_CONTAINER_multihashmap_create(4, GNUNET_NO);
++  struct GNUNET_CONTAINER_MultiHashMap *map =
++    GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
+ 
+   forward_about_members (tunnel->room, tunnel, session, map);
+ 
 -  GNUNET_CONTAINER_multihashmap_destroy(map);
++  GNUNET_CONTAINER_multihashmap_destroy (map);
+   return GNUNET_YES;
+ }
+ 
++
+ int
+ recv_message_info (struct GNUNET_MESSENGER_SrvRoom *room,
+                    struct GNUNET_MESSENGER_SrvTunnel *tunnel,
+                    const struct GNUNET_MESSENGER_Message *message,
+                    const struct GNUNET_HashCode *hash)
+ {
 -  const uint32_t version = get_tunnel_messenger_version(tunnel);
++  const uint32_t version = get_tunnel_messenger_version (tunnel);
+ 
 -  if (GNUNET_OK != update_tunnel_messenger_version(tunnel, 
message->body.info.messenger_version))
++  if (GNUNET_OK != update_tunnel_messenger_version (tunnel,
++                                                    message->body.info.
++                                                    messenger_version))
+   {
 -    disconnect_tunnel(tunnel);
++    disconnect_tunnel (tunnel);
+     return GNUNET_NO;
+   }
+ 
 -  if (version == get_tunnel_messenger_version(tunnel))
++  if (version == get_tunnel_messenger_version (tunnel))
+     return GNUNET_NO;
+ 
+   if (room->host)
 -  {
 -    const struct GNUNET_MESSENGER_Ego *ego = get_srv_handle_ego(room->host);
 -
 -    send_tunnel_message (tunnel, room->host, create_message_info(ego));
 -  }
++    send_tunnel_message (tunnel, room->host, create_message_info (
++                           room->service));
+ 
+   struct GNUNET_PeerIdentity peer;
 -  get_tunnel_peer_identity(tunnel, &peer);
++  get_tunnel_peer_identity (tunnel, &peer);
+ 
 -  if (GNUNET_YES != contains_list_tunnels(&(room->basement), &peer))
++  if (GNUNET_YES != contains_list_tunnels (&(room->basement), &peer))
+   {
 -    struct GNUNET_MESSENGER_MemberStore *member_store = 
get_srv_room_member_store(room);
++    struct GNUNET_MESSENGER_MessageStore *message_store =
++      get_srv_room_message_store (room);
++
++    struct GNUNET_MESSENGER_ListTunnel *element;
++    for (element = room->basement.head; element; element = element->next)
++    {
++      if (! element->hash)
++        continue;
++
++      const struct GNUNET_MESSENGER_Message *message = get_store_message (
++        message_store, element->hash);
+ 
 -    iterate_store_members(member_store, iterate_forward_members, tunnel);
++      if (message)
++        forward_tunnel_message (tunnel, message, element->hash);
++    }
+   }
+ 
 -  check_srv_room_peer_status(room, tunnel);
++  if (GNUNET_YES != contains_list_tunnels (&(room->basement), &peer))
++  {
++    struct GNUNET_MESSENGER_MemberStore *member_store =
++      get_srv_room_member_store (room);
++
++    iterate_store_members (member_store, iterate_forward_members, tunnel);
++  }
+ 
++  check_srv_room_peer_status (room, tunnel);
+   return GNUNET_NO;
+ }
+ 
++
+ int
+ recv_message_peer (struct GNUNET_MESSENGER_SrvRoom *room,
+                    struct GNUNET_MESSENGER_SrvTunnel *tunnel,
+                    const struct GNUNET_MESSENGER_Message *message,
+                    const struct GNUNET_HashCode *hash)
+ {
+   struct GNUNET_PeerIdentity peer;
+   GNUNET_PEER_resolve (tunnel->peer, &peer);
+ 
 -  if (0 == GNUNET_memcmp(&peer, &(message->body.peer.peer)))
++  if (0 == GNUNET_memcmp (&peer, &(message->body.peer.peer)))
+   {
 -    if (!tunnel->peer_message)
 -      tunnel->peer_message = GNUNET_new(struct GNUNET_HashCode);
++    if (! tunnel->peer_message)
++      tunnel->peer_message = GNUNET_new (struct GNUNET_HashCode);
+ 
 -    GNUNET_memcpy(tunnel->peer_message, &hash, sizeof(hash));
++    GNUNET_memcpy (tunnel->peer_message, &hash, sizeof(hash));
+   }
+ 
++  update_to_list_tunnels (&(room->basement), &(message->body.peer.peer), 
hash);
+   return GNUNET_YES;
+ }
+ 
++
+ static void
+ callback_found_message (void *cls,
+                         struct GNUNET_MESSENGER_SrvRoom *room,
+                         const struct GNUNET_MESSENGER_Message *message,
+                         const struct GNUNET_HashCode *hash)
+ {
 -  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
++  struct GNUNET_MESSENGER_SrvTunnel *tunnel = tunnel;
+ 
 -  if (!message)
++  if (! message)
+   {
 -    struct GNUNET_MESSENGER_OperationStore *operation_store = 
get_srv_room_operation_store(room);
 -
 -    use_store_operation(
 -        operation_store,
 -        hash,
 -        GNUNET_MESSENGER_OP_REQUEST,
 -        GNUNET_MESSENGER_REQUEST_DELAY
 -    );
++    struct GNUNET_MESSENGER_OperationStore *operation_store =
++      get_srv_room_operation_store (room);
++
++    use_store_operation (
++      operation_store,
++      hash,
++      GNUNET_MESSENGER_OP_REQUEST,
++      GNUNET_MESSENGER_REQUEST_DELAY
++      );
+   }
+   else
+     forward_tunnel_message (tunnel, message, hash);
+ }
+ 
++
+ /*
+  * Function returns GNUNET_NO to drop forwarding the request.
+  * It will only be forwarded if it can't be answered!
+  */
+ int
+ recv_message_request (struct GNUNET_MESSENGER_SrvRoom *room,
+                       struct GNUNET_MESSENGER_SrvTunnel *tunnel,
+                       const struct GNUNET_MESSENGER_Message *message,
+                       const struct GNUNET_HashCode *hash)
+ {
 -  struct GNUNET_MESSENGER_MemberStore *member_store = 
get_srv_room_member_store(room);
 -  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, 
message);
++  struct GNUNET_MESSENGER_MemberStore *member_store =
++    get_srv_room_member_store (room);
++  struct GNUNET_MESSENGER_Member *member = get_store_member_of (member_store,
++                                                                message);
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Request for message (%s)\n", 
GNUNET_h2s (hash));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request for message (%s)\n",
++              GNUNET_h2s (hash));
+ 
 -  if (!member)
++  if (! member)
+     return GNUNET_NO;
+ 
 -  struct GNUNET_MESSENGER_MemberSession *session = 
get_member_session_of(member, message, hash);
++  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of (
++    member, message, hash);
+ 
 -  if ((!session) || (GNUNET_YES != check_member_session_history(session, 
hash, GNUNET_NO)))
++  if ((! session) || (GNUNET_YES != check_member_session_history (session,
++                                                                  &(message->
++                                                                    
body.request
++                                                                    .hash),
++                                                                  GNUNET_NO)))
+     return GNUNET_NO;
+ 
 -  if (GNUNET_NO == request_srv_room_message(room, 
&(message->body.request.hash), session, callback_found_message, tunnel))
++  if (GNUNET_NO == request_srv_room_message (room,
++                                             &(message->body.request.hash),
++                                             session, callback_found_message,
++                                             tunnel))
+     return GNUNET_YES;
+ 
+   return GNUNET_NO;
+ }
diff --cc src/service/messenger/gnunet-service-messenger_message_send.c
index 000000000,09039758b..a616355eb
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_message_send.c
+++ b/src/service/messenger/gnunet-service-messenger_message_send.c
@@@ -1,0 -1,77 +1,197 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2022 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_message_send.c
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "gnunet-service-messenger_message_send.h"
+ 
++#include "gnunet-service-messenger_handle.h"
+ #include "gnunet-service-messenger_member.h"
+ #include "gnunet-service-messenger_member_session.h"
+ #include "gnunet-service-messenger_operation.h"
++#include "gnunet-service-messenger_room.h"
++
++struct GNUNET_MESSENGER_MemberNotify
++{
++  struct GNUNET_MESSENGER_SrvRoom *room;
++  struct GNUNET_MESSENGER_SrvHandle *handle;
++  struct GNUNET_MESSENGER_MemberSession *session;
++};
++
++static void
++notify_about_members (struct GNUNET_MESSENGER_MemberNotify *notify,
++                      struct GNUNET_MESSENGER_MemberSession *session,
++                      struct GNUNET_CONTAINER_MultiHashMap *map,
++                      int check_permission)
++{
++  if (session->prev)
++    notify_about_members (notify, session->prev, map, GNUNET_YES);
++
++  struct GNUNET_MESSENGER_MessageStore *message_store =
++    get_srv_room_message_store (notify->room);
++  struct GNUNET_MESSENGER_ListMessage *element;
++
++  for (element = session->messages.head; element; element = element->next)
++  {
++    if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (map,
++                                                              
&(element->hash)))
++      continue;
++
++    if ((GNUNET_YES == check_permission) &&
++        (GNUNET_YES != check_member_session_history (notify->session,
++                                                     &(element->hash),
++                                                     GNUNET_NO)))
++      continue;
++
++    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &(element->hash),
++                                                        NULL,
++                                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
++      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                  "Notification of session message could be duplicated!\n");
++
++    const struct GNUNET_MESSENGER_Message *message = get_store_message (
++      message_store, &(element->hash));
++
++    if ((! message) || (GNUNET_YES == is_peer_message (message)))
++      continue;
++
++    struct GNUNET_MESSENGER_SenderSession sender;
++    sender.member = session;
++
++    notify_srv_handle_message (notify->handle, notify->room, &sender, message,
++                               &(element->hash));
++  }
++}
++
++
++static int
++iterate_notify_about_members (void *cls,
++                              const struct
++                              GNUNET_CRYPTO_PublicKey *public_key,
++                              struct GNUNET_MESSENGER_MemberSession *session)
++{
++  struct GNUNET_MESSENGER_MemberNotify *notify = cls;
++
++  if ((notify->session == session) || (GNUNET_YES ==
++                                       is_member_session_completed (session)))
++    return GNUNET_YES;
++
++  struct GNUNET_CONTAINER_MultiHashMap *map =
++    GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
++
++  notify_about_members (notify, session, map, GNUNET_NO);
++
++  GNUNET_CONTAINER_multihashmap_destroy (map);
++  return GNUNET_YES;
++}
++
+ 
+ void
+ send_message_join (struct GNUNET_MESSENGER_SrvRoom *room,
+                    struct GNUNET_MESSENGER_SrvHandle *handle,
+                    const struct GNUNET_MESSENGER_Message *message,
+                    const struct GNUNET_HashCode *hash)
+ {
 -  check_srv_room_peer_status(room, NULL);
++  set_srv_handle_key (handle, &(message->body.join.key));
++
++  struct GNUNET_MESSENGER_MemberStore *member_store =
++    get_srv_room_member_store (room);
++  struct GNUNET_MESSENGER_Member *member = add_store_member (member_store,
++                                                             
&(message->header.
++                                                               sender_id));
++
++  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of (
++    member, message, hash);
++
++  if (! session)
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "A valid session is required to join a room!\n");
++    goto skip_member_notification;
++  }
++
++  struct GNUNET_MESSENGER_MemberNotify notify;
++
++  notify.room = room;
++  notify.handle = handle;
++  notify.session = session;
++
++  iterate_store_members (get_srv_room_member_store (room),
++                         iterate_notify_about_members, &notify);
++
++skip_member_notification:
++  check_srv_room_peer_status (room, NULL);
+ }
+ 
++
++void
++send_message_key (struct GNUNET_MESSENGER_SrvRoom *room,
++                  struct GNUNET_MESSENGER_SrvHandle *handle,
++                  const struct GNUNET_MESSENGER_Message *message,
++                  const struct GNUNET_HashCode *hash)
++{
++  set_srv_handle_key (handle, &(message->body.key.key));
++}
++
++
+ void
+ send_message_peer (struct GNUNET_MESSENGER_SrvRoom *room,
+                    struct GNUNET_MESSENGER_SrvHandle *handle,
+                    const struct GNUNET_MESSENGER_Message *message,
+                    const struct GNUNET_HashCode *hash)
+ {
 -  if (!room->peer_message)
 -    room->peer_message = GNUNET_new(struct GNUNET_HashCode);
++  if (! room->peer_message)
++    room->peer_message = GNUNET_new (struct GNUNET_HashCode);
+ 
 -  GNUNET_memcpy(room->peer_message, hash, sizeof(struct GNUNET_HashCode));
++  GNUNET_memcpy (room->peer_message, hash, sizeof(struct GNUNET_HashCode));
+ }
+ 
++
+ void
+ send_message_id (struct GNUNET_MESSENGER_SrvRoom *room,
+                  struct GNUNET_MESSENGER_SrvHandle *handle,
+                  const struct GNUNET_MESSENGER_Message *message,
+                  const struct GNUNET_HashCode *hash)
+ {
 -  change_srv_handle_member_id (handle, get_srv_room_key(room), 
&(message->body.id.id));
++  change_srv_handle_member_id (handle, get_srv_room_key (room),
++                               &(message->body.id.id));
+ }
+ 
++
+ void
+ send_message_request (struct GNUNET_MESSENGER_SrvRoom *room,
+                       struct GNUNET_MESSENGER_SrvHandle *handle,
+                       const struct GNUNET_MESSENGER_Message *message,
+                       const struct GNUNET_HashCode *hash)
+ {
 -  struct GNUNET_MESSENGER_OperationStore *operation_store = 
get_srv_room_operation_store(room);
 -
 -  use_store_operation(
 -      operation_store,
 -      &(message->body.request.hash),
 -      GNUNET_MESSENGER_OP_REQUEST,
 -      GNUNET_MESSENGER_REQUEST_DELAY
 -  );
++  struct GNUNET_MESSENGER_OperationStore *operation_store =
++    get_srv_room_operation_store (room);
++
++  use_store_operation (
++    operation_store,
++    &(message->body.request.hash),
++    GNUNET_MESSENGER_OP_REQUEST,
++    GNUNET_MESSENGER_REQUEST_DELAY
++    );
+ }
diff --cc src/service/messenger/gnunet-service-messenger_room.c
index 000000000,f2f841c20..f08bfb402
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_room.c
+++ b/src/service/messenger/gnunet-service-messenger_room.c
@@@ -1,0 -1,1274 +1,1390 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2022 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_room.c
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "gnunet-service-messenger_room.h"
+ 
+ #include "gnunet-service-messenger_member.h"
 -#include "gnunet-service-messenger_member_session.h"
++#include "gnunet-service-messenger_sender_session.h"
+ 
+ #include "gnunet-service-messenger_message_kind.h"
+ #include "gnunet-service-messenger_message_handle.h"
+ #include "gnunet-service-messenger_message_send.h"
+ 
+ #include "gnunet-service-messenger_operation.h"
+ 
+ #include "gnunet-service-messenger.h"
+ #include "gnunet-service-messenger_service.h"
+ #include "gnunet-service-messenger_tunnel.h"
++
++#include "messenger_api_message.h"
+ #include "messenger_api_util.h"
+ 
+ static void
+ idle_request_room_messages (void *cls);
+ 
+ struct GNUNET_MESSENGER_SrvRoom*
+ create_srv_room (struct GNUNET_MESSENGER_SrvHandle *handle,
+                  const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (key));
++  GNUNET_assert ((handle) && (key));
+ 
 -  struct GNUNET_MESSENGER_SrvRoom *room = GNUNET_new(struct 
GNUNET_MESSENGER_SrvRoom);
++  struct GNUNET_MESSENGER_SrvRoom *room = GNUNET_new (struct
++                                                      
GNUNET_MESSENGER_SrvRoom);
+ 
+   room->service = handle->service;
+   room->host = handle;
+   room->port = NULL;
+ 
 -  GNUNET_memcpy(&(room->key), key, sizeof(struct GNUNET_HashCode));
++  GNUNET_memcpy (&(room->key), key, sizeof(struct GNUNET_HashCode));
+ 
+   room->tunnels = GNUNET_CONTAINER_multipeermap_create (8, GNUNET_NO);
+ 
 -  init_member_store(get_srv_room_member_store(room), room);
 -  init_message_store (get_srv_room_message_store(room));
 -  init_operation_store(get_srv_room_operation_store(room), room);
++  init_peer_store (get_srv_room_peer_store (room));
++  init_member_store (get_srv_room_member_store (room), room);
++  init_message_store (get_srv_room_message_store (room));
++  init_operation_store (get_srv_room_operation_store (room), room);
+ 
+   init_list_tunnels (&(room->basement));
 -  init_message_state(&(room->state));
++  init_message_state (&(room->state));
+ 
+   room->peer_message = NULL;
+ 
+   init_list_messages (&(room->handling));
+   room->idle = NULL;
+ 
+   if (room->service->dir)
+     load_srv_room (room);
+ 
 -  room->idle = GNUNET_SCHEDULER_add_with_priority 
(GNUNET_SCHEDULER_PRIORITY_IDLE, idle_request_room_messages, room);
++  room->idle = GNUNET_SCHEDULER_add_with_priority (
++    GNUNET_SCHEDULER_PRIORITY_IDLE, idle_request_room_messages, room);
+ 
+   return room;
+ }
+ 
++
+ static int
+ iterate_destroy_tunnels (void *cls,
+                          const struct GNUNET_PeerIdentity *key,
+                          void *value)
+ {
+   struct GNUNET_MESSENGER_SrvTunnel *tunnel = value;
+   destroy_tunnel (tunnel);
+   return GNUNET_YES;
+ }
+ 
++
+ static void
+ handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ void
+ destroy_srv_room (struct GNUNET_MESSENGER_SrvRoom *room,
+                   int deletion)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   if (room->idle)
+   {
+     GNUNET_SCHEDULER_cancel (room->idle);
+     room->idle = NULL;
+   }
+ 
+   if (room->port)
+     GNUNET_CADET_close_port (room->port);
+ 
 -  GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, 
iterate_destroy_tunnels, NULL);
++  GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, 
iterate_destroy_tunnels,
++                                         NULL);
+   handle_room_messages (room);
+ 
 -  if (!(room->service->dir))
++  if (! (room->service->dir))
+     goto skip_saving;
+ 
+   if (GNUNET_YES == deletion)
+     remove_srv_room (room);
+   else
+     save_srv_room (room);
+ 
+ skip_saving:
 -  clear_member_store (get_srv_room_member_store(room));
 -  clear_message_store (get_srv_room_message_store(room));
 -  clear_operation_store(get_srv_room_operation_store(room));
++  clear_peer_store (get_srv_room_peer_store (room));
++  clear_member_store (get_srv_room_member_store (room));
++  clear_message_store (get_srv_room_message_store (room));
++  clear_operation_store (get_srv_room_operation_store (room));
+ 
+   GNUNET_CONTAINER_multipeermap_destroy (room->tunnels);
+   clear_list_tunnels (&(room->basement));
 -  clear_message_state(&(room->state));
++  clear_message_state (&(room->state));
+ 
+   if (room->peer_message)
 -    GNUNET_free(room->peer_message);
++    GNUNET_free (room->peer_message);
++
++  GNUNET_free (room);
++}
+ 
 -  GNUNET_free(room);
++
++struct GNUNET_MESSENGER_PeerStore*
++get_srv_room_peer_store (struct GNUNET_MESSENGER_SrvRoom *room)
++{
++  GNUNET_assert (room);
++
++  return &(room->peer_store);
+ }
+ 
++
+ struct GNUNET_MESSENGER_MemberStore*
+ get_srv_room_member_store (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   return &(room->member_store);
+ }
+ 
++
+ struct GNUNET_MESSENGER_MessageStore*
+ get_srv_room_message_store (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   return &(room->message_store);
+ }
+ 
++
+ struct GNUNET_MESSENGER_OperationStore*
+ get_srv_room_operation_store (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   return &(room->operation_store);
+ }
+ 
++
+ static int
+ send_room_info (struct GNUNET_MESSENGER_SrvRoom *room,
+                 struct GNUNET_MESSENGER_SrvHandle *handle,
+                 struct GNUNET_MESSENGER_SrvTunnel *tunnel)
+ {
 -  if ((!handle) || (!is_tunnel_connected (tunnel)))
++  if ((! handle) || (! is_tunnel_connected (tunnel)))
+     return GNUNET_NO;
+ 
 -  return send_tunnel_message (tunnel, handle, create_message_info 
(get_srv_handle_ego (handle)));
++  return send_tunnel_message (tunnel, handle, create_message_info (
++                                room->service));
+ }
+ 
++
+ static void*
+ callback_room_connect (void *cls,
+                        struct GNUNET_CADET_Channel *channel,
+                        const struct GNUNET_PeerIdentity *source)
+ {
+   struct GNUNET_MESSENGER_SrvRoom *room = cls;
+ 
+   struct GNUNET_MESSENGER_SrvTunnel *tunnel = create_tunnel (room, source);
+ 
+   if ((tunnel) &&
 -      (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (room->tunnels, source, 
tunnel,
++      (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (room->tunnels, source,
++                                                       tunnel,
+                                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)))
+   {
+     destroy_tunnel (tunnel);
+     tunnel = NULL;
+   }
+ 
 -  if (!tunnel)
++  if (! tunnel)
+   {
+     delayed_disconnect_channel (channel);
+     return NULL;
+   }
+ 
 -  bind_tunnel(tunnel, channel);
++  bind_tunnel (tunnel, channel);
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "New tunnel in room (%s) established to 
peer: %s\n",
 -             GNUNET_h2s(get_srv_room_key(room)), GNUNET_i2s (source));
++  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
++              "New tunnel in room (%s) established to peer: %s\n",
++              GNUNET_h2s (get_srv_room_key (room)), GNUNET_i2s (source));
+ 
+   if (GNUNET_YES == send_room_info (room, room->host, tunnel))
+     return tunnel;
+ 
+   disconnect_tunnel (tunnel);
+ 
 -  if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (room->tunnels, 
source, tunnel))
++  if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (room->tunnels, 
source,
++                                                          tunnel))
+     destroy_tunnel (tunnel);
+ 
+   return NULL;
+ }
+ 
++
+ static int
+ join_room (struct GNUNET_MESSENGER_SrvRoom *room,
+            struct GNUNET_MESSENGER_SrvHandle *handle,
+            struct GNUNET_MESSENGER_Member *member)
+ {
 -  GNUNET_assert((room) && (handle) && (member));
 -
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Joining room: %s (%s)\n", GNUNET_h2s 
(get_srv_room_key (room)),
 -             GNUNET_sh2s (get_member_id(member)));
++  GNUNET_assert ((room) && (handle) && (member));
+ 
 -  const struct GNUNET_ShortHashCode *member_id = get_member_id(member);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Joining room: %s (%s)\n", GNUNET_h2s (
++                get_srv_room_key (room)),
++              GNUNET_sh2s (get_member_id (member)));
+ 
 -  if (GNUNET_OK != change_srv_handle_member_id (handle, 
get_srv_room_key(room), member_id))
 -    return GNUNET_NO;
 -
 -  struct GNUNET_MESSENGER_Message *message = create_message_join 
(get_srv_handle_ego (handle));
 -
 -  if (!message)
 -  {
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Your join message could not be 
created!\n");
++  const struct GNUNET_ShortHashCode *member_id = get_member_id (member);
+ 
++  if (GNUNET_OK != change_srv_handle_member_id (handle, get_srv_room_key 
(room),
++                                                member_id))
+     return GNUNET_NO;
 -  }
 -
 -  GNUNET_memcpy(&(message->header.sender_id), member_id, sizeof(*member_id));
 -  return send_srv_room_message (room, handle, message);
 -}
 -
 -struct GNUNET_MESSENGER_MemberNotify
 -{
 -  struct GNUNET_MESSENGER_SrvRoom *room;
 -  struct GNUNET_MESSENGER_SrvHandle *handle;
 -  struct GNUNET_MESSENGER_MemberSession *session;
 -};
 -
 -static void
 -notify_about_members (struct GNUNET_MESSENGER_MemberNotify *notify,
 -                      struct GNUNET_MESSENGER_MemberSession *session,
 -                      struct GNUNET_CONTAINER_MultiHashMap *map,
 -                      int check_permission)
 -{
 -  if (session->prev)
 -    notify_about_members (notify, session->prev, map, GNUNET_YES);
 -
 -  struct GNUNET_MESSENGER_MessageStore *message_store = 
get_srv_room_message_store(notify->room);
 -  struct GNUNET_MESSENGER_ListMessage *element;
 -
 -  for (element = session->messages.head; element; element = element->next)
 -  {
 -    if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(map, 
&(element->hash)))
 -      continue;
 -
 -    if ((GNUNET_YES == check_permission) &&
 -        (GNUNET_YES != check_member_session_history(notify->session, 
&(element->hash), GNUNET_NO)))
 -      continue;
+ 
 -    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(map, &(element->hash), 
NULL,
 -                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
 -      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notification of session message 
could be duplicated!\n");
 -
 -    const struct GNUNET_MESSENGER_Message *message = 
get_store_message(message_store, &(element->hash));
 -
 -    if (message)
 -      notify_srv_handle_message (notify->handle, notify->room, session, 
message, &(element->hash));
 -  }
 -}
 -
 -static int
 -iterate_notify_about_members (void *cls,
 -                              const struct GNUNET_CRYPTO_PublicKey 
*public_key,
 -                              struct GNUNET_MESSENGER_MemberSession *session)
 -{
 -  struct GNUNET_MESSENGER_MemberNotify *notify = cls;
 -
 -  if ((notify->session == session) || (GNUNET_YES == 
is_member_session_completed(session)))
 -    return GNUNET_YES;
 -
 -  struct GNUNET_CONTAINER_MultiHashMap *map = 
GNUNET_CONTAINER_multihashmap_create(4, GNUNET_NO);
 -
 -  notify_about_members (notify, session, map, GNUNET_NO);
 -
 -  GNUNET_CONTAINER_multihashmap_destroy(map);
++  notify_srv_handle_member_id (handle, room, member_id, GNUNET_YES);
+   return GNUNET_YES;
+ }
+ 
++
+ static int
+ join_room_locally (struct GNUNET_MESSENGER_SrvRoom *room,
+                    struct GNUNET_MESSENGER_SrvHandle *handle)
+ {
 -  const struct GNUNET_ShortHashCode *member_id = get_srv_handle_member_id 
(handle, get_srv_room_key(room));
++  const struct GNUNET_ShortHashCode *member_id = get_srv_handle_member_id (
++    handle, get_srv_room_key (room));
+ 
 -  struct GNUNET_MESSENGER_MemberStore *member_store = 
get_srv_room_member_store(room);
 -  struct GNUNET_MESSENGER_Member *member = add_store_member(member_store, 
member_id);
++  struct GNUNET_MESSENGER_MemberStore *member_store =
++    get_srv_room_member_store (room);
++  struct GNUNET_MESSENGER_Member *member = add_store_member (member_store,
++                                                             member_id);
+ 
+   if (GNUNET_NO == join_room (room, handle, member))
+     return GNUNET_NO;
+ 
 -  const struct GNUNET_MESSENGER_Ego *ego = get_srv_handle_ego(handle);
 -  struct GNUNET_MESSENGER_MemberSession *session = get_member_session 
(member, &(ego->pub));
 -
 -  if (!session)
 -  {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "A valid session is required to 
join a room!\n");
 -    return GNUNET_NO;
 -  }
 -
 -  struct GNUNET_MESSENGER_MemberNotify notify;
 -
 -  notify.room = room;
 -  notify.handle = handle;
 -  notify.session = session;
 -
 -  iterate_store_members(get_srv_room_member_store(room), 
iterate_notify_about_members, &notify);
 -
+   return GNUNET_YES;
+ }
+ 
++
+ extern int
+ check_tunnel_message (void *cls,
+                       const struct GNUNET_MessageHeader *header);
+ 
+ extern void
+ handle_tunnel_message (void *cls,
+                        const struct GNUNET_MessageHeader *header);
+ 
+ extern void
+ callback_tunnel_disconnect (void *cls,
+                             const struct GNUNET_CADET_Channel *channel);
+ 
+ int
+ open_srv_room (struct GNUNET_MESSENGER_SrvRoom *room,
+                struct GNUNET_MESSENGER_SrvHandle *handle)
+ {
 -  GNUNET_assert((room) && (handle));
++  GNUNET_assert ((room) && (handle));
+ 
+   if (room->port)
+     return join_room_locally (room, handle);
+ 
+   struct GNUNET_CADET_Handle *cadet = get_srv_room_cadet (room);
+   const struct GNUNET_HashCode *key = get_srv_room_key (room);
+ 
 -  struct GNUNET_MQ_MessageHandler handlers[] = { 
GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI,
 -                                                                       struct 
GNUNET_MessageHeader, NULL),
 -                                                 GNUNET_MQ_handler_end() };
++  struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size (
++                                                   tunnel_message,
++                                                   
GNUNET_MESSAGE_TYPE_CADET_CLI,
++                                                   struct
++                                                   GNUNET_MessageHeader, 
NULL),
++                                                 GNUNET_MQ_handler_end () };
+ 
+   struct GNUNET_HashCode port;
 -  convert_messenger_key_to_port(key, &port);
 -  room->port = GNUNET_CADET_open_port (cadet, &port, callback_room_connect, 
room, NULL, callback_tunnel_disconnect,
++  convert_messenger_key_to_port (key, &port);
++  room->port = GNUNET_CADET_open_port (cadet, &port, callback_room_connect,
++                                       room, NULL, callback_tunnel_disconnect,
+                                        handlers);
+ 
+   if (room->port)
 -    GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Port of room (%s) was opened!\n",
 -               GNUNET_h2s(get_srv_room_key(room)));
++    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Port of room (%s) was opened!\n",
++                GNUNET_h2s (get_srv_room_key (room)));
+   else
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Port of room (%s) could not be 
opened!\n",
 -               GNUNET_h2s(get_srv_room_key(room)));
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Port of room (%s) could not be opened!\n",
++                GNUNET_h2s (get_srv_room_key (room)));
+ 
 -  const struct GNUNET_ShortHashCode *member_id = get_srv_handle_member_id 
(handle, get_srv_room_key(room));
++  const struct GNUNET_ShortHashCode *member_id = get_srv_handle_member_id (
++    handle, get_srv_room_key (room));
+ 
 -  struct GNUNET_MESSENGER_MemberStore *member_store = 
get_srv_room_member_store(room);
 -  struct GNUNET_MESSENGER_Member *member = add_store_member(member_store, 
member_id);
++  struct GNUNET_MESSENGER_MemberStore *member_store =
++    get_srv_room_member_store (room);
++  struct GNUNET_MESSENGER_Member *member = add_store_member (member_store,
++                                                             member_id);
+ 
+   if ((GNUNET_NO == join_room (room, handle, member)) && (room->port))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not join the room, 
therefore it keeps closed!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "You could not join the room, therefore it keeps closed!\n");
+ 
+     GNUNET_CADET_close_port (room->port);
+     room->port = NULL;
+ 
+     return GNUNET_NO;
+   }
+ 
 -  struct GNUNET_MESSENGER_Message *peer_msg = create_message_peer 
(room->service);
 -  GNUNET_memcpy(&(peer_msg->header.sender_id), member_id, sizeof(*member_id));
 -  return (room->port ? send_srv_room_message (room, handle, peer_msg) : 
GNUNET_NO);
++  if (! room->port)
++    return GNUNET_NO;
++
++  return send_srv_room_message (room, handle, create_message_peer (
++                                  room->service));
+ }
+ 
++
+ int
+ enter_srv_room_at (struct GNUNET_MESSENGER_SrvRoom *room,
+                    struct GNUNET_MESSENGER_SrvHandle *handle,
+                    const struct GNUNET_PeerIdentity *door)
+ {
 -  GNUNET_assert((room) && (handle) && (door));
++  GNUNET_assert ((room) && (handle) && (door));
+ 
+   struct GNUNET_PeerIdentity peer;
+ 
+   if ((GNUNET_OK == get_service_peer_identity (room->service, &peer)) &&
 -      (0 == GNUNET_memcmp(&peer, door)))
++      (0 == GNUNET_memcmp (&peer, door)))
+     return join_room_locally (room, handle);
+ 
 -  struct GNUNET_MESSENGER_SrvTunnel *tunnel = 
GNUNET_CONTAINER_multipeermap_get (room->tunnels, door);
++  struct GNUNET_MESSENGER_SrvTunnel *tunnel =
++    GNUNET_CONTAINER_multipeermap_get (room->tunnels, door);
+ 
 -  if (!tunnel)
++  if (! tunnel)
+   {
+     tunnel = create_tunnel (room, door);
+ 
 -    if (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (room->tunnels, door, 
tunnel,
++    if (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (room->tunnels, door,
++                                                        tunnel,
+                                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))
+     {
 -      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not connect to that 
door!\n");
++      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                  "You could not connect to that door!\n");
+       destroy_tunnel (tunnel);
+       return GNUNET_NO;
+     }
+   }
+ 
+   if (GNUNET_SYSERR == connect_tunnel (tunnel))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Connection failure during 
entrance!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Connection failure during entrance!\n");
+     GNUNET_CONTAINER_multipeermap_remove (room->tunnels, door, tunnel);
+     destroy_tunnel (tunnel);
+     return GNUNET_NO;
+   }
+ 
+   return join_room_locally (room, handle);
+ }
+ 
++
++static void
++sign_srv_room_message_by_peer (const void *cls,
++                               struct GNUNET_MESSENGER_Message *message,
++                               uint16_t length,
++                               char *buffer,
++                               const struct GNUNET_HashCode *hash)
++{
++  const struct GNUNET_MESSENGER_SrvHandle *handle = cls;
++
++  GNUNET_assert ((handle) && (handle->service));
++
++  sign_message_by_peer (message, length, buffer, hash, 
handle->service->config);
++}
++
++
+ struct GNUNET_MQ_Envelope*
+ pack_srv_room_message (const struct GNUNET_MESSENGER_SrvRoom *room,
+                        const struct GNUNET_MESSENGER_SrvHandle *handle,
+                        struct GNUNET_MESSENGER_Message *message,
+                        struct GNUNET_HashCode *hash,
+                        int mode)
+ {
 -  GNUNET_assert((room) && (handle) && (message) && (hash));
++  GNUNET_assert ((room) && (handle) && (message) && (hash));
+ 
 -  message->header.timestamp = GNUNET_TIME_absolute_hton 
(GNUNET_TIME_absolute_get ());
++  if (GNUNET_YES != is_peer_message (message))
++    return pack_message (message, hash, NULL, mode, NULL);
+ 
 -  const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id (handle, 
get_srv_room_key(room));
++  message->header.timestamp = GNUNET_TIME_absolute_hton (
++    GNUNET_TIME_absolute_get ());
+ 
 -  GNUNET_assert(id);
++  struct GNUNET_PeerIdentity peer;
++  if (GNUNET_OK != get_service_peer_identity (handle->service, &peer))
++    return NULL;
+ 
 -  GNUNET_memcpy(&(message->header.sender_id), id, sizeof(struct 
GNUNET_ShortHashCode));
++  convert_peer_identity_to_id (&peer, &(message->header.sender_id));
+   get_message_state_chain_hash (&(room->state), &(message->header.previous));
+ 
 -  return pack_message (message, hash, get_srv_handle_ego (handle), mode);
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Packing message with peer signature: %s\n",
++              GNUNET_sh2s (&(message->header.sender_id)));
++
++  message->header.signature.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
++  return pack_message (message, hash, sign_srv_room_message_by_peer, mode,
++                       handle);
+ }
+ 
++
+ struct GNUNET_MESSENGER_ClosureSendRoom
+ {
+   struct GNUNET_MESSENGER_SrvRoom *room;
+   struct GNUNET_MESSENGER_SrvHandle *handle;
+   struct GNUNET_MESSENGER_SrvTunnel *exclude;
+   struct GNUNET_MESSENGER_Message *message;
+   struct GNUNET_HashCode *hash;
+   int packed;
+ };
+ 
+ static int
+ iterate_send_room_message (void *cls,
+                            const struct GNUNET_PeerIdentity *key,
+                            void *value)
+ {
+   struct GNUNET_MESSENGER_SrvTunnel *tunnel = value;
+ 
 -  if ((!is_tunnel_connected (tunnel)) ||
 -      (get_tunnel_messenger_version(tunnel) < GNUNET_MESSENGER_VERSION))
++  if ((! is_tunnel_connected (tunnel)) ||
++      (get_tunnel_messenger_version (tunnel) < GNUNET_MESSENGER_VERSION))
+     return GNUNET_YES;
+ 
+   struct GNUNET_MESSENGER_ClosureSendRoom *closure = cls;
+ 
+   if (tunnel == closure->exclude)
+     return GNUNET_YES;
+ 
+   struct GNUNET_MQ_Envelope *env = NULL;
+ 
+   if (closure->packed == GNUNET_NO)
+   {
 -    env = pack_srv_room_message (closure->room, closure->handle, 
closure->message, closure->hash,
 -    GNUNET_MESSENGER_PACK_MODE_ENVELOPE);
++    env = pack_srv_room_message (closure->room, closure->handle,
++                                 closure->message, closure->hash,
++                                 GNUNET_MESSENGER_PACK_MODE_ENVELOPE);
+ 
+     if (env)
+       closure->packed = GNUNET_YES;
+   }
+   else
 -    env = pack_message (closure->message, NULL, NULL, 
GNUNET_MESSENGER_PACK_MODE_ENVELOPE);
++    env = pack_message (closure->message, NULL, NULL,
++                        GNUNET_MESSENGER_PACK_MODE_ENVELOPE, NULL);
+ 
+   if (env)
+     send_tunnel_envelope (tunnel, env, closure->hash);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ int
+ update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                      struct GNUNET_MESSENGER_Message *message,
+                      const struct GNUNET_HashCode *hash);
+ 
+ void
+ callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room,
 -                              struct GNUNET_MESSENGER_SrvHandle *handle,
+                               const struct GNUNET_MESSENGER_Message *message,
+                               const struct GNUNET_HashCode *hash);
+ 
+ int
+ send_srv_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                        struct GNUNET_MESSENGER_SrvHandle *handle,
+                        struct GNUNET_MESSENGER_Message *message)
+ {
 -  GNUNET_assert((room) && (handle));
++  GNUNET_assert ((room) && (handle));
+ 
 -  if (!message)
++  if (! message)
+     return GNUNET_NO;
+ 
 -  if (GNUNET_YES == is_message_session_bound(message))
 -    merge_srv_room_last_messages(room, handle);
++  if (GNUNET_YES == is_message_session_bound (message))
++    merge_srv_room_last_messages (room, handle);
++
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Sending message from handle with member 
id: %s\n",
 -             GNUNET_sh2s(get_srv_handle_member_id(handle, 
get_srv_room_key(room))));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Sending message from handle in room: %s (%s)\n",
++              GNUNET_h2s (&(room->key)),
++              GNUNET_MESSENGER_name_of_kind (message->header.kind));
+ 
+   struct GNUNET_HashCode hash;
+   struct GNUNET_MESSENGER_ClosureSendRoom closure;
+ 
+   closure.room = room;
+   closure.handle = handle;
+   closure.exclude = NULL;
+   closure.message = message;
+   closure.hash = &hash;
+   closure.packed = GNUNET_NO;
+ 
 -  GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, 
iterate_send_room_message, &closure);
++  GNUNET_CONTAINER_multipeermap_iterate (room->tunnels,
++                                         iterate_send_room_message, &closure);
+ 
+   if (GNUNET_NO == closure.packed)
 -    pack_srv_room_message (room, handle, message, &hash, 
GNUNET_MESSENGER_PACK_MODE_UNKNOWN);
++    pack_srv_room_message (room, handle, message, &hash,
++                           GNUNET_MESSENGER_PACK_MODE_UNKNOWN);
+ 
+   const int new_message = update_room_message (room, message, &hash);
+ 
+   if (GNUNET_YES != new_message)
+     return GNUNET_SYSERR;
+ 
+   switch (message->header.kind)
+   {
+   case GNUNET_MESSENGER_KIND_JOIN:
+     send_message_join (room, handle, message, &hash);
+     break;
++  case GNUNET_MESSENGER_KIND_KEY:
++    send_message_key (room, handle, message, &hash);
++    break;
+   case GNUNET_MESSENGER_KIND_PEER:
+     send_message_peer (room, handle, message, &hash);
+     break;
+   case GNUNET_MESSENGER_KIND_ID:
+     send_message_id (room, handle, message, &hash);
+     break;
+   case GNUNET_MESSENGER_KIND_REQUEST:
+     send_message_request (room, handle, message, &hash);
+     break;
+   default:
+     break;
+   }
+ 
 -  callback_room_handle_message (room, handle, message, &hash);
++  callback_room_handle_message (room, message, &hash);
+   return GNUNET_YES;
+ }
+ 
++
+ void
+ forward_srv_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                           struct GNUNET_MESSENGER_SrvTunnel *tunnel,
+                           struct GNUNET_MESSENGER_Message *message,
+                           const struct GNUNET_HashCode *hash)
+ {
 -  GNUNET_assert((room) && (tunnel));
++  GNUNET_assert ((room) && (tunnel));
+ 
 -  if (!message)
++  if (! message)
+     return;
+ 
+   struct GNUNET_MESSENGER_ClosureSendRoom closure;
+   struct GNUNET_HashCode message_hash;
+ 
 -  GNUNET_memcpy(&message_hash, hash, sizeof(struct GNUNET_HashCode));
++  GNUNET_memcpy (&message_hash, hash, sizeof(struct GNUNET_HashCode));
+ 
+   closure.room = room;
+   closure.handle = NULL;
+   closure.exclude = tunnel;
+   closure.message = message;
+   closure.hash = &message_hash;
+   closure.packed = GNUNET_YES;
+ 
 -  GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, 
iterate_send_room_message, &closure);
++  GNUNET_CONTAINER_multipeermap_iterate (room->tunnels,
++                                         iterate_send_room_message, &closure);
+ }
+ 
++
+ void
+ check_srv_room_peer_status (struct GNUNET_MESSENGER_SrvRoom *room,
+                             struct GNUNET_MESSENGER_SrvTunnel *tunnel)
+ {
 -  if (!room->peer_message)
++  if (! room->peer_message)
+     return;
+ 
 -  struct GNUNET_MESSENGER_MessageStore *message_store = 
get_srv_room_message_store(room);
++  struct GNUNET_MESSENGER_MessageStore *message_store =
++    get_srv_room_message_store (room);
+ 
 -  const struct GNUNET_MESSENGER_Message *message = 
get_store_message(message_store, room->peer_message);
++  const struct GNUNET_MESSENGER_Message *message = get_store_message (
++    message_store, room->peer_message);
+ 
 -  if (!message)
++  if (! message)
+   {
 -    GNUNET_free(room->peer_message);
++    GNUNET_free (room->peer_message);
+     room->peer_message = NULL;
+     return;
+   }
+ 
 -  struct GNUNET_MESSENGER_MemberStore *member_store = 
get_srv_room_member_store(room);
 -  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, 
message);
 -
 -  if (!member)
 -    goto resend_peer_message;
 -
 -  struct GNUNET_MESSENGER_MemberSession *session = 
get_member_session_of(member, message, room->peer_message);
 -
 -  if (GNUNET_YES == is_member_session_closed(session))
 -    goto resend_peer_message;
 -
+   if (tunnel)
 -    forward_tunnel_message(tunnel, message, room->peer_message);
 -
 -  return;
 -
 -resend_peer_message:
 -  if (room->host)
 -    send_srv_room_message (room, room->host, create_message_peer 
(room->service));
++    forward_tunnel_message (tunnel, message, room->peer_message);
+ }
+ 
++
+ void
+ merge_srv_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room,
+                               struct GNUNET_MESSENGER_SrvHandle *handle)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
 -  if (!handle)
++  if (! handle)
+     return;
+ 
+   const struct GNUNET_HashCode *hash;
+ 
+ merge_next:
+   hash = get_message_state_merge_hash (&(room->state));
+ 
 -  if (!hash)
++  if (! hash)
+     return;
+ 
+   send_srv_room_message (room, handle, create_message_merge (hash));
+   goto merge_next;
+ }
+ 
++
+ void
+ callback_room_deletion (struct GNUNET_MESSENGER_SrvRoom *room,
+                         const struct GNUNET_HashCode *hash)
+ {
 -  if (GNUNET_OK != delete_store_message (get_srv_room_message_store(room), 
hash))
++  if (GNUNET_OK != delete_store_message (get_srv_room_message_store (room),
++                                         hash))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Deletion of message failed! 
(%s)\n", GNUNET_h2s(hash));
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deletion of message failed! 
(%s)\n",
++                GNUNET_h2s (hash));
+     return;
+   }
+ }
+ 
++
+ void
+ callback_room_merge (struct GNUNET_MESSENGER_SrvRoom *room,
+                      const struct GNUNET_HashCode *hash)
+ {
 -  if (!room->host)
++  if (! room->host)
+     return;
+ 
+   send_srv_room_message (room, room->host, create_message_merge (hash));
+ }
+ 
++
+ int
+ delete_srv_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                          struct GNUNET_MESSENGER_MemberSession *session,
+                          const struct GNUNET_HashCode *hash,
+                          const struct GNUNET_TIME_Relative delay)
+ {
 -  GNUNET_assert((room) && (session) && (hash));
++  GNUNET_assert ((room) && (session) && (hash));
+ 
 -  const struct GNUNET_TIME_Relative forever = 
GNUNET_TIME_relative_get_forever_ ();
++  const struct GNUNET_TIME_Relative forever =
++    GNUNET_TIME_relative_get_forever_ ();
+ 
 -  if (0 == GNUNET_memcmp(&forever, &delay))
++  if (0 == GNUNET_memcmp (&forever, &delay))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Deletion is delayed forever: 
operation is impossible!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
++                "Deletion is delayed forever: operation is impossible!\n");
+     return GNUNET_SYSERR;
+   }
+ 
 -  struct GNUNET_MESSENGER_MessageStore *message_store = 
get_srv_room_message_store(room);
++  struct GNUNET_MESSENGER_MessageStore *message_store =
++    get_srv_room_message_store (room);
+ 
 -  const struct GNUNET_MESSENGER_Message *message = 
get_store_message(message_store, hash);
++  const struct GNUNET_MESSENGER_Message *message = get_store_message (
++    message_store, hash);
+ 
 -  if (!message)
++  if (! message)
+     return GNUNET_YES;
+ 
 -  if (GNUNET_YES != check_member_session_history(session, hash, GNUNET_YES))
++  if (GNUNET_YES != check_member_session_history (session, hash, GNUNET_YES))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Unpermitted request for deletion 
by member (%s) of message (%s)!\n",
 -               GNUNET_sh2s(get_member_session_id(session)), GNUNET_h2s(hash));
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Unpermitted request for deletion by member (%s) of message 
(%s)!\n",
++                GNUNET_sh2s (get_member_session_id (session)), GNUNET_h2s (
++                  hash));
+ 
+     return GNUNET_NO;
+   }
+ 
 -  struct GNUNET_MESSENGER_OperationStore *operation_store = 
get_srv_room_operation_store(room);
++  struct GNUNET_MESSENGER_OperationStore *operation_store =
++    get_srv_room_operation_store (room);
+ 
 -  if (GNUNET_OK != use_store_operation(operation_store, hash, 
GNUNET_MESSENGER_OP_DELETE, delay))
++  if (GNUNET_OK != use_store_operation (operation_store, hash,
++                                        GNUNET_MESSENGER_OP_DELETE, delay))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Deletion has failed: operation 
denied!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Deletion has failed: operation denied!\n");
+     return GNUNET_SYSERR;
+   }
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ struct GNUNET_CADET_Handle*
+ get_srv_room_cadet (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   return room->service->cadet;
+ }
+ 
++
+ const struct GNUNET_HashCode*
+ get_srv_room_key (const struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   return &(room->key);
+ }
+ 
++
+ const struct GNUNET_MESSENGER_SrvTunnel*
+ get_srv_room_tunnel (const struct GNUNET_MESSENGER_SrvRoom *room,
+                      const struct GNUNET_PeerIdentity *peer)
+ {
 -  GNUNET_assert((room) && (peer));
++  GNUNET_assert ((room) && (peer));
+ 
+   return GNUNET_CONTAINER_multipeermap_get (room->tunnels, peer);
+ }
+ 
++
+ static int
+ request_room_message_step (struct GNUNET_MESSENGER_SrvRoom *room,
+                            const struct GNUNET_HashCode *hash,
+                            const struct GNUNET_MESSENGER_MemberSession 
*session,
+                            GNUNET_MESSENGER_MessageRequestCallback callback,
 -                           void* cls)
++                           void *cls)
+ {
 -  struct GNUNET_MESSENGER_MessageStore *message_store = 
get_srv_room_message_store(room);
++  struct GNUNET_MESSENGER_MessageStore *message_store =
++    get_srv_room_message_store (room);
+ 
 -  const struct GNUNET_MESSENGER_MessageLink *link = get_store_message_link(
 -      message_store, hash, GNUNET_YES
 -  );
++  const struct GNUNET_MESSENGER_MessageLink *link = get_store_message_link (
++    message_store, hash, GNUNET_YES
++    );
+ 
 -  if (!link)
++  if (! link)
+     goto forward;
+ 
 -  int result = request_room_message_step(room, &(link->first), session, 
callback, cls);
++  int result = request_room_message_step (room, &(link->first), session,
++                                          callback, cls);
+ 
+   if ((GNUNET_YES == link->multiple) &&
 -      (GNUNET_YES == request_room_message_step(room, &(link->second), 
session, callback, cls)))
++      (GNUNET_YES == request_room_message_step (room, &(link->second), 
session,
++                                                callback, cls)))
+     return GNUNET_YES;
+   else
+     return result;
+ 
+ forward:
 -  if (GNUNET_YES != check_member_session_history(session, hash, GNUNET_NO))
++  if (GNUNET_YES != check_member_session_history (session, hash, GNUNET_NO))
+     return GNUNET_YES;
+ 
 -  const struct GNUNET_MESSENGER_Message *message = 
get_store_message(message_store, hash);
++  const struct GNUNET_MESSENGER_Message *message = get_store_message (
++    message_store, hash);
+ 
 -  if (!message)
++  if (! message)
+     return GNUNET_NO;
+ 
+   if (callback)
+     callback (cls, room, message, hash);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ int
+ request_srv_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                           const struct GNUNET_HashCode *hash,
+                           const struct GNUNET_MESSENGER_MemberSession 
*session,
+                           GNUNET_MESSENGER_MessageRequestCallback callback,
 -                          void* cls)
++                          void *cls)
+ {
 -  GNUNET_assert((room) && (hash));
++  GNUNET_assert ((room) && (hash));
+ 
+   int result = request_room_message_step (room, hash, session, callback, cls);
+ 
+   if ((GNUNET_NO == result) && (callback))
+     callback (cls, room, NULL, hash);
+ 
+   return result;
+ }
+ 
++
+ void
+ callback_room_disconnect (struct GNUNET_MESSENGER_SrvRoom *room,
+                           void *cls)
+ {
+   struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
+ 
 -  if (!room->host)
++  if (! room->host)
+     return;
+ 
+   struct GNUNET_PeerIdentity identity;
 -  get_tunnel_peer_identity(tunnel, &identity);
++  get_tunnel_peer_identity (tunnel, &identity);
+ 
 -  if ((GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove (room->tunnels, 
&identity, tunnel)) ||
 -      (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains(room->tunnels, 
&identity)))
++  if ((GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove (room->tunnels,
++                                                           &identity,
++                                                           tunnel)) ||
++      (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (room->tunnels,
++                                                             &identity)))
+     return;
+ 
+   if (GNUNET_YES == contains_list_tunnels (&(room->basement), &identity))
+     send_srv_room_message (room, room->host, create_message_miss (&identity));
+ }
+ 
++
+ int
+ callback_verify_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                               void *cls,
+                               struct GNUNET_MESSENGER_Message *message,
+                               struct GNUNET_HashCode *hash)
+ {
+   if (GNUNET_MESSENGER_KIND_UNKNOWN == message->header.kind)
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Message error: Kind is unknown! 
(%d)\n", message->header.kind);
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Message error: Kind is unknown! (%d)\n", 
message->header.kind);
+     return GNUNET_SYSERR;
+   }
+ 
 -  struct GNUNET_MESSENGER_MessageStore *message_store = 
get_srv_room_message_store(room);
++  struct GNUNET_MESSENGER_MessageStore *message_store =
++    get_srv_room_message_store (room);
+ 
 -  const struct GNUNET_MESSENGER_Message *previous = 
get_store_message(message_store, &(message->header.previous));
++  const struct GNUNET_MESSENGER_Message *previous = get_store_message (
++    message_store, &(message->header.previous));
+ 
 -  if (!previous)
++  if (! previous)
+     goto skip_time_comparison;
+ 
 -  struct GNUNET_TIME_Absolute timestamp = 
GNUNET_TIME_absolute_ntoh(message->header.timestamp);
 -  struct GNUNET_TIME_Absolute last = 
GNUNET_TIME_absolute_ntoh(previous->header.timestamp);
++  struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_absolute_ntoh (
++    message->header.timestamp);
++  struct GNUNET_TIME_Absolute last = GNUNET_TIME_absolute_ntoh (
++    previous->header.timestamp);
+ 
 -  if (GNUNET_TIME_relative_get_zero_().rel_value_us != 
GNUNET_TIME_absolute_get_difference(timestamp, last).rel_value_us)
++  if (GNUNET_TIME_relative_get_zero_ ().rel_value_us !=
++      GNUNET_TIME_absolute_get_difference (timestamp, last).rel_value_us)
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Message error: Timestamp does not 
check out!\n");
 -    return GNUNET_SYSERR;
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Message warning: Timestamp does not check out!\n");
+   }
+ 
+ skip_time_comparison:
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message of kind: %s!\n",
 -             GNUNET_MESSENGER_name_of_kind(message->header.kind));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving message of kind: %s!\n",
++              GNUNET_MESSENGER_name_of_kind (message->header.kind));
+ 
+   return GNUNET_OK;
+ }
+ 
++
+ static void
+ idle_request_room_messages (void *cls)
+ {
+   struct GNUNET_MESSENGER_SrvRoom *room = cls;
+ 
+   room->idle = NULL;
+ 
 -  struct GNUNET_MESSENGER_OperationStore *operation_store = 
get_srv_room_operation_store(room);
 -  const struct GNUNET_HashCode *hash = 
get_message_state_merge_hash(&(room->state));
++  struct GNUNET_MESSENGER_OperationStore *operation_store =
++    get_srv_room_operation_store (room);
++  const struct GNUNET_HashCode *hash = get_message_state_merge_hash (
++    &(room->state));
+ 
+   if ((hash) &&
 -      (GNUNET_MESSENGER_OP_UNKNOWN == 
get_store_operation_type(operation_store, hash)))
 -    use_store_operation(
 -        operation_store,
 -        hash,
 -        GNUNET_MESSENGER_OP_MERGE,
 -        GNUNET_MESSENGER_MERGE_DELAY
 -    );
++      (GNUNET_MESSENGER_OP_UNKNOWN == get_store_operation_type 
(operation_store,
++                                                                hash)))
++    use_store_operation (
++      operation_store,
++      hash,
++      GNUNET_MESSENGER_OP_MERGE,
++      GNUNET_MESSENGER_MERGE_DELAY
++      );
+ 
+   room->idle = GNUNET_SCHEDULER_add_delayed_with_priority (
 -      GNUNET_MESSENGER_IDLE_DELAY,
 -      GNUNET_SCHEDULER_PRIORITY_IDLE,
 -      idle_request_room_messages,
 -      cls
 -  );
++    GNUNET_MESSENGER_IDLE_DELAY,
++    GNUNET_SCHEDULER_PRIORITY_IDLE,
++    idle_request_room_messages,
++    cls
++    );
+ }
+ 
++
+ void
+ solve_srv_room_member_collisions (struct GNUNET_MESSENGER_SrvRoom *room,
 -                                  const struct GNUNET_CRYPTO_PublicKey 
*public_key,
++                                  const struct
++                                  GNUNET_CRYPTO_PublicKey *public_key,
+                                   const struct GNUNET_ShortHashCode 
*member_id,
+                                   struct GNUNET_TIME_Absolute timestamp)
+ {
+   GNUNET_assert ((room) && (public_key) && (member_id));
+ 
 -  struct GNUNET_MESSENGER_MemberStore *member_store = 
get_srv_room_member_store(room);
 -  struct GNUNET_MESSENGER_Member *member = get_store_member(member_store, 
member_id);
++  struct GNUNET_MESSENGER_MemberStore *member_store =
++    get_srv_room_member_store (room);
++  struct GNUNET_MESSENGER_Member *member = get_store_member (member_store,
++                                                             member_id);
+ 
 -  if ((!member) || (1 >= 
GNUNET_CONTAINER_multihashmap_size(member->sessions)))
++  if ((! member) || (1 >= GNUNET_CONTAINER_multihashmap_size (
++                       member->sessions)))
+     return;
+ 
+   struct GNUNET_MESSENGER_ListHandles *handles = &(room->service->handles);
 -  struct GNUNET_MESSENGER_ListHandle* element;
++  struct GNUNET_MESSENGER_ListHandle *element;
++
++  const struct GNUNET_CRYPTO_PublicKey *pubkey;
+ 
+   for (element = handles->head; element; element = element->next)
+   {
 -    if (0 != GNUNET_memcmp(member_id, 
get_srv_handle_member_id(element->handle, get_srv_room_key(room))))
++    if (0 != GNUNET_memcmp (member_id, get_srv_handle_member_id (
++                              element->handle, get_srv_room_key (room))))
+       continue;
+ 
 -    if (0 == GNUNET_memcmp(public_key, 
&(get_srv_handle_ego(element->handle)->pub)))
++    pubkey = get_srv_handle_key (element->handle);
++
++    if (0 == GNUNET_memcmp (public_key, pubkey))
+       continue;
+ 
 -    struct GNUNET_MESSENGER_MemberSession *session = 
get_member_session(member, &(get_srv_handle_ego(element->handle)->pub));
++    struct GNUNET_MESSENGER_MemberSession *session = get_member_session 
(member,
++                                                                         
pubkey);
+ 
 -    if (!session)
++    if (! session)
+       continue;
+ 
 -    struct GNUNET_TIME_Absolute start = get_member_session_start(session);
++    struct GNUNET_TIME_Absolute start = get_member_session_start (session);
+ 
 -    if (GNUNET_TIME_relative_get_zero_().rel_value_us != 
GNUNET_TIME_absolute_get_difference(start, timestamp).rel_value_us)
++    if (GNUNET_TIME_relative_get_zero_ ().rel_value_us !=
++        GNUNET_TIME_absolute_get_difference (start, timestamp).rel_value_us)
+       continue;
+ 
+     struct GNUNET_ShortHashCode random_id;
+     generate_free_member_id (&random_id, member_store->members);
+ 
 -    send_srv_room_message(room, element->handle, 
create_message_id(&random_id));
++    notify_srv_handle_member_id (element->handle, room, &random_id, 
GNUNET_NO);
+   }
+ }
+ 
++
+ void
+ rebuild_srv_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   struct GNUNET_PeerIdentity peer;
+   size_t src;
+ 
+   if ((GNUNET_OK != get_service_peer_identity (room->service, &peer)) ||
 -      (!find_list_tunnels (&(room->basement), &peer, &src)))
++      (! find_list_tunnels (&(room->basement), &peer, &src)))
+     return;
+ 
+   size_t count = count_of_tunnels (&(room->basement));
+ 
+   struct GNUNET_MESSENGER_ListTunnel *element = room->basement.head;
+   struct GNUNET_MESSENGER_SrvTunnel *tunnel;
+ 
+   size_t dst = 0;
+ 
+   while (element)
+   {
+     GNUNET_PEER_resolve (element->peer, &peer);
+ 
+     tunnel = GNUNET_CONTAINER_multipeermap_get (room->tunnels, &peer);
+ 
 -    if (!tunnel)
++    if (! tunnel)
+     {
+       element = remove_from_list_tunnels (&(room->basement), element);
+       continue;
+     }
+ 
+     if (GNUNET_YES == required_connection_between (count, src, dst))
+     {
+       if (GNUNET_SYSERR == connect_tunnel (tunnel))
+       {
+         element = remove_from_list_tunnels (&(room->basement), element);
+         continue;
+       }
+     }
+     else
+       disconnect_tunnel (tunnel);
+ 
+     element = element->next;
+     dst++;
+   }
+ }
+ 
++
+ static void
+ handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  struct GNUNET_MESSENGER_MessageStore *message_store = 
get_srv_room_message_store(room);
 -  struct GNUNET_MESSENGER_MemberStore *member_store = 
get_srv_room_member_store(room);
++  struct GNUNET_MESSENGER_MessageStore *message_store =
++    get_srv_room_message_store (room);
++  struct GNUNET_MESSENGER_MemberStore *member_store =
++    get_srv_room_member_store (room);
++  struct GNUNET_MESSENGER_PeerStore *peer_store = get_srv_room_peer_store (
++    room);
+ 
+   while (room->handling.head)
+   {
+     struct GNUNET_MESSENGER_ListMessage *element = room->handling.head;
+ 
 -    const struct GNUNET_MESSENGER_Message *message = get_store_message 
(message_store, &(element->hash));
++    const struct GNUNET_MESSENGER_Message *message = get_store_message (
++      message_store, &(element->hash));
+ 
 -    if (!message)
++    if (! message)
+       goto finish_handling;
+ 
 -    struct GNUNET_MESSENGER_Member *member = 
get_store_member_of(member_store, message);
++    struct GNUNET_MESSENGER_SenderSession session;
+ 
 -    if (!member)
 -      goto finish_handling;
++    if (GNUNET_YES == is_peer_message (message))
++    {
++      session.peer = get_store_peer_of (peer_store, message, 
&(element->hash));
+ 
 -    struct GNUNET_MESSENGER_MemberSession *session = 
get_member_session_of(member, message, &(element->hash));
++      if (! session.peer)
++        goto finish_handling;
++    }
++    else
++    {
++      struct GNUNET_MESSENGER_Member *member = get_store_member_of (
++        member_store, message);
+ 
 -    if (session)
 -      handle_service_message (room->service, room, session, message, 
&(element->hash));
++      if (! member)
++        goto finish_handling;
++
++      session.member = get_member_session_of (member, message,
++                                              &(element->hash));
++
++      if (! session.member)
++        goto finish_handling;
++    }
++
++    handle_service_message (room->service, room, &session, message,
++                            &(element->hash));
+ 
+ finish_handling:
 -    GNUNET_CONTAINER_DLL_remove(room->handling.head, room->handling.tail, 
element);
 -    GNUNET_free(element);
++    GNUNET_CONTAINER_DLL_remove (room->handling.head, room->handling.tail,
++                                 element);
++    GNUNET_free (element);
+   }
+ }
+ 
++
+ int
+ update_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                      struct GNUNET_MESSENGER_Message *message,
+                      const struct GNUNET_HashCode *hash)
+ {
 -  GNUNET_assert((room) && (message) && (hash));
++  GNUNET_assert ((room) && (message) && (hash));
+ 
 -  struct GNUNET_MESSENGER_OperationStore *operation_store = 
get_srv_room_operation_store(room);
++  struct GNUNET_MESSENGER_OperationStore *operation_store =
++    get_srv_room_operation_store (room);
+ 
 -  const int requested = (GNUNET_MESSENGER_OP_REQUEST == 
get_store_operation_type(operation_store, hash)?
 -      GNUNET_YES : GNUNET_NO
 -  );
++  const int requested = (GNUNET_MESSENGER_OP_REQUEST ==
++                         get_store_operation_type (operation_store, hash)?
++                         GNUNET_YES : GNUNET_NO
++                         );
+ 
+   if (GNUNET_YES == requested)
 -    cancel_store_operation(operation_store, hash);
++    cancel_store_operation (operation_store, hash);
+ 
 -  struct GNUNET_MESSENGER_MessageStore *message_store = 
get_srv_room_message_store(room);
++  struct GNUNET_MESSENGER_MessageStore *message_store =
++    get_srv_room_message_store (room);
+ 
 -  const struct GNUNET_MESSENGER_Message *old_message = get_store_message 
(message_store, hash);
++  const struct GNUNET_MESSENGER_Message *old_message = get_store_message (
++    message_store, hash);
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle a message in room (%s).\n", 
GNUNET_h2s (get_srv_room_key(room)));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Handle a message in room (%s).\n",
++              GNUNET_h2s (get_srv_room_key (room)));
+ 
 -  if ((old_message) || (GNUNET_OK != put_store_message (message_store, hash, 
message)))
++  if ((old_message) || (GNUNET_OK != put_store_message (message_store, hash,
++                                                        message)))
+   {
+     if (old_message != message)
 -      destroy_message(message);
++      destroy_message (message);
+ 
 -    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Duplicate message got dropped!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Duplicate message got dropped!\n");
+     return GNUNET_NO;
+   }
+ 
 -  update_message_state(&(room->state), requested, message, hash);
++  update_message_state (&(room->state), requested, message, hash);
+ 
+   if ((GNUNET_YES == requested) ||
+       (GNUNET_MESSENGER_KIND_INFO == message->header.kind) ||
+       (GNUNET_MESSENGER_KIND_REQUEST == message->header.kind))
+     return GNUNET_YES;
+ 
+   if ((GNUNET_MESSENGER_KIND_MERGE == message->header.kind) &&
 -      (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, 
&(message->body.merge.previous))))
 -    cancel_store_operation(operation_store, &(message->body.merge.previous));
++      (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type (operation_store,
++                                                              &(message->body.
++                                                                
merge.previous))))
++    cancel_store_operation (operation_store, &(message->body.merge.previous));
+ 
 -  if (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, 
&(message->header.previous)))
 -    cancel_store_operation(operation_store, &(message->header.previous));
++  if (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type (operation_store,
++                                                             
&(message->header.
++                                                               previous)))
++    cancel_store_operation (operation_store, &(message->header.previous));
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ struct GNUNET_MESSENGER_MemberSessionCompletion
+ {
+   struct GNUNET_MESSENGER_MemberSessionCompletion *prev;
+   struct GNUNET_MESSENGER_MemberSessionCompletion *next;
+ 
+   struct GNUNET_MESSENGER_MemberSession *session;
+ };
+ 
+ struct GNUNET_MESSENGER_MemberUpdate
+ {
+   const struct GNUNET_MESSENGER_Message *message;
+   const struct GNUNET_HashCode *hash;
+ 
+   struct GNUNET_MESSENGER_MemberSessionCompletion *head;
+   struct GNUNET_MESSENGER_MemberSessionCompletion *tail;
+ };
+ 
+ static int
+ iterate_update_member_sessions (void *cls,
 -                                const struct GNUNET_CRYPTO_PublicKey 
*public_key,
++                                const struct
++                                GNUNET_CRYPTO_PublicKey *public_key,
+                                 struct GNUNET_MESSENGER_MemberSession 
*session)
+ {
+   struct GNUNET_MESSENGER_MemberUpdate *update = cls;
+ 
 -  update_member_session_history(session, update->message, update->hash);
++  update_member_session_history (session, update->message, update->hash);
+ 
 -  if (GNUNET_YES == is_member_session_completed(session))
++  if (GNUNET_YES == is_member_session_completed (session))
+   {
 -    struct GNUNET_MESSENGER_MemberSessionCompletion *element = GNUNET_new(
 -        struct GNUNET_MESSENGER_MemberSessionCompletion
 -    );
++    struct GNUNET_MESSENGER_MemberSessionCompletion *element = GNUNET_new (
++      struct GNUNET_MESSENGER_MemberSessionCompletion
++      );
+ 
+     element->session = session;
+ 
 -    GNUNET_CONTAINER_DLL_insert_tail(update->head, update->tail, element);
++    GNUNET_CONTAINER_DLL_insert_tail (update->head, update->tail, element);
+   }
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ static void
+ remove_room_member_session (struct GNUNET_MESSENGER_SrvRoom *room,
+                             struct GNUNET_MESSENGER_MemberSession *session);
+ 
+ void
+ callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room,
 -                              struct GNUNET_MESSENGER_SrvHandle *handle,
+                               const struct GNUNET_MESSENGER_Message *message,
+                               const struct GNUNET_HashCode *hash)
+ {
 -  struct GNUNET_MESSENGER_MemberStore *member_store = 
get_srv_room_member_store(room);
 -  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, 
message);
++  GNUNET_assert ((room) && (message) && (hash));
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Callback for message (%s)\n", 
GNUNET_h2s (hash));
++  struct GNUNET_MESSENGER_PeerStore *peer_store = get_srv_room_peer_store (
++    room);
++  struct GNUNET_MESSENGER_MemberStore *member_store =
++    get_srv_room_member_store (room);
+ 
 -  if (!member)
++  struct GNUNET_MESSENGER_SenderSession session;
++
++  if (GNUNET_YES == is_peer_message (message))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Message handling dropped: Member 
is missing!\n");
 -    return;
++    session.peer = get_store_peer_of (peer_store, message, hash);
++
++    if (! session.peer)
++    {
++      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                  "Message handling dropped: Peer is missing!\n");
++      return;
++    }
+   }
++  else
++  {
++    struct GNUNET_MESSENGER_Member *member = get_store_member_of 
(member_store,
++                                                                  message);
+ 
 -  struct GNUNET_MESSENGER_MemberSession *session = 
get_member_session_of(member, message, hash);
++    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for message (%s)\n",
++                GNUNET_h2s (hash));
+ 
 -  if (!session)
 -  {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Message handling dropped: Session 
is missing!\n");
 -    return;
++    if (! member)
++    {
++      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                  "Message handling dropped: Member is missing!\n");
++      return;
++    }
++
++    session.member = get_member_session_of (member, message, hash);
++
++    if (! session.member)
++    {
++      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                  "Message handling dropped: Session is missing!\n");
++      return;
++    }
+   }
+ 
+   struct GNUNET_MESSENGER_MemberUpdate update;
+   update.message = message;
+   update.hash = hash;
+ 
+   update.head = NULL;
+   update.tail = NULL;
+ 
 -  iterate_store_members(member_store, iterate_update_member_sessions, 
&update);
++  iterate_store_members (member_store, iterate_update_member_sessions, 
&update);
+ 
+   while (update.head)
+   {
+     struct GNUNET_MESSENGER_MemberSessionCompletion *element = update.head;
+ 
+     remove_room_member_session (room, element->session);
+ 
 -    GNUNET_CONTAINER_DLL_remove(update.head, update.tail, element);
++    GNUNET_CONTAINER_DLL_remove (update.head, update.tail, element);
+     GNUNET_free (element);
+   }
+ 
+   const int start_handle = room->handling.head ? GNUNET_NO : GNUNET_YES;
+ 
+   add_to_list_messages (&(room->handling), hash);
+ 
+   switch (message->header.kind)
+   {
+   case GNUNET_MESSENGER_KIND_JOIN:
 -    handle_message_join (room, session, message, hash);
++    handle_message_join (room, &session, message, hash);
+     break;
+   case GNUNET_MESSENGER_KIND_LEAVE:
 -    handle_message_leave (room, session, message, hash);
++    handle_message_leave (room, &session, message, hash);
+     break;
+   case GNUNET_MESSENGER_KIND_NAME:
 -    handle_message_name (room, session, message, hash);
++    handle_message_name (room, &session, message, hash);
+     break;
+   case GNUNET_MESSENGER_KIND_KEY:
 -    handle_message_key (room, session, message, hash);
++    handle_message_key (room, &session, message, hash);
+     break;
+   case GNUNET_MESSENGER_KIND_PEER:
 -    handle_message_peer (room, session, message, hash);
++    handle_message_peer (room, &session, message, hash);
+     break;
+   case GNUNET_MESSENGER_KIND_ID:
 -    handle_message_id (room, session, message, hash);
++    handle_message_id (room, &session, message, hash);
+     break;
+   case GNUNET_MESSENGER_KIND_MISS:
 -    handle_message_miss (room, session, message, hash);
++    handle_message_miss (room, &session, message, hash);
+     break;
+   case GNUNET_MESSENGER_KIND_DELETE:
 -    handle_message_delete (room, session, message, hash);
++    handle_message_delete (room, &session, message, hash);
+     break;
+   default:
+     break;
+   }
+ 
+   if (GNUNET_YES == start_handle)
+     handle_room_messages (room);
+ }
+ 
++
+ static void
+ get_room_data_subdir (struct GNUNET_MESSENGER_SrvRoom *room,
+                       char **dir)
+ {
 -  GNUNET_assert((room) && (dir));
++  GNUNET_assert ((room) && (dir));
+ 
 -  GNUNET_asprintf (dir, "%s%s%c%s%c", room->service->dir, "rooms", 
DIR_SEPARATOR, GNUNET_h2s (get_srv_room_key(room)), DIR_SEPARATOR);
++  GNUNET_asprintf (dir, "%s%s%c%s%c", room->service->dir, "rooms",
++                   DIR_SEPARATOR, GNUNET_h2s (get_srv_room_key (room)),
++                   DIR_SEPARATOR);
+ }
+ 
++
+ void
+ load_srv_room (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   char *room_dir;
+   get_room_data_subdir (room, &room_dir);
+ 
+   if (GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_YES))
+   {
 -    load_member_store (get_srv_room_member_store(room), room_dir);
 -    load_message_store (get_srv_room_message_store(room), room_dir);
 -    load_operation_store(get_srv_room_operation_store(room), room_dir);
++    load_member_store (get_srv_room_member_store (room), room_dir);
++    load_message_store (get_srv_room_message_store (room), room_dir);
++    load_operation_store (get_srv_room_operation_store (room), room_dir);
+ 
+     char *basement_file;
+     GNUNET_asprintf (&basement_file, "%s%s", room_dir, "basement.list");
+ 
 -    load_list_tunnels(&(room->basement), basement_file);
 -    GNUNET_free(basement_file);
++    load_list_tunnels (&(room->basement), basement_file);
++    GNUNET_free (basement_file);
+ 
 -    load_message_state(&(room->state), room_dir);
++    load_message_state (&(room->state), room_dir);
+   }
+ 
 -  GNUNET_free(room_dir);
++  GNUNET_free (room_dir);
+ }
+ 
++
+ void
+ save_srv_room (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   char *room_dir;
+   get_room_data_subdir (room, &room_dir);
+ 
+   if ((GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_NO)) ||
+       (GNUNET_OK == GNUNET_DISK_directory_create (room_dir)))
+   {
 -    save_member_store(get_srv_room_member_store(room), room_dir);
 -    save_message_store (get_srv_room_message_store(room), room_dir);
 -    save_operation_store(get_srv_room_operation_store(room), room_dir);
++    save_member_store (get_srv_room_member_store (room), room_dir);
++    save_message_store (get_srv_room_message_store (room), room_dir);
++    save_operation_store (get_srv_room_operation_store (room), room_dir);
+ 
+     char *basement_file;
+     GNUNET_asprintf (&basement_file, "%s%s", room_dir, "basement.list");
+ 
 -    save_list_tunnels(&(room->basement), basement_file);
 -    GNUNET_free(basement_file);
++    save_list_tunnels (&(room->basement), basement_file);
++    GNUNET_free (basement_file);
+ 
 -    save_message_state(&(room->state), room_dir);
++    save_message_state (&(room->state), room_dir);
+   }
+ 
 -  GNUNET_free(room_dir);
++  GNUNET_free (room_dir);
+ }
+ 
++
+ void
+ remove_srv_room (struct GNUNET_MESSENGER_SrvRoom *room)
+ {
 -  GNUNET_assert(room);
++  GNUNET_assert (room);
+ 
+   char *room_dir;
+   get_room_data_subdir (room, &room_dir);
+ 
+   if (GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_YES))
 -    GNUNET_DISK_directory_remove(room_dir);
++    GNUNET_DISK_directory_remove (room_dir);
+ 
 -  GNUNET_free(room_dir);
++  GNUNET_free (room_dir);
+ }
+ 
++
+ static void
+ remove_room_member_session (struct GNUNET_MESSENGER_SrvRoom *room,
+                             struct GNUNET_MESSENGER_MemberSession *session)
+ {
+   GNUNET_assert ((room) && (session));
+ 
+   remove_member_session (session->member, session);
+ 
 -  const struct GNUNET_CRYPTO_PublicKey *public_key = 
get_member_session_public_key(session);
++  const struct GNUNET_CRYPTO_PublicKey *public_key =
++    get_member_session_public_key (session);
+ 
+   struct GNUNET_HashCode hash;
 -  GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash);
++  GNUNET_CRYPTO_hash (public_key, sizeof(*public_key), &hash);
+ 
+   char *room_dir;
+   get_room_data_subdir (room, &room_dir);
+ 
 -  char* session_dir;
++  char *session_dir;
+   GNUNET_asprintf (
 -      &session_dir, "%s%s%c%s%c%s%c%s%c", room_dir,
 -      "members", DIR_SEPARATOR,
 -      GNUNET_sh2s(get_member_session_id(session)), DIR_SEPARATOR,
 -      "sessions", DIR_SEPARATOR,
 -      GNUNET_h2s(&hash), DIR_SEPARATOR
 -  );
++    &session_dir, "%s%s%c%s%c%s%c%s%c", room_dir,
++    "members", DIR_SEPARATOR,
++    GNUNET_sh2s (get_member_session_id (session)), DIR_SEPARATOR,
++    "sessions", DIR_SEPARATOR,
++    GNUNET_h2s (&hash), DIR_SEPARATOR
++    );
+ 
+   GNUNET_free (room_dir);
+ 
 -  GNUNET_DISK_directory_remove(session_dir);
++  GNUNET_DISK_directory_remove (session_dir);
+   GNUNET_free (session_dir);
+ 
 -  destroy_member_session(session);
++  destroy_member_session (session);
+ }
diff --cc src/service/messenger/gnunet-service-messenger_room.h
index 000000000,fb2a88aea..e3e561d8b
mode 000000,100644..100644
--- a/src/service/messenger/gnunet-service-messenger_room.h
+++ b/src/service/messenger/gnunet-service-messenger_room.h
@@@ -1,0 -1,378 +1,389 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2022 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_room.h
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_SERVICE_MESSENGER_ROOM_H
+ #define GNUNET_SERVICE_MESSENGER_ROOM_H
+ 
+ #include "platform.h"
+ #include "gnunet_cadet_service.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ 
+ #include "gnunet_messenger_service.h"
+ #include "gnunet-service-messenger_basement.h"
+ #include "gnunet-service-messenger_handle.h"
+ #include "gnunet-service-messenger_message_state.h"
+ #include "gnunet-service-messenger_list_messages.h"
+ 
+ #include "messenger_api_list_tunnels.h"
++#include "messenger_api_peer_store.h"
+ 
+ #include "gnunet-service-messenger_member_store.h"
+ #include "gnunet-service-messenger_message_store.h"
+ #include "gnunet-service-messenger_operation_store.h"
 -#include "messenger_api_ego.h"
+ 
+ #define GNUNET_MESSENGER_IDLE_DELAY GNUNET_TIME_relative_multiply \
 -  (GNUNET_TIME_relative_get_second_ (), 5)
++          (GNUNET_TIME_relative_get_second_ (), 5)
+ 
+ #define GNUNET_MESSENGER_REQUEST_DELAY GNUNET_TIME_relative_multiply \
 -  (GNUNET_TIME_relative_get_minute_ (), 5)
++          (GNUNET_TIME_relative_get_minute_ (), 5)
+ 
+ #define GNUNET_MESSENGER_MERGE_DELAY GNUNET_TIME_relative_multiply \
 -  (GNUNET_TIME_relative_get_second_ (), 30)
++          (GNUNET_TIME_relative_get_second_ (), 30)
+ 
+ struct GNUNET_MESSENGER_SrvTunnel;
+ struct GNUNET_MESSENGER_MemberSession;
+ 
+ struct GNUNET_MESSENGER_SrvRoom
+ {
+   struct GNUNET_MESSENGER_Service *service;
+   struct GNUNET_MESSENGER_SrvHandle *host;
+   struct GNUNET_CADET_Port *port;
+ 
+   struct GNUNET_HashCode key;
+ 
+   struct GNUNET_CONTAINER_MultiPeerMap *tunnels;
+ 
++  struct GNUNET_MESSENGER_PeerStore peer_store;
+   struct GNUNET_MESSENGER_MemberStore member_store;
+   struct GNUNET_MESSENGER_MessageStore message_store;
+   struct GNUNET_MESSENGER_OperationStore operation_store;
+ 
+   struct GNUNET_MESSENGER_ListTunnels basement;
+   struct GNUNET_MESSENGER_MessageState state;
+ 
+   struct GNUNET_HashCode *peer_message;
+ 
+   struct GNUNET_MESSENGER_ListMessages handling;
+   struct GNUNET_SCHEDULER_Task *idle;
+ };
+ 
+ /**
+  * Creates and allocates a new room for a <i>handle</i> with a given 
<i>key</i>.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] key Key of room
+  * @return New room
+  */
+ struct GNUNET_MESSENGER_SrvRoom*
+ create_srv_room (struct GNUNET_MESSENGER_SrvHandle *handle,
 -             const struct GNUNET_HashCode *key);
++                 const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Destroys a room and frees its memory fully.
+  *
+  * The <i>deletion</i> flag should only be set to #GNUNET_YES if the
+  * room gets dropped by the service, otherwise #GNUNET_NO.
+  *
+  * @param[in,out] room Room
+  * @param[in] deletion Flag to indicate context of destruction
+  */
+ void
+ destroy_srv_room (struct GNUNET_MESSENGER_SrvRoom *room,
 -              int deletion);
++                  int deletion);
++
++/**
++ * Returns the used peer store of a given <i>room</i>.
++ *
++ * @param[in,out] room Room
++ * @return Peer store
++ */
++struct GNUNET_MESSENGER_PeerStore*
++get_srv_room_peer_store (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Returns the used member store of a given <i>room</i>.
+  *
+  * @param[in,out] room Room
+  * @return Member store
+  */
+ struct GNUNET_MESSENGER_MemberStore*
+ get_srv_room_member_store (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Returns the used message store of a given <i>room</i>.
+  *
+  * @param[in,out] room Room
+  * @return Message store
+  */
+ struct GNUNET_MESSENGER_MessageStore*
+ get_srv_room_message_store (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Returns the used operation store of a given <i>room</i>.
+  *
+  * @param[in,out] room Room
+  * @return Operation store
+  */
+ struct GNUNET_MESSENGER_OperationStore*
+ get_srv_room_operation_store (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Tries to open a <i>room</i> for a given <i>handle</i>. If the room has 
already been opened, the handle
+  * will locally join the room.
+  *
+  * Calling this method should result in joining a room and sending a peer 
message as well for this peer.
+  *
+  * If the function returns #GNUNET_YES the port for this room is guaranteed 
to be open for incoming connections.
+  *
+  * @param[in,out] room Room
+  * @param[in,out] handle Handle
+  * @return #GNUNET_YES on success, #GNUNET_NO on failure.
+  */
+ int
+ open_srv_room (struct GNUNET_MESSENGER_SrvRoom *room,
+                struct GNUNET_MESSENGER_SrvHandle *handle);
+ 
+ /**
+  * Connects a tunnel to a hosting peer of a <i>room</i> through a so called 
<i>door</i> which is represented by
+  * a peer identity of a hosting peer. During the connection the handle will 
join the room as a member, waiting for
+  * an info message from the selected host.
+  *
+  * @param[in,out] room Room
+  * @param[in,out] handle Handle
+  * @param[in] door Peer identity
+  * @return #GNUNET_YES on success, #GNUNET_NO on failure.
+  */
+ int
+ enter_srv_room_at (struct GNUNET_MESSENGER_SrvRoom *room,
+                    struct GNUNET_MESSENGER_SrvHandle *handle,
+                    const struct GNUNET_PeerIdentity *door);
+ 
+ /**
+  * Packs a <i>message</i> depending on the selected <i>mode</i> into a newly 
allocated envelope. It will set the
+  * timestamp of the message, the sender id and the previous messages hash 
automatically before packing. The message
+  * will be signed by the handles EGO.
+  *
+  * If the optional <i>hash</i> parameter is a valid pointer, its value will 
be overridden by the signed messages hash.
+  *
+  * If <i>mode</i> is set to #GNUNET_MESSENGER_PACK_MODE_ENVELOPE, the 
function returns a valid envelope to send
+  * through a message queue, otherwise NULL.
+  *
+  * @param[in] room Room
+  * @param[in] handle Handle
+  * @param[in,out] message Message
+  * @param[out] hash Hash of message
+  * @param[in] mode Packing mode
+  * @return New envelope or NULL
+  */
+ struct GNUNET_MQ_Envelope*
+ pack_srv_room_message (const struct GNUNET_MESSENGER_SrvRoom *room,
+                        const struct GNUNET_MESSENGER_SrvHandle *handle,
+                        struct GNUNET_MESSENGER_Message *message,
+                        struct GNUNET_HashCode *hash,
+                        int mode);
+ 
+ /**
+  * Sends a <i>message</i> from a given <i>handle</i> into a <i>room</i>. The 
<i>hash</i> parameter will be
+  * updated with the hash-value resulting from the sent message.
+  *
+  * The function handles packing the message automatically and will call 
linked message-events locally even if
+  * the message won't be sent to another peer.
+  *
+  * The function returns #GNUNET_YES on success, #GNUNET_NO if message is null 
and
+  * #GNUNET_SYSERR if the message was known already.
+  *
+  * @param[in,out] room Room
+  * @param[in,out] handle Handle
+  * @param[in,out] message Message
+  * @return #GNUNET_YES on success, #GNUNET_NO or #GNUNET_SYSERR otherwise.
+  */
+ int
+ send_srv_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                        struct GNUNET_MESSENGER_SrvHandle *handle,
+                        struct GNUNET_MESSENGER_Message *message);
+ 
+ /**
+  * Forwards a <i>message</i> with a given <i>hash</i> to a specific 
<i>tunnel</i> inside of a <i>room</i>.
+  *
+  * @param[in,out] room Room
+  * @param[in,out] tunnel Tunnel
+  * @param[in,out] message Message
+  * @param[in] hash Hash of message
+  */
+ void
+ forward_srv_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                           struct GNUNET_MESSENGER_SrvTunnel *tunnel,
+                           struct GNUNET_MESSENGER_Message *message,
+                           const struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Checks the current state of opening a given <i>room</i> from this peer and 
re-publishes it
+  * if necessary to a selected <i>tunnel</i> or to all connected tunnels if 
necessary or if the
+  * selected tunnel is NULL.
+  *
+  * @param[in,out] room Room
+  * @param[in,out] tunnel Tunnel
+  */
+ void
+ check_srv_room_peer_status (struct GNUNET_MESSENGER_SrvRoom *room,
+                             struct GNUNET_MESSENGER_SrvTunnel *tunnel);
+ 
+ /**
+  * Reduces all current forks inside of the message history of a <i>room</i> 
to one remaining last message
+  * by merging them down. All merge messages will be sent from a given 
<i>handle</i>.
+  *
+  * @param[in,out] room Room
+  * @param[in,out] handle Handle
+  */
+ void
+ merge_srv_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room,
+                               struct GNUNET_MESSENGER_SrvHandle *handle);
+ 
+ /**
+  * Deletes a message from the <i>room</i> with a given <i>hash</i> in a 
specific <i>delay</i> if
+  * the provided member by its session is permitted to do so.
+  *
+  * @param[in,out] room Room
+  * @param[in,out] session Member session
+  * @param[in] hash Hash of message
+  * @param[in] delay Delay of deletion
+  * @return #GNUNET_YES on success, #GNUNET_NO if permission gets denied, 
#GNUNET_SYSERR on operation failure
+  */
+ int
+ delete_srv_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                          struct GNUNET_MESSENGER_MemberSession *session,
+                          const struct GNUNET_HashCode *hash,
+                          const struct GNUNET_TIME_Relative delay);
+ 
+ /**
+  * Returns the CADET handle from a rooms service.
+  *
+  * @param[in,out] room Room
+  * @return CADET handle
+  */
+ struct GNUNET_CADET_Handle*
+ get_srv_room_cadet (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Returns the shared secret you need to access a <i>room</i>.
+  *
+  * @param[in] room Room
+  * @return Shared secret
+  */
+ const struct GNUNET_HashCode*
+ get_srv_room_key (const struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Returns a tunnel inside of a <i>room</i> leading towards a given 
<i>peer</i> if such a tunnel exists,
+  * otherwise NULL.
+  *
+  * @param[in] room Room
+  * @param[in] peer Peer identity
+  * @return Tunnel or NULL
+  */
+ const struct GNUNET_MESSENGER_SrvTunnel*
+ get_srv_room_tunnel (const struct GNUNET_MESSENGER_SrvRoom *room,
+                      const struct GNUNET_PeerIdentity *peer);
+ 
+ /**
+  * Method called whenever a <i>message</i> is found during a request in a 
<i>room</i>.
+  *
+  * @param[in,out] cls Closure from #request_room_message
+  * @param[in,out] room Room
+  * @param[in] message Message or NULL
+  * @param[in] hash Hash of message
+  */
+ typedef void (GNUNET_MESSENGER_MessageRequestCallback) (
 -    void *cls,
 -    struct GNUNET_MESSENGER_SrvRoom *room,
 -    const struct GNUNET_MESSENGER_Message *message,
 -    const struct GNUNET_HashCode *hash
 -);
++  void *cls,
++  struct GNUNET_MESSENGER_SrvRoom *room,
++  const struct GNUNET_MESSENGER_Message *message,
++  const struct GNUNET_HashCode *hash
++  );
+ 
+ /**
+  * Requests a message from a <i>room</i> identified by a given <i>hash</i>. 
If the message is found,
+  * the selected <i>callback</i> will be called with it and the provided 
closure. If no matching message
+  * is found but it wasn't deleted the selected callback will be called with 
#NULL as message instead.
+  * In case of deletion the next available previous message will be used to 
call the callback.
+  *
+  * It is also possible that the given callback will not be called if the 
requesting session is not
+  * permitted!
+  *
+  * @param[in,out] room Room
+  * @param[in] hash Hash of message
+  * @param[in] callback Callback to process result
+  * @param[in] cls Closure for the <i>callback</i>
+  * @return #GNUNET_YES if the request could be processed, otherwise #GNUNET_NO
+  */
+ int
+ request_srv_room_message (struct GNUNET_MESSENGER_SrvRoom *room,
+                           const struct GNUNET_HashCode *hash,
+                           const struct GNUNET_MESSENGER_MemberSession 
*session,
+                           GNUNET_MESSENGER_MessageRequestCallback callback,
 -                          void* cls);
++                          void *cls);
+ 
+ /**
+  * Checks for potential collisions with member ids and solves them changing 
active handles ids if they
+  * use an already used member id (comparing public key and timestamp).
+  *
+  * @param[in,out] room Room
+  * @param[in] public_key Public key of EGO
+  * @param[in] member_id Member ID
+  * @param[in] timestamp Timestamp
+  */
+ void
+ solve_srv_room_member_collisions (struct GNUNET_MESSENGER_SrvRoom *room,
 -                                  const struct GNUNET_CRYPTO_PublicKey 
*public_key,
++                                  const struct
++                                  GNUNET_CRYPTO_PublicKey *public_key,
+                                   const struct GNUNET_ShortHashCode 
*member_id,
+                                   struct GNUNET_TIME_Absolute timestamp);
+ 
+ /**
+  * Rebuilds the decentralized structure for a <i>room</i> by ensuring all 
required connections are made
+  * depending on the amount of peers and this peers index in the list of them.
+  *
+  * @param[in,out] room Room
+  */
+ void
+ rebuild_srv_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Loads the local configuration for a given <i>room</i> of a service which 
contains the last messages hash
+  * and the ruleset for general access of new members.
+  *
+  * @param[out] room Room
+  */
+ void
+ load_srv_room (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Saves the configuration for a given <i>room</i> of a service which 
contains the last messages hash
+  * and the ruleset for general access of new members locally.
+  *
+  * @param[in] room Room
+  */
+ void
+ save_srv_room (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ /**
+  * Removes the configuration for a given <i>room</i> of a service.
+  *
+  * @param[in] room Room
+  */
+ void
+ remove_srv_room (struct GNUNET_MESSENGER_SrvRoom *room);
+ 
+ #endif //GNUNET_SERVICE_MESSENGER_ROOM_H
diff --cc src/service/messenger/meson.build
index 000000000,3c05d7760..f6d63bc6c
mode 000000,100644..100644
--- a/src/service/messenger/meson.build
+++ b/src/service/messenger/meson.build
@@@ -1,0 -1,67 +1,69 @@@
+ libgnunetmessenger_src = ['messenger_api.c',
+                           'messenger_api_contact.c',
+                           'messenger_api_contact_store.c',
++                          'messenger_api_peer_store.c',
+                           'messenger_api_message.c',
++                          'messenger_api_message_kind.c',
+                           'messenger_api_list_tunnels.c',
++                          'messenger_api_queue_messages.c',
+                           'messenger_api_util.c',
+                           'messenger_api_handle.c',
+                           'messenger_api_room.c']
+ 
+ gnunetservicemessenger_src = ['gnunet-service-messenger.c',
+                               'gnunet-service-messenger_service.c',
+                               'gnunet-service-messenger_list_handles.c',
+                               'gnunet-service-messenger_list_messages.c',
+                               'gnunet-service-messenger_member_session.c',
+                               'gnunet-service-messenger_member.c',
+                               'gnunet-service-messenger_member_store.c',
+                               'gnunet-service-messenger_message_handle.c',
+                               'gnunet-service-messenger_message_kind.c',
+                               'gnunet-service-messenger_message_recv.c',
+                               'gnunet-service-messenger_message_send.c',
+                               'gnunet-service-messenger_message_state.c',
+                               'gnunet-service-messenger_message_store.c',
+                               'gnunet-service-messenger_operation_store.c',
+                               'gnunet-service-messenger_operation.c',
+                               'gnunet-service-messenger_basement.c',
 -                              'gnunet-service-messenger_ego_store.c',
+                               'gnunet-service-messenger_handle.c',
+                               'gnunet-service-messenger_room.c',
+                               'gnunet-service-messenger_tunnel.c']
+ 
+ configure_file(input : 'messenger.conf.in',
+                output : 'messenger.conf',
+                configuration : cdata,
+                install: true,
+                install_dir: pkgcfgdir)
+ 
+ 
+ if get_option('monolith')
+   foreach p : libgnunetmessenger_src + gnunetservicemessenger_src
+     gnunet_src += 'messenger/' + p
+   endforeach
+ endif
+ 
+ libgnunetmessenger = library('gnunetmessenger',
+         libgnunetmessenger_src,
+         soversion: '0',
+         version: '0.0.0',
+         dependencies: [libgnunetutil_dep,
+                        libgnunetcadet_dep,
+                        libgnunetidentity_dep],
+         include_directories: [incdir, configuration_inc],
+         install: true,
+         install_dir: get_option('libdir'))
+ libgnunetmessenger_dep = declare_dependency(link_with : libgnunetmessenger)
+ pkg.generate(libgnunetmessenger, url: 'https://www.gnunet.org',
+              description : 'Provides API to access the GNUnet Messenger 
subsystem')
+ 
+ executable ('gnunet-service-messenger',
+             gnunetservicemessenger_src,
+             dependencies: [libgnunetmessenger_dep,
+                            libgnunetutil_dep,
+                            libgnunetidentity_dep,
+                            libgnunetcadet_dep],
+             include_directories: [incdir, configuration_inc],
+             install: true,
+             install_dir: get_option('libdir') / 'gnunet' / 'libexec')
+ 
diff --cc src/service/messenger/messenger_api.c
index 000000000,3604d0569..a5b2d7687
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api.c
+++ b/src/service/messenger/messenger_api.c
@@@ -1,0 -1,801 +1,1075 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api.c
+  * @brief messenger api: client implementation of GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
++#include "gnunet_identity_service.h"
+ #include "gnunet_messenger_service.h"
+ 
+ #include "gnunet-service-messenger.h"
+ 
+ #include "messenger_api_handle.h"
+ #include "messenger_api_message.h"
++#include "messenger_api_message_kind.h"
++#include "messenger_api_room.h"
+ #include "messenger_api_util.h"
+ 
+ const char*
+ GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind)
+ {
+   switch (kind)
+   {
+   case GNUNET_MESSENGER_KIND_INFO:
+     return "INFO";
+   case GNUNET_MESSENGER_KIND_JOIN:
+     return "JOIN";
+   case GNUNET_MESSENGER_KIND_LEAVE:
+     return "LEAVE";
+   case GNUNET_MESSENGER_KIND_NAME:
+     return "NAME";
+   case GNUNET_MESSENGER_KIND_KEY:
+     return "KEY";
+   case GNUNET_MESSENGER_KIND_PEER:
+     return "PEER";
+   case GNUNET_MESSENGER_KIND_ID:
+     return "ID";
+   case GNUNET_MESSENGER_KIND_MISS:
+     return "MISS";
+   case GNUNET_MESSENGER_KIND_MERGE:
+     return "MERGE";
+   case GNUNET_MESSENGER_KIND_REQUEST:
+     return "REQUEST";
+   case GNUNET_MESSENGER_KIND_INVITE:
+     return "INVITE";
+   case GNUNET_MESSENGER_KIND_TEXT:
+     return "TEXT";
+   case GNUNET_MESSENGER_KIND_FILE:
+     return "FILE";
+   case GNUNET_MESSENGER_KIND_PRIVATE:
+     return "PRIVATE";
+   case GNUNET_MESSENGER_KIND_DELETE:
+     return "DELETE";
+   default:
+     return "UNKNOWN";
+   }
+ }
+ 
 -static int
 -check_get_name (void *cls,
 -                const struct GNUNET_MESSENGER_NameMessage *msg)
 -{
 -  GNUNET_MQ_check_zero_termination(msg);
 -  return GNUNET_OK;
 -}
++
++static enum GNUNET_GenericReturnValue
++dequeue_messages_from_room (struct GNUNET_MESSENGER_Room *room);
+ 
+ static void
 -handle_get_name (void *cls,
 -                 const struct GNUNET_MESSENGER_NameMessage *msg)
++handle_room_open (void *cls,
++                  const struct GNUNET_MESSENGER_RoomMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+ 
 -  const char *name = ((const char*) msg) + sizeof(*msg);
 -
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set name of handle: %s\n", name);
 -
 -  set_handle_name (handle, strlen (name) > 0 ? name : NULL);
 -}
 -
 -static int
 -check_get_key (void *cls,
 -               const struct GNUNET_MESSENGER_KeyMessage *msg)
 -{
 -  const uint16_t full_length = ntohs (msg->header.size);
++  const struct GNUNET_HashCode *key = &(msg->key);
+ 
 -  if (full_length < sizeof(*msg))
 -    return GNUNET_NO;
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Opened room: %s\n", GNUNET_h2s (key));
+ 
 -  const uint16_t length = full_length - sizeof(*msg);
 -  const char *buffer = ((const char*) msg) + sizeof(*msg);
++  open_handle_room (handle, key);
+ 
 -  struct GNUNET_CRYPTO_PublicKey pubkey;
 -  size_t read;
 -  if (GNUNET_SYSERR ==
 -      GNUNET_CRYPTO_read_public_key_from_buffer(buffer, length,
 -                                                  &pubkey, &read))
 -    return GNUNET_NO;
++  struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key);
+ 
 -  return GNUNET_OK;
++  if (room)
++    dequeue_messages_from_room (room);
+ }
+ 
++
+ static void
 -handle_get_key (void *cls,
 -                const struct GNUNET_MESSENGER_KeyMessage *msg)
++handle_room_entry (void *cls,
++                   const struct GNUNET_MESSENGER_RoomMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+ 
 -  const uint16_t length = ntohs (msg->header.size) - sizeof(*msg);
 -  const char *buffer = ((const char*) msg) + sizeof(*msg);
++  const struct GNUNET_PeerIdentity *door = &(msg->door);
++  const struct GNUNET_HashCode *key = &(msg->key);
+ 
 -  struct GNUNET_CRYPTO_PublicKey pubkey;
 -  size_t read;
 -  if (GNUNET_SYSERR ==
 -      GNUNET_CRYPTO_read_public_key_from_buffer(buffer, length,
 -                                                  &pubkey, &read))
 -    return;
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered room: %s\n", GNUNET_h2s 
(key));
+ 
 -  char* str = GNUNET_CRYPTO_public_key_to_string (&pubkey);
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set key of handle: %s\n", str);
 -  GNUNET_free(str);
++  entry_handle_room_at (handle, door, key);
+ 
 -  set_handle_key (handle, &pubkey);
++  struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key);
+ 
 -  if (handle->identity_callback)
 -    handle->identity_callback (handle->identity_cls, handle);
++  if (room)
++    dequeue_messages_from_room (room);
+ }
+ 
++
+ static void
 -handle_member_id (void *cls,
 -                  const struct GNUNET_MESSENGER_MemberMessage *msg)
++handle_room_close (void *cls,
++                   const struct GNUNET_MESSENGER_RoomMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+ 
+   const struct GNUNET_HashCode *key = &(msg->key);
 -  const struct GNUNET_ShortHashCode *id = &(msg->id);
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set id of handle in room: %s\n", 
GNUNET_h2s (key));
 -
 -  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get 
(handle->rooms, key);
++  struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key);
+ 
+   if (room)
 -  {
 -    if (!room->contact_id)
 -      room->contact_id = GNUNET_new(struct GNUNET_ShortHashCode);
 -
 -    GNUNET_memcpy(room->contact_id, id, sizeof(*id));
 -  }
 -}
++    dequeue_messages_from_room (room);
+ 
 -static void
 -handle_room_open (void *cls,
 -                  const struct GNUNET_MESSENGER_RoomMessage *msg)
 -{
 -  struct GNUNET_MESSENGER_Handle *handle = cls;
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key));
+ 
 -  const struct GNUNET_HashCode *key = &(msg->key);
++  close_handle_room (handle, key);
++}
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opened room: %s\n", GNUNET_h2s (key));
+ 
 -  open_handle_room (handle, key);
 -}
++static void
++enqueue_message_to_room (struct GNUNET_MESSENGER_Room *room,
++                         struct GNUNET_MESSENGER_Message *message);
+ 
+ static void
 -handle_room_entry (void *cls,
 -                   const struct GNUNET_MESSENGER_RoomMessage *msg)
++handle_member_id (void *cls,
++                  const struct GNUNET_MESSENGER_MemberMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+ 
 -  const struct GNUNET_PeerIdentity *door = &(msg->door);
+   const struct GNUNET_HashCode *key = &(msg->key);
++  const struct GNUNET_ShortHashCode *id = &(msg->id);
++  const uint32_t reset = msg->reset;
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entered room: %s\n", GNUNET_h2s (key));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Changed member id in room: %s\n",
++              GNUNET_h2s (key));
+ 
 -  entry_handle_room_at (handle, door, key);
 -}
++  struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key);
+ 
 -static void
 -handle_room_close (void *cls,
 -                   const struct GNUNET_MESSENGER_RoomMessage *msg)
 -{
 -  struct GNUNET_MESSENGER_Handle *handle = cls;
++  if (! room)
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Room is unknown to handle: %s\n",
++                GNUNET_h2s (key));
++    return;
++  }
+ 
 -  const struct GNUNET_HashCode *key = &(msg->key);
++  struct GNUNET_MESSENGER_Message *message;
++  switch (reset)
++  {
++  case GNUNET_YES:
++    set_room_sender_id (room, id);
++    message = create_message_join (get_handle_key (handle));
++    break;
++  case GNUNET_NO:
++    message = create_message_id (id);
++    break;
++  default:
++    break;
++  }
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key));
++  if (! message)
++    return;
+ 
 -  close_handle_room (handle, key);
++  enqueue_message_to_room (room, message);
++  destroy_message (message);
+ }
+ 
++
+ static int
+ check_recv_message (void *cls,
+                     const struct GNUNET_MESSENGER_RecvMessage *msg)
+ {
+   const uint16_t full_length = ntohs (msg->header.size);
+ 
+   if (full_length < sizeof(*msg))
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Receiving failed: Message invalid!\n");
+     return GNUNET_NO;
++  }
+ 
+   const uint16_t length = full_length - sizeof(*msg);
+   const char *buffer = ((const char*) msg) + sizeof(*msg);
+ 
+   struct GNUNET_MESSENGER_Message message;
+ 
 -  if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, 
GNUNET_YES))
++  if (length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN,
++                                      GNUNET_YES))
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Receiving failed: Message too short!\n");
+     return GNUNET_NO;
++  }
+ 
+   if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, 
NULL))
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Receiving failed: Message decoding failed!\n");
+     return GNUNET_NO;
++  }
+ 
 -  cleanup_message(&message);
++  cleanup_message (&message);
+   return GNUNET_OK;
+ }
+ 
++
+ static void
+ handle_recv_message (void *cls,
+                      const struct GNUNET_MESSENGER_RecvMessage *msg)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+ 
+   const struct GNUNET_HashCode *key = &(msg->key);
+   const struct GNUNET_HashCode *sender = &(msg->sender);
+   const struct GNUNET_HashCode *context = &(msg->context);
+   const struct GNUNET_HashCode *hash = &(msg->hash);
 -  const enum GNUNET_MESSENGER_MessageFlags flags = (
 -      (enum GNUNET_MESSENGER_MessageFlags) (msg->flags)
 -  );
++
++  enum GNUNET_MESSENGER_MessageFlags flags = (
++    (enum GNUNET_MESSENGER_MessageFlags) (msg->flags)
++    );
+ 
+   const uint16_t length = ntohs (msg->header.size) - sizeof(*msg);
+   const char *buffer = ((const char*) msg) + sizeof(*msg);
+ 
+   struct GNUNET_MESSENGER_Message message;
+   decode_message (&message, length, buffer, GNUNET_YES, NULL);
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", 
GNUNET_MESSENGER_name_of_kind (message.header.kind));
++  struct GNUNET_MESSENGER_Message *private_message = NULL;
++  if (GNUNET_MESSENGER_KIND_PRIVATE == message.header.kind)
++  {
++    private_message = copy_message (&message);
++
++    if (GNUNET_YES != decrypt_message (private_message, get_handle_key (
++                                         handle)))
++    {
++      destroy_message (private_message);
++      private_message = NULL;
++    }
++  }
+ 
 -  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get 
(handle->rooms, key);
++  if (private_message)
++    flags |= GNUNET_MESSENGER_FLAG_PRIVATE;
++
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n",
++              GNUNET_MESSENGER_name_of_kind (private_message ?
++                                             private_message->header.kind :
++                                             message.header.kind));
++
++  struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key);
+ 
+   if (room)
+   {
 -    struct GNUNET_MESSENGER_ContactStore *store = 
get_handle_contact_store(handle);
++    struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store (
++      handle);
+ 
 -    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Raw contact from sender and context: 
(%s : %s)\n",
 -               GNUNET_h2s(sender), GNUNET_h2s_full(context));
++    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++                "Raw contact from sender and context: (%s : %s)\n",
++                GNUNET_h2s (sender), GNUNET_h2s_full (context));
+ 
 -    struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw(
 -        store, context, sender
 -    );
++    struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw (
++      store, context, sender
++      );
+ 
 -    contact = handle_room_message (room, contact, &message, hash);
++    contact = handle_room_message (room, contact, private_message ?
++                                   private_message : &message, hash, flags);
+ 
 -    const struct GNUNET_MESSENGER_Message *stored_message = 
get_room_message(room, hash);
++    const struct GNUNET_MESSENGER_Message *stored_message = get_room_message (
++      room, hash);
+ 
+     if (handle->msg_callback)
 -      handle->msg_callback (handle->msg_cls, room, contact, stored_message, 
hash, flags);
++      handle->msg_callback (handle->msg_cls, room, contact, stored_message,
++                            hash, flags);
+   }
+   else
 -    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Unknown room for this client: %s\n", 
GNUNET_h2s (key));
++    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Unknown room for this client: %s\n",
++                GNUNET_h2s (key));
++
++  cleanup_message (&message);
++
++  if (private_message)
++    destroy_message (private_message);
++}
++
++
++static void
++handle_miss_message (void *cls,
++                     const struct GNUNET_MESSENGER_GetMessage *msg)
++{
++  struct GNUNET_MESSENGER_Handle *handle = cls;
++
++  const struct GNUNET_HashCode *key = &(msg->key);
++  const struct GNUNET_HashCode *hash = &(msg->hash);
++
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Missing message in room: %s\n",
++              GNUNET_h2s (hash));
++
++  struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key);
++
++  if (! room)
++  {
++    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++                "Miss in unknown room for this client: %s\n", GNUNET_h2s 
(key));
++    return;
++  }
++
++  if (! get_room_sender_id (room))
++    return;
+ 
 -  cleanup_message(&message);
++  struct GNUNET_MESSENGER_Message *message = create_message_request (hash);
++  if (! message)
++    return;
++
++  enqueue_message_to_room (room, message);
++  destroy_message (message);
+ }
+ 
++
+ static void
+ reconnect (struct GNUNET_MESSENGER_Handle *handle);
+ 
+ static void
+ send_open_room (struct GNUNET_MESSENGER_Handle *handle,
+                 struct GNUNET_MESSENGER_Room *room)
+ {
++  const struct GNUNET_CRYPTO_PublicKey *key = get_handle_pubkey (handle);
++
+   struct GNUNET_MESSENGER_RoomMessage *msg;
+   struct GNUNET_MQ_Envelope *env;
+ 
 -  env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN);
 -  GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Open room (%s) by member using key: %s\n",
++              GNUNET_h2s (&(room->key)),
++              GNUNET_CRYPTO_public_key_to_string (key));
++
++  const ssize_t len = GNUNET_CRYPTO_public_key_get_length (key);
++
++  env = GNUNET_MQ_msg_extra (msg, len > 0 ? len : 0,
++                             GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN);
++  GNUNET_memcpy (&(msg->key), &(room->key), sizeof(msg->key));
++
++  char *msg_buffer = ((char*) msg) + sizeof(*msg);
++
++  if (len > 0)
++    GNUNET_CRYPTO_write_public_key_to_buffer (key, msg_buffer, len);
++
+   GNUNET_MQ_send (handle->mq, env);
+ }
+ 
++
+ static void
+ send_enter_room (struct GNUNET_MESSENGER_Handle *handle,
+                  struct GNUNET_MESSENGER_Room *room,
+                  const struct GNUNET_PeerIdentity *door)
+ {
++  const struct GNUNET_CRYPTO_PublicKey *key = get_handle_pubkey (handle);
++
+   struct GNUNET_MESSENGER_RoomMessage *msg;
+   struct GNUNET_MQ_Envelope *env;
+ 
 -  env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY);
 -  GNUNET_memcpy(&(msg->door), door, sizeof(*door));
 -  GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Enter room (%s) via door: %s (%s)\n",
++              GNUNET_h2s (&(room->key)),
++              GNUNET_i2s (door),
++              GNUNET_CRYPTO_public_key_to_string (key));
++
++  const ssize_t len = GNUNET_CRYPTO_public_key_get_length (key);
++
++  env = GNUNET_MQ_msg_extra (msg, len > 0 ? len : 0,
++                             GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY);
++  GNUNET_memcpy (&(msg->door), door, sizeof(*door));
++  GNUNET_memcpy (&(msg->key), &(room->key), sizeof(msg->key));
++
++  char *msg_buffer = ((char*) msg) + sizeof(*msg);
++
++  if (len > 0)
++    GNUNET_CRYPTO_write_public_key_to_buffer (key, msg_buffer, len);
++
+   GNUNET_MQ_send (handle->mq, env);
+ }
+ 
++
+ static void
+ send_close_room (struct GNUNET_MESSENGER_Handle *handle,
+                  struct GNUNET_MESSENGER_Room *room)
+ {
+   struct GNUNET_MESSENGER_RoomMessage *msg;
+   struct GNUNET_MQ_Envelope *env;
+ 
 -  env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE);
 -  GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Close room (%s)!\n",
++              GNUNET_h2s (&(room->key)));
++
++  env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE);
++  GNUNET_memcpy (&(msg->key), &(room->key), sizeof(msg->key));
+   GNUNET_MQ_send (handle->mq, env);
+ }
+ 
++
+ static int
+ iterate_reset_room (void *cls,
+                     const struct GNUNET_HashCode *key,
+                     void *value)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+   struct GNUNET_MESSENGER_Room *room = value;
+ 
+   if (GNUNET_YES == room->opened)
+     send_open_room (handle, room);
+ 
+   struct GNUNET_MESSENGER_ListTunnel *entry = room->entries.head;
+ 
+   struct GNUNET_PeerIdentity door;
+ 
+   while (entry)
+   {
+     GNUNET_PEER_resolve (entry->peer, &door);
+ 
+     send_enter_room (handle, room, &door);
+ 
+     entry = entry->next;
+   }
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ static void
+ callback_reconnect (void *cls)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+ 
+   handle->reconnect_task = NULL;
 -  handle->reconnect_time = GNUNET_TIME_STD_BACKOFF(handle->reconnect_time)
 -  ;
++  handle->reconnect_time = GNUNET_TIME_STD_BACKOFF (handle->reconnect_time);
++
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnect messenger!\n");
+ 
+   reconnect (handle);
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_reset_room, 
handle);
++  GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_reset_room,
++                                         handle);
+ }
+ 
++
+ static int
+ iterate_close_room (void *cls,
+                     const struct GNUNET_HashCode *key,
+                     void *value)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+   struct GNUNET_MESSENGER_Room *room = value;
+ 
+   send_close_room (handle, room);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ static void
+ callback_mq_error (void *cls,
+                    enum GNUNET_MQ_Error error)
+ {
+   struct GNUNET_MESSENGER_Handle *handle = cls;
+ 
 -  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "MQ_Error: %u\n", error);
++  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MQ_Error: %u\n", error);
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_close_room, 
handle);
++  GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_close_room,
++                                         handle);
+ 
+   if (handle->mq)
+   {
+     GNUNET_MQ_destroy (handle->mq);
+     handle->mq = NULL;
+   }
+ 
 -  handle->reconnect_task = GNUNET_SCHEDULER_add_delayed 
(handle->reconnect_time, &callback_reconnect, handle);
++  handle->reconnect_task = GNUNET_SCHEDULER_add_delayed 
(handle->reconnect_time,
++                                                         &callback_reconnect,
++                                                         handle);
+ }
+ 
++
+ static void
+ reconnect (struct GNUNET_MESSENGER_Handle *handle)
+ {
 -  const struct GNUNET_MQ_MessageHandler handlers[] =
 -  {
 -   GNUNET_MQ_hd_var_size(
 -        get_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME,
 -        struct GNUNET_MESSENGER_NameMessage, handle
 -   ),
 -   GNUNET_MQ_hd_var_size(
 -       get_key, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY,
 -       struct GNUNET_MESSENGER_KeyMessage, handle
 -   ),
 -   GNUNET_MQ_hd_fixed_size(
 -       member_id,
 -       GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID,
 -       struct GNUNET_MESSENGER_MemberMessage, handle
 -   ),
 -   GNUNET_MQ_hd_fixed_size(
 -       room_open,
 -       GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN,
 -       struct GNUNET_MESSENGER_RoomMessage, handle
 -   ),
 -   GNUNET_MQ_hd_fixed_size(
 -       room_entry,
 -       GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY,
 -       struct GNUNET_MESSENGER_RoomMessage, handle
 -   ),
 -   GNUNET_MQ_hd_fixed_size(
 -       room_close,
 -       GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE,
 -       struct GNUNET_MESSENGER_RoomMessage, handle
 -   ),
 -   GNUNET_MQ_hd_var_size(
 -       recv_message,
 -       GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE,
 -       struct GNUNET_MESSENGER_RecvMessage, handle
 -   ),
 -   GNUNET_MQ_handler_end()
++  const struct GNUNET_MQ_MessageHandler handlers[] = {
++    GNUNET_MQ_hd_fixed_size (
++      member_id,
++      GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID,
++      struct GNUNET_MESSENGER_MemberMessage, handle
++      ),
++    GNUNET_MQ_hd_fixed_size (
++      room_open,
++      GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN,
++      struct GNUNET_MESSENGER_RoomMessage, handle
++      ),
++    GNUNET_MQ_hd_fixed_size (
++      room_entry,
++      GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY,
++      struct GNUNET_MESSENGER_RoomMessage, handle
++      ),
++    GNUNET_MQ_hd_fixed_size (
++      room_close,
++      GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE,
++      struct GNUNET_MESSENGER_RoomMessage, handle
++      ),
++    GNUNET_MQ_hd_var_size (
++      recv_message,
++      GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE,
++      struct GNUNET_MESSENGER_RecvMessage, handle
++      ),
++    GNUNET_MQ_hd_fixed_size (
++      miss_message,
++      GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE,
++      struct GNUNET_MESSENGER_GetMessage, handle
++      ),
++    GNUNET_MQ_handler_end ()
+   };
+ 
 -  handle->mq = GNUNET_CLIENT_connect (handle->cfg, 
GNUNET_MESSENGER_SERVICE_NAME, handlers, &callback_mq_error, handle);
++  handle->mq = GNUNET_CLIENT_connect (handle->cfg,
++                                      GNUNET_MESSENGER_SERVICE_NAME, handlers,
++                                      &callback_mq_error, handle);
+ }
+ 
++
+ struct GNUNET_MESSENGER_Handle*
+ GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
+                           const char *name,
 -                          GNUNET_MESSENGER_IdentityCallback identity_callback,
 -                          void *identity_cls,
++                          const struct GNUNET_CRYPTO_PrivateKey *key,
+                           GNUNET_MESSENGER_MessageCallback msg_callback,
+                           void *msg_cls)
+ {
 -  struct GNUNET_MESSENGER_Handle *handle = create_handle (cfg, 
identity_callback, identity_cls, msg_callback, msg_cls);
++  struct GNUNET_MESSENGER_Handle *handle = create_handle (cfg, msg_callback,
++                                                          msg_cls);
+ 
+   reconnect (handle);
+ 
+   if (handle->mq)
+   {
 -    const uint16_t name_len = name ? strlen (name) : 0;
++    set_handle_name (handle, name);
++
++    if ((! key) || (0 < GNUNET_CRYPTO_private_key_get_length (key)))
++      set_handle_key (handle, key);
+ 
+     struct GNUNET_MESSENGER_CreateMessage *msg;
+     struct GNUNET_MQ_Envelope *env;
+ 
 -    env = GNUNET_MQ_msg_extra(msg, name_len + 1, 
GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE);
 -
 -    char *extra = ((char*) msg) + sizeof(*msg);
 -
 -    if (name_len)
 -      GNUNET_memcpy(extra, name, name_len);
 -
 -    extra[name_len] = '\0';
 -
++    env = GNUNET_MQ_msg (msg, 
GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE);
+     GNUNET_MQ_send (handle->mq, env);
+     return handle;
+   }
+   else
+   {
+     destroy_handle (handle);
+     return NULL;
+   }
+ }
+ 
 -int
 -GNUNET_MESSENGER_update (struct GNUNET_MESSENGER_Handle *handle)
 -{
 -  if ((!handle) || (!get_handle_name (handle)))
 -    return GNUNET_SYSERR;
 -
 -  struct GNUNET_MESSENGER_UpdateMessage *msg;
 -  struct GNUNET_MQ_Envelope *env;
 -
 -  env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE);
 -  GNUNET_MQ_send (handle->mq, env);
 -  return GNUNET_OK;
 -}
+ 
+ void
+ GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle)
+ {
 -  if (!handle)
++  if (! handle)
+     return;
+ 
+   struct GNUNET_MESSENGER_DestroyMessage *msg;
+   struct GNUNET_MQ_Envelope *env;
+ 
 -  env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY);
++  env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY);
+   GNUNET_MQ_send (handle->mq, env);
+ 
+   destroy_handle (handle);
+ }
+ 
++
++static void
++send_message_to_room (struct GNUNET_MESSENGER_Room *room,
++                      struct GNUNET_MESSENGER_Message *message,
++                      const struct GNUNET_CRYPTO_PrivateKey *key)
++{
++  const struct GNUNET_ShortHashCode *sender_id = get_room_sender_id (room);
++
++  message->header.timestamp = GNUNET_TIME_absolute_hton (
++    GNUNET_TIME_absolute_get ());
++
++  GNUNET_memcpy (&(message->header.sender_id), sender_id,
++                 sizeof(message->header.sender_id));
++  GNUNET_memcpy (&(message->header.previous), &(room->last_message),
++                 sizeof(message->header.previous));
++
++  message->header.signature.type = key->type;
++
++  const uint16_t msg_length = get_message_size (message, GNUNET_YES);
++
++  struct GNUNET_MESSENGER_SendMessage *msg;
++  struct GNUNET_MQ_Envelope *env;
++
++  env = GNUNET_MQ_msg_extra (
++    msg, msg_length,
++    GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE
++    );
++
++  GNUNET_memcpy (&(msg->key), &(room->key), sizeof(msg->key));
++
++  char *msg_buffer = ((char*) msg) + sizeof(*msg);
++  encode_message (message, msg_length, msg_buffer, GNUNET_YES);
++
++  struct GNUNET_HashCode hash;
++  hash_message (message, msg_length, msg_buffer, &hash);
++  sign_message (message, msg_length, msg_buffer, &hash, key);
++
++  GNUNET_memcpy (&(room->last_message), &hash, sizeof(room->last_message));
++
++  GNUNET_MQ_send (room->handle->mq, env);
++}
++
++
++static void
++enqueue_message_to_room (struct GNUNET_MESSENGER_Room *room,
++                         struct GNUNET_MESSENGER_Message *message)
++{
++  const struct GNUNET_CRYPTO_PrivateKey *key = get_handle_key (room->handle);
++
++  if (GNUNET_YES == is_room_available (room))
++  {
++    send_message_to_room (room, message, key);
++    dequeue_messages_from_room (room);
++  }
++  else
++    enqueue_to_messages (&(room->queue), key, message);
++}
++
++
++static enum GNUNET_GenericReturnValue
++dequeue_messages_from_room (struct GNUNET_MESSENGER_Room *room)
++{
++  struct GNUNET_MESSENGER_Message *message = NULL;
++  struct GNUNET_CRYPTO_PrivateKey key;
++
++  if (GNUNET_YES != is_room_available (room))
++    return room->queue.head ? GNUNET_NO : GNUNET_YES;
++
++  do {
++    if (message)
++      destroy_message (message);
++
++    message = dequeue_from_messages (&(room->queue), &key);
++
++    if (message)
++      send_message_to_room (room, message, &key);
++  } while (message);
++
++  return GNUNET_YES;
++}
++
++
+ const char*
+ GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle)
+ {
 -  if (!handle)
++  if (! handle)
+     return NULL;
+ 
+   return get_handle_name (handle);
+ }
+ 
 -int
 -GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle,
 -                           const char *name)
++
++static int
++iterate_send_name_to_room (void *cls,
++                           struct GNUNET_MESSENGER_Room *room,
++                           const struct GNUNET_MESSENGER_Contact *contact)
+ {
 -  if (!handle)
 -    return GNUNET_SYSERR;
++  const struct GNUNET_MESSENGER_Handle *handle = cls;
+ 
 -  const uint16_t name_len = name ? strlen (name) : 0;
++  if (GNUNET_YES != room->use_handle_name)
++    return GNUNET_YES;
+ 
 -  struct GNUNET_MESSENGER_NameMessage *msg;
 -  struct GNUNET_MQ_Envelope *env;
++  const char *name = get_handle_name (handle);
+ 
 -  env = GNUNET_MQ_msg_extra(msg, name_len + 1, 
GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME);
++  if (! name)
++    return GNUNET_YES;
+ 
 -  char *extra = ((char*) msg) + sizeof(*msg);
++  struct GNUNET_MESSENGER_Message *message = create_message_name (name);
+ 
 -  if (name_len)
 -    GNUNET_memcpy(extra, name, name_len);
++  if (! message)
++    return GNUNET_NO;
+ 
 -  extra[name_len] = '\0';
++  enqueue_message_to_room (room, message);
++  destroy_message (message);
++  return GNUNET_YES;
++}
+ 
 -  GNUNET_MQ_send (handle->mq, env);
++
++int
++GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle,
++                           const char *name)
++{
++  if (! handle)
++    return GNUNET_SYSERR;
++
++  set_handle_name (handle, strlen (name) > 0 ? name : NULL);
++  GNUNET_MESSENGER_find_rooms (handle, NULL, iterate_send_name_to_room, 
handle);
+   return GNUNET_YES;
+ }
+ 
++
+ static const struct GNUNET_CRYPTO_PublicKey*
 -get_non_anonymous_key (const struct GNUNET_CRYPTO_PublicKey* public_key)
++get_non_anonymous_key (const struct GNUNET_CRYPTO_PublicKey *public_key)
+ {
 -  if (0 == GNUNET_memcmp(public_key, get_anonymous_public_key()))
++  if (0 == GNUNET_memcmp (public_key, get_anonymous_public_key ()))
+     return NULL;
+ 
+   return public_key;
+ }
+ 
++
+ const struct GNUNET_CRYPTO_PublicKey*
+ GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle)
+ {
 -  if (!handle)
++  if (! handle)
+     return NULL;
+ 
 -  return get_non_anonymous_key (get_handle_key (handle));
++  return get_non_anonymous_key (get_handle_pubkey (handle));
+ }
+ 
++
++static int
++iterate_send_key_to_room (void *cls,
++                          struct GNUNET_MESSENGER_Room *room,
++                          const struct GNUNET_MESSENGER_Contact *contact)
++{
++  const struct GNUNET_CRYPTO_PrivateKey *key = cls;
++
++  struct GNUNET_MESSENGER_Message *message = create_message_key (key);
++
++  if (! message)
++    return GNUNET_NO;
++
++  enqueue_message_to_room (room, message);
++  destroy_message (message);
++  return GNUNET_YES;
++}
++
++
++int
++GNUNET_MESSENGER_set_key (struct GNUNET_MESSENGER_Handle *handle,
++                          const struct GNUNET_CRYPTO_PrivateKey *key)
++{
++  if (! handle)
++    return GNUNET_SYSERR;
++
++  if (! key)
++  {
++    GNUNET_MESSENGER_find_rooms (handle, NULL, iterate_send_key_to_room, 
NULL);
++    set_handle_key (handle, NULL);
++    return GNUNET_YES;
++  }
++
++  if (0 >= GNUNET_CRYPTO_private_key_get_length (key))
++    return GNUNET_SYSERR;
++
++  struct GNUNET_CRYPTO_PrivateKey priv;
++  GNUNET_memcpy (&priv, key, sizeof (priv));
++
++  GNUNET_MESSENGER_find_rooms (handle, NULL, iterate_send_key_to_room, &priv);
++  set_handle_key (handle, &priv);
++  return GNUNET_YES;
++}
++
++
+ struct GNUNET_MESSENGER_Room*
+ GNUNET_MESSENGER_open_room (struct GNUNET_MESSENGER_Handle *handle,
+                             const struct GNUNET_HashCode *key)
+ {
 -  if ((!handle) || (!key))
++  if ((! handle) || (! key))
+     return NULL;
+ 
 -  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get 
(handle->rooms, key);
++  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (
++    handle->rooms, key);
+ 
 -  if (!room)
++  if (! room)
+   {
+     room = create_room (handle, key);
+ 
 -    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key, 
room,
++    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key,
++                                                        room,
+                                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+     {
+       destroy_room (room);
+       return NULL;
+     }
+   }
+ 
+   send_open_room (handle, room);
+   return room;
+ }
+ 
++
+ struct GNUNET_MESSENGER_Room*
+ GNUNET_MESSENGER_enter_room (struct GNUNET_MESSENGER_Handle *handle,
+                              const struct GNUNET_PeerIdentity *door,
+                              const struct GNUNET_HashCode *key)
+ {
 -  if ((!handle) || (!door) || (!key))
++  if ((! handle) || (! door) || (! key))
+     return NULL;
+ 
 -  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get 
(handle->rooms, key);
++  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (
++    handle->rooms, key);
+ 
 -  if (!room)
++  if (! room)
+   {
+     room = create_room (handle, key);
+ 
 -    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key, 
room,
++    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key,
++                                                        room,
+                                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+     {
+       destroy_room (room);
+       return NULL;
+     }
+   }
+ 
+   send_enter_room (handle, room, door);
+   return room;
+ }
+ 
++
+ void
+ GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room)
+ {
 -  if (!room)
++  if (! room)
+     return;
+ 
++  struct GNUNET_MESSENGER_Message *message = create_message_leave ();
++
++  if (message)
++  {
++    enqueue_message_to_room (room, message);
++    destroy_message (message);
++  }
++
+   send_close_room (room->handle, room);
+ }
+ 
++
+ struct GNUNET_MESSENGER_RoomFind
+ {
+   const struct GNUNET_MESSENGER_Contact *contact;
+   GNUNET_MESSENGER_MemberCallback callback;
+   size_t counter;
+   void *cls;
+ };
+ 
+ static int
 -iterate_find_room (void* cls,
++iterate_find_room (void *cls,
+                    const struct GNUNET_HashCode *key,
+                    void *value)
+ {
+   struct GNUNET_MESSENGER_RoomFind *find = cls;
+   struct GNUNET_MESSENGER_Room *room = value;
+ 
 -  if ((find->counter > 0) && ((!find->contact) || (GNUNET_YES == 
find_room_member(room, find->contact))))
++  if ((find->counter > 0) && ((! find->contact) || (GNUNET_YES ==
++                                                    find_room_member (room,
++                                                                      find->
++                                                                      
contact))))
+   {
+     find->counter--;
+ 
 -    if (!find->callback)
++    if (! find->callback)
+       return GNUNET_YES;
+ 
 -    return find->callback(find->cls, room, find->contact);
++    return find->callback (find->cls, room, find->contact);
+   }
+   else
+     return GNUNET_NO;
+ }
+ 
++
+ int
+ GNUNET_MESSENGER_find_rooms (const struct GNUNET_MESSENGER_Handle *handle,
+                              const struct GNUNET_MESSENGER_Contact *contact,
+                              GNUNET_MESSENGER_MemberCallback callback,
+                              void *cls)
+ {
 -  if (!handle)
++  if (! handle)
+     return GNUNET_SYSERR;
+ 
+   struct GNUNET_MESSENGER_RoomFind find;
+ 
+   find.contact = contact;
+   find.callback = callback;
+   find.counter = (contact? contact->rc : SIZE_MAX);
+   find.cls = cls;
+ 
 -  return GNUNET_CONTAINER_multihashmap_iterate(handle->rooms, 
iterate_find_room, &find);
++  return GNUNET_CONTAINER_multihashmap_iterate (handle->rooms,
++                                                iterate_find_room, &find);
+ }
+ 
++
+ const struct GNUNET_HashCode*
+ GNUNET_MESSENGER_room_get_key (const struct GNUNET_MESSENGER_Room *room)
+ {
 -  if (!room)
++  if (! room)
+     return NULL;
+ 
+   return &(room->key);
+ }
+ 
++
+ const struct GNUNET_MESSENGER_Contact*
+ GNUNET_MESSENGER_get_sender (const struct GNUNET_MESSENGER_Room *room,
+                              const struct GNUNET_HashCode *hash)
+ {
 -  if ((!room) || (!hash))
++  if ((! room) || (! hash))
+     return NULL;
+ 
 -  return get_room_sender(room, hash);
++  return get_room_sender (room, hash);
+ }
+ 
++
+ const char*
 -GNUNET_MESSENGER_contact_get_name (const struct GNUNET_MESSENGER_Contact 
*contact)
++GNUNET_MESSENGER_contact_get_name (const struct
++                                   GNUNET_MESSENGER_Contact *contact)
+ {
 -  if (!contact)
++  if (! contact)
+     return NULL;
+ 
+   return get_contact_name (contact);
+ }
+ 
++
+ const struct GNUNET_CRYPTO_PublicKey*
 -GNUNET_MESSENGER_contact_get_key (const struct GNUNET_MESSENGER_Contact 
*contact)
++GNUNET_MESSENGER_contact_get_key (const struct
++                                  GNUNET_MESSENGER_Contact *contact)
+ {
 -  if (!contact)
++  if (! contact)
+     return NULL;
+ 
+   return get_non_anonymous_key (get_contact_key (contact));
+ }
+ 
++
+ void
+ GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room,
 -                               const struct GNUNET_MESSENGER_Message *message,
++                               struct GNUNET_MESSENGER_Message *message,
+                                const struct GNUNET_MESSENGER_Contact *contact)
+ {
 -  if ((!room) || (!message))
++  if ((! room) || (! message))
+     return;
+ 
+   switch (filter_message_sending (message))
+   {
+   case GNUNET_SYSERR:
 -    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sending message aborted: This kind 
of message is reserved for the service!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                "Sending message aborted: This kind of message is reserved 
for the service!\n");
+     return;
+   case GNUNET_NO:
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending message aborted: This kind 
of message could cause issues!\n");
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                "Sending message aborted: This kind of message could cause 
issues!\n");
+     return;
+   default:
+     break;
+   }
+ 
 -  ssize_t key_length = 0;
++  char *original_name;
++  char *changed_name = NULL;
+ 
 -  if (contact)
 -  {
 -    const struct GNUNET_CRYPTO_PublicKey *public_key = get_non_anonymous_key (
 -        get_contact_key(contact)
 -    );
++  if (GNUNET_MESSENGER_KIND_NAME != message->header.kind)
++    goto skip_naming;
+ 
 -    if (public_key)
 -      key_length = GNUNET_CRYPTO_public_key_get_length(public_key);
 -    else
 -      key_length = -1;
 -  }
++  original_name = message->body.name.name;
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++              "Apply rule for using handle name in room: %s\n", GNUNET_h2s (
++                &(room->key)));
++
++  const char *handle_name = get_handle_name (room->handle);
+ 
 -  if (key_length < 0)
++  if ((handle_name) && (GNUNET_YES == room->use_handle_name) &&
++      ((! original_name) || (0 == strlen (original_name))))
+   {
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending message aborted: Invalid 
key!\n");
 -    return;
++    changed_name = GNUNET_strdup (handle_name);
++    message->body.name.name = changed_name;
+   }
+ 
 -  const uint16_t msg_length = get_message_size (message, GNUNET_NO);
++skip_naming:
++  if (contact)
++  {
++    const struct GNUNET_CRYPTO_PublicKey *public_key = get_non_anonymous_key (
++      get_contact_key (contact)
++      );
+ 
 -  struct GNUNET_MESSENGER_SendMessage *msg;
 -  struct GNUNET_MQ_Envelope *env;
++    if (! public_key)
++    {
++      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
++                  "Sending message aborted: Invalid key!\n");
++      goto reset_naming;
++    }
+ 
 -  const uint16_t length = (uint16_t) key_length + msg_length;
++    struct GNUNET_MESSENGER_Message *original = message;
++    message = copy_message (original);
+ 
 -  env = GNUNET_MQ_msg_extra(
 -      msg, length,
 -      GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE
 -  );
++    if (GNUNET_YES != encrypt_message (message, public_key))
++    {
++      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++                  "Sending message aborted: Encryption failed!\n");
+ 
 -  GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
++      destroy_message (message);
++      message = original;
+ 
 -  msg->flags = (uint32_t) (
 -      contact? GNUNET_MESSENGER_FLAG_PRIVATE : GNUNET_MESSENGER_FLAG_NONE
 -  );
++      goto reset_naming;
++    }
++  }
+ 
 -  char *buffer = ((char*) msg) + sizeof(*msg);
 -  char *msg_buffer = buffer + key_length;
++  enqueue_message_to_room (room, message);
+ 
 -  if (key_length > 0)
 -    GNUNET_CRYPTO_write_public_key_to_buffer(get_contact_key(contact), 
buffer, key_length);
++reset_naming:
++  if (changed_name)
++    GNUNET_free (changed_name);
+ 
 -  encode_message (message, msg_length, msg_buffer, GNUNET_NO);
++  if (GNUNET_MESSENGER_KIND_NAME != message->header.kind)
++    return;
+ 
 -  GNUNET_MQ_send (room->handle->mq, env);
++  message->body.name.name = original_name;
+ }
+ 
++
+ const struct GNUNET_MESSENGER_Message*
+ GNUNET_MESSENGER_get_message (const struct GNUNET_MESSENGER_Room *room,
+                               const struct GNUNET_HashCode *hash)
+ {
 -  if ((!room) || (!hash))
++  if ((! room) || (! hash))
+     return NULL;
+ 
 -  const struct GNUNET_MESSENGER_Message *message = get_room_message (room, 
hash);
++  const struct GNUNET_MESSENGER_Message *message = get_room_message (room,
++                                                                     hash);
+ 
 -  if (!message)
++  if (! message)
+   {
+     struct GNUNET_MESSENGER_GetMessage *msg;
+     struct GNUNET_MQ_Envelope *env;
+ 
 -    env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE);
 -    GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
 -    GNUNET_memcpy(&(msg->hash), hash, sizeof(*hash));
++    env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE);
++    GNUNET_memcpy (&(msg->key), &(room->key), sizeof(msg->key));
++    GNUNET_memcpy (&(msg->hash), hash, sizeof(*hash));
+     GNUNET_MQ_send (room->handle->mq, env);
+   }
+ 
+   return message;
+ }
+ 
++
+ int
+ GNUNET_MESSENGER_iterate_members (struct GNUNET_MESSENGER_Room *room,
+                                   GNUNET_MESSENGER_MemberCallback callback,
+                                   void *cls)
+ {
 -  if (!room)
++  if (! room)
+     return GNUNET_SYSERR;
+ 
 -  return iterate_room_members(room, callback, cls);
++  return iterate_room_members (room, callback, cls);
+ }
diff --cc src/service/messenger/messenger_api_contact.c
index 000000000,a11190c2c..848a27b8f
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_contact.c
+++ b/src/service/messenger/messenger_api_contact.c
@@@ -1,0 -1,111 +1,119 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_contact.c
+  * @brief messenger api: client implementation of GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "messenger_api_contact.h"
+ 
+ struct GNUNET_MESSENGER_Contact*
+ create_contact (const struct GNUNET_CRYPTO_PublicKey *key)
+ {
 -  GNUNET_assert(key);
++  GNUNET_assert (key);
+ 
 -  struct GNUNET_MESSENGER_Contact *contact = GNUNET_new(struct 
GNUNET_MESSENGER_Contact);
++  struct GNUNET_MESSENGER_Contact *contact = GNUNET_new (struct
++                                                         
GNUNET_MESSENGER_Contact);
+ 
+   contact->name = NULL;
+   contact->rc = 0;
+ 
 -  GNUNET_memcpy(&(contact->public_key), key, sizeof(contact->public_key));
++  GNUNET_memcpy (&(contact->public_key), key, sizeof(contact->public_key));
+ 
+   return contact;
+ }
+ 
++
+ void
+ destroy_contact (struct GNUNET_MESSENGER_Contact *contact)
+ {
 -  GNUNET_assert(contact);
++  GNUNET_assert (contact);
+ 
+   if (contact->name)
 -    GNUNET_free(contact->name);
++    GNUNET_free (contact->name);
+ 
 -  GNUNET_free(contact);
++  GNUNET_free (contact);
+ }
+ 
++
+ const char*
+ get_contact_name (const struct GNUNET_MESSENGER_Contact *contact)
+ {
 -  GNUNET_assert(contact);
++  GNUNET_assert (contact);
+ 
+   return contact->name;
+ }
+ 
++
+ void
+ set_contact_name (struct GNUNET_MESSENGER_Contact *contact,
+                   const char *name)
+ {
 -  GNUNET_assert(contact);
++  GNUNET_assert (contact);
+ 
+   if (contact->name)
 -    GNUNET_free(contact->name);
++    GNUNET_free (contact->name);
+ 
 -  contact->name = name ? GNUNET_strdup(name) : NULL;
++  contact->name = name ? GNUNET_strdup (name) : NULL;
+ }
+ 
++
+ const struct GNUNET_CRYPTO_PublicKey*
+ get_contact_key (const struct GNUNET_MESSENGER_Contact *contact)
+ {
 -  GNUNET_assert(contact);
++  GNUNET_assert (contact);
+ 
+   return &(contact->public_key);
+ }
+ 
++
+ void
+ increase_contact_rc (struct GNUNET_MESSENGER_Contact *contact)
+ {
 -  GNUNET_assert(contact);
++  GNUNET_assert (contact);
+ 
+   contact->rc++;
+ }
+ 
++
+ int
+ decrease_contact_rc (struct GNUNET_MESSENGER_Contact *contact)
+ {
 -  GNUNET_assert(contact);
++  GNUNET_assert (contact);
+ 
+   if (contact->rc > 0)
+     contact->rc--;
+ 
+   return contact->rc ? GNUNET_NO : GNUNET_YES;
+ }
+ 
++
+ void
+ get_context_from_member (const struct GNUNET_HashCode *key,
+                          const struct GNUNET_ShortHashCode *id,
+                          struct GNUNET_HashCode *context)
+ {
 -  GNUNET_assert((key) && (id) && (context));
++  GNUNET_assert ((key) && (id) && (context));
+ 
+   GNUNET_CRYPTO_hash (id, sizeof(*id), context);
+   GNUNET_CRYPTO_hash_xor (key, context, context);
+ }
diff --cc src/service/messenger/messenger_api_contact_store.c
index 000000000,b0e0d026b..8bcfb24ff
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_contact_store.c
+++ b/src/service/messenger/messenger_api_contact_store.c
@@@ -1,0 -1,194 +1,207 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_contact_store.c
+  * @brief messenger api: client implementation of GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "messenger_api_contact_store.h"
+ 
+ #include "messenger_api_contact.h"
+ #include "messenger_api_util.h"
+ 
+ void
+ init_contact_store (struct GNUNET_MESSENGER_ContactStore *store)
+ {
+   GNUNET_assert (store);
+ 
+   store->anonymous = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
+   store->contacts = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
+ }
+ 
++
+ static int
+ iterate_destroy_contacts (void *cls,
+                           const struct GNUNET_HashCode *key,
+                           void *value)
+ {
+   struct GNUNET_MESSENGER_Contact *contact = value;
+   destroy_contact (contact);
+   return GNUNET_YES;
+ }
+ 
++
+ void
+ clear_contact_store (struct GNUNET_MESSENGER_ContactStore *store)
+ {
+   GNUNET_assert ((store) && (store->contacts));
+ 
 -  GNUNET_CONTAINER_multihashmap_iterate (store->anonymous, 
iterate_destroy_contacts, NULL);
 -  GNUNET_CONTAINER_multihashmap_iterate (store->contacts, 
iterate_destroy_contacts, NULL);
++  GNUNET_CONTAINER_multihashmap_iterate (store->anonymous,
++                                         iterate_destroy_contacts, NULL);
++  GNUNET_CONTAINER_multihashmap_iterate (store->contacts,
++                                         iterate_destroy_contacts, NULL);
+ 
+   GNUNET_CONTAINER_multihashmap_destroy (store->anonymous);
+   GNUNET_CONTAINER_multihashmap_destroy (store->contacts);
+ }
+ 
++
+ static struct GNUNET_CONTAINER_MultiHashMap*
+ select_store_contact_map (struct GNUNET_MESSENGER_ContactStore *store,
+                           const struct GNUNET_HashCode *context,
+                           struct GNUNET_HashCode *hash)
+ {
 -  const struct GNUNET_CRYPTO_PublicKey *anonymous = get_anonymous_public_key 
();
++  const struct GNUNET_CRYPTO_PublicKey *anonymous =
++    get_anonymous_public_key ();
+ 
+   struct GNUNET_HashCode anonHash;
+   GNUNET_CRYPTO_hash (anonymous, sizeof(*anonymous), &anonHash);
+ 
 -  if ((context) && (0 == GNUNET_CRYPTO_hash_cmp(hash, &anonHash)))
++  if ((context) && (0 == GNUNET_CRYPTO_hash_cmp (hash, &anonHash)))
+   {
 -    GNUNET_memcpy(hash, context, sizeof(*context));
++    GNUNET_memcpy (hash, context, sizeof(*context));
+     return store->anonymous;
+   }
+   else
+     return store->contacts;
+ }
+ 
++
+ struct GNUNET_MESSENGER_Contact*
+ get_store_contact_raw (struct GNUNET_MESSENGER_ContactStore *store,
+                        const struct GNUNET_HashCode *context,
+                        const struct GNUNET_HashCode *key_hash)
+ {
+   GNUNET_assert ((store) && (store->contacts) && (context) && (key_hash));
+ 
+   struct GNUNET_HashCode hash;
 -  GNUNET_memcpy(&hash, key_hash, sizeof(*key_hash));
++  GNUNET_memcpy (&hash, key_hash, sizeof(*key_hash));
+ 
+   struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map (
 -      store, context, &hash
 -  );
++    store, context, &hash
++    );
+ 
+   return GNUNET_CONTAINER_multihashmap_get (map, &hash);
+ }
+ 
++
+ struct GNUNET_MESSENGER_Contact*
+ get_store_contact (struct GNUNET_MESSENGER_ContactStore *store,
+                    const struct GNUNET_HashCode *context,
+                    const struct GNUNET_CRYPTO_PublicKey *pubkey)
+ {
+   GNUNET_assert ((store) && (store->contacts) && (context) && (pubkey));
+ 
+   struct GNUNET_HashCode hash;
+   GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
+ 
+   struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map (
 -      store, context, &hash
 -  );
++    store, context, &hash
++    );
+ 
 -  struct GNUNET_MESSENGER_Contact *contact = 
GNUNET_CONTAINER_multihashmap_get (map, &hash);
++  struct GNUNET_MESSENGER_Contact *contact = 
GNUNET_CONTAINER_multihashmap_get (
++    map, &hash);
+ 
+   if (contact)
+   {
 -    if (0 != GNUNET_memcmp(pubkey, get_contact_key(contact)))
++    if (0 != GNUNET_memcmp (pubkey, get_contact_key (contact)))
+     {
 -      char* str = GNUNET_CRYPTO_public_key_to_string 
(get_contact_key(contact));
 -      GNUNET_log (GNUNET_ERROR_TYPE_INVALID, "Contact in store uses wrong 
key: %s\n", str);
++      char *str = GNUNET_CRYPTO_public_key_to_string (get_contact_key (
++                                                          contact));
++      GNUNET_log (GNUNET_ERROR_TYPE_INVALID,
++                  "Contact in store uses wrong key: %s\n", str);
+       GNUNET_free (str);
+       return NULL;
+     }
+ 
+     return contact;
+   }
+ 
+   contact = create_contact (pubkey);
+ 
+   if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (map, &hash, contact,
+                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+     return contact;
+ 
+   destroy_contact (contact);
+   return NULL;
+ }
+ 
++
+ void
+ update_store_contact (struct GNUNET_MESSENGER_ContactStore *store,
 -                      struct GNUNET_MESSENGER_Contact* contact,
++                      struct GNUNET_MESSENGER_Contact *contact,
+                       const struct GNUNET_HashCode *context,
+                       const struct GNUNET_HashCode *next_context,
+                       const struct GNUNET_CRYPTO_PublicKey *pubkey)
+ {
+   GNUNET_assert ((store) && (store->contacts) && (contact) && (pubkey));
+ 
 -  const struct GNUNET_CRYPTO_PublicKey* oldkey = get_contact_key (contact);
++  const struct GNUNET_CRYPTO_PublicKey *oldkey = get_contact_key (contact);
+ 
+   struct GNUNET_HashCode hash;
+   GNUNET_CRYPTO_hash (oldkey, sizeof(*oldkey), &hash);
+ 
+   struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map (
 -      store, context, &hash
 -  );
++    store, context, &hash
++    );
+ 
+   if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (map, &hash, 
contact))
+   {
 -    GNUNET_memcpy(&(contact->public_key), pubkey, sizeof(*pubkey));
++    GNUNET_memcpy (&(contact->public_key), pubkey, sizeof(*pubkey));
+ 
+     GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
+ 
+     map = select_store_contact_map (
 -        store, next_context, &hash
 -    );
++      store, next_context, &hash
++      );
+ 
+     if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &hash, contact,
+                                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
 -      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating a contact failed: %s\n",
 -                 GNUNET_h2s(&hash));
++      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Updating a contact failed: 
%s\n",
++                  GNUNET_h2s (&hash));
+   }
+ }
+ 
++
+ void
+ remove_store_contact (struct GNUNET_MESSENGER_ContactStore *store,
 -                      struct GNUNET_MESSENGER_Contact* contact,
++                      struct GNUNET_MESSENGER_Contact *contact,
+                       const struct GNUNET_HashCode *context)
+ {
+   GNUNET_assert ((store) && (store->contacts) && (contact));
+ 
 -  const struct GNUNET_CRYPTO_PublicKey* pubkey = get_contact_key(contact);
++  const struct GNUNET_CRYPTO_PublicKey *pubkey = get_contact_key (contact);
+ 
+   struct GNUNET_HashCode hash;
+   GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
+ 
+   struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map (
 -      store, context, &hash
 -  );
++    store, context, &hash
++    );
+ 
+   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (map, &hash, 
contact))
 -    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Removing a contact failed: %s\n",
 -               GNUNET_h2s(&hash));
++    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Removing a contact failed: %s\n",
++                GNUNET_h2s (&hash));
+ 
+   destroy_contact (contact);
+ }
diff --cc src/service/messenger/messenger_api_contact_store.h
index 000000000,e012e42c1..03912e985
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_contact_store.h
+++ b/src/service/messenger/messenger_api_contact_store.h
@@@ -1,0 -1,126 +1,126 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_contact_store.h
+  * @brief messenger api: client implementation of GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_MESSENGER_API_CONTACT_STORE_H
+ #define GNUNET_MESSENGER_API_CONTACT_STORE_H
+ 
+ #include "platform.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ 
+ struct GNUNET_MESSENGER_Contact;
+ 
+ struct GNUNET_MESSENGER_ContactStore
+ {
+   struct GNUNET_CONTAINER_MultiHashMap *anonymous;
+   struct GNUNET_CONTAINER_MultiHashMap *contacts;
+ };
+ 
+ /**
+  * Initializes a contact store as fully empty.
+  *
+  * @param[out] store Contact store
+  */
+ void
+ init_contact_store (struct GNUNET_MESSENGER_ContactStore *store);
+ 
+ /**
+  * Clears a contact store, wipes its content and deallocates its memory.
+  *
+  * @param[in,out] store Contact store
+  */
+ void
+ clear_contact_store (struct GNUNET_MESSENGER_ContactStore *store);
+ 
+ /**
+  * Returns a contact using the hash of a specific public key. In case the 
anonymous
+  * key gets used by the requested contact, it will use its provided member
+  * <i>context</i> to select the matching contact from the <i>store</i>.
+  *
+  * In case there is no contact stored which uses the given key or context,
+  * NULL gets returned.
+  *
+  * @param[in,out] store Contact store
+  * @param[in] context Member context
+  * @param[in] key_hash Hash of public key
+  */
+ struct GNUNET_MESSENGER_Contact*
+ get_store_contact_raw (struct GNUNET_MESSENGER_ContactStore *store,
+                        const struct GNUNET_HashCode *context,
+                        const struct GNUNET_HashCode *key_hash);
+ 
+ /**
+  * Returns a contact using a specific public key. In case the anonymous
+  * key gets used by the requested contact, it will use its provided member
+  * <i>context</i> to select the matching contact from the <i>store</i>.
+  *
+  * In case there is no contact stored which uses the given key or context,
+  * a new contact will be created automatically.
+  *
+  * The function returns NULL if an error occurs during allocation
+  * or validation of the contacts key.
+  *
+  * @param[in,out] store Contact store
+  * @param[in] context Member context
+  * @param[in] pubkey Public key of EGO
+  */
+ struct GNUNET_MESSENGER_Contact*
+ get_store_contact (struct GNUNET_MESSENGER_ContactStore *store,
+                    const struct GNUNET_HashCode *context,
+                    const struct GNUNET_CRYPTO_PublicKey *pubkey);
+ 
+ /**
+  * Moves a <i>contact</i> from the <i>store</i> to another location
+  * matching a given public key and member <i>context</i>.
+  *
+  * This function allows changes of keys or changes of member contexts!
+  *
+  * @param[in,out] store Contact store
+  * @param[in,out] contact Contact
+  * @param[in] context Member context
+  * @param[in] next_context Member context
+  * @param[in] pubkey Public key of EGO
+  */
+ void
+ update_store_contact (struct GNUNET_MESSENGER_ContactStore *store,
 -                      struct GNUNET_MESSENGER_Contact* contact,
++                      struct GNUNET_MESSENGER_Contact *contact,
+                       const struct GNUNET_HashCode *context,
+                       const struct GNUNET_HashCode *next_context,
+                       const struct GNUNET_CRYPTO_PublicKey *pubkey);
+ 
+ /**
+  * Removes a <i>contact</i> from the <i>store</i> which uses
+  * a given member <i>context</i>.
+  *
+  * @param[in,out] store Contact store
+  * @param[in,out] contact Contact
+  * @param[in] context Member context
+  */
+ void
+ remove_store_contact (struct GNUNET_MESSENGER_ContactStore *store,
 -                      struct GNUNET_MESSENGER_Contact* contact,
++                      struct GNUNET_MESSENGER_Contact *contact,
+                       const struct GNUNET_HashCode *context);
+ 
+ #endif //GNUNET_MESSENGER_API_CONTACT_STORE_H
diff --cc src/service/messenger/messenger_api_handle.c
index 000000000,fddf73ad5..816153e42
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_handle.c
+++ b/src/service/messenger/messenger_api_handle.c
@@@ -1,0 -1,208 +1,271 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_handle.c
+  * @brief messenger api: client implementation of GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "messenger_api_handle.h"
+ 
++#include "messenger_api_room.h"
+ #include "messenger_api_util.h"
+ 
+ struct GNUNET_MESSENGER_Handle*
+ create_handle (const struct GNUNET_CONFIGURATION_Handle *cfg,
 -               GNUNET_MESSENGER_IdentityCallback identity_callback,
 -               void *identity_cls,
+                GNUNET_MESSENGER_MessageCallback msg_callback,
+                void *msg_cls)
+ {
 -  GNUNET_assert(cfg);
++  GNUNET_assert (cfg);
+ 
 -  struct GNUNET_MESSENGER_Handle *handle = GNUNET_new(struct 
GNUNET_MESSENGER_Handle);
++  struct GNUNET_MESSENGER_Handle *handle = GNUNET_new (struct
++                                                       
GNUNET_MESSENGER_Handle);
+ 
+   handle->cfg = cfg;
+   handle->mq = NULL;
+ 
 -  handle->identity_callback = identity_callback;
 -  handle->identity_cls = identity_cls;
 -
+   handle->msg_callback = msg_callback;
+   handle->msg_cls = msg_cls;
+ 
+   handle->name = NULL;
++  handle->key = NULL;
+   handle->pubkey = NULL;
+ 
+   handle->reconnect_time = GNUNET_TIME_relative_get_zero_ ();
+   handle->reconnect_task = NULL;
+ 
+   handle->rooms = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
+ 
 -  init_contact_store(get_handle_contact_store(handle));
++  init_contact_store (get_handle_contact_store (handle));
+ 
+   return handle;
+ }
+ 
++
+ static int
+ iterate_destroy_room (void *cls,
+                       const struct GNUNET_HashCode *key,
+                       void *value)
+ {
+   struct GNUNET_MESSENGER_Room *room = value;
+ 
+   destroy_room (room);
+ 
+   return GNUNET_YES;
+ }
+ 
++
+ void
+ destroy_handle (struct GNUNET_MESSENGER_Handle *handle)
+ {
 -  GNUNET_assert(handle);
++  GNUNET_assert (handle);
+ 
+   if (handle->reconnect_task)
+     GNUNET_SCHEDULER_cancel (handle->reconnect_task);
+ 
+   if (handle->mq)
+     GNUNET_MQ_destroy (handle->mq);
+ 
+   if (handle->name)
 -    GNUNET_free(handle->name);
++    GNUNET_free (handle->name);
++
++  if (handle->key)
++    GNUNET_free (handle->key);
+ 
+   if (handle->pubkey)
 -    GNUNET_free(handle->pubkey);
++    GNUNET_free (handle->pubkey);
+ 
+   if (handle->rooms)
+   {
 -    GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, 
iterate_destroy_room, NULL);
++    GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, 
iterate_destroy_room,
++                                           NULL);
+ 
+     GNUNET_CONTAINER_multihashmap_destroy (handle->rooms);
+   }
+ 
 -  clear_contact_store(get_handle_contact_store(handle));
++  clear_contact_store (get_handle_contact_store (handle));
+ 
 -  GNUNET_free(handle);
++  GNUNET_free (handle);
+ }
+ 
++
+ void
+ set_handle_name (struct GNUNET_MESSENGER_Handle *handle,
+                  const char *name)
+ {
 -  GNUNET_assert(handle);
++  GNUNET_assert (handle);
+ 
+   if (handle->name)
 -    GNUNET_free(handle->name);
++    GNUNET_free (handle->name);
+ 
 -  handle->name = name ? GNUNET_strdup(name) : NULL;
++  handle->name = name ? GNUNET_strdup (name) : NULL;
+ }
+ 
++
+ const char*
+ get_handle_name (const struct GNUNET_MESSENGER_Handle *handle)
+ {
 -  GNUNET_assert(handle);
++  GNUNET_assert (handle);
+ 
+   return handle->name;
+ }
+ 
++
+ void
+ set_handle_key (struct GNUNET_MESSENGER_Handle *handle,
 -                const struct GNUNET_CRYPTO_PublicKey *pubkey)
++                const struct GNUNET_CRYPTO_PrivateKey *key)
+ {
 -  GNUNET_assert(handle);
++  GNUNET_assert (handle);
++
++  if (! key)
++  {
++    if (handle->key)
++      GNUNET_free (handle->key);
+ 
 -  if (!handle->pubkey)
 -    handle->pubkey = GNUNET_new(struct GNUNET_CRYPTO_PublicKey);
++    if (handle->pubkey)
++      GNUNET_free (handle->pubkey);
+ 
 -  GNUNET_memcpy(handle->pubkey, pubkey, sizeof(*pubkey));
++    handle->key = NULL;
++    handle->pubkey = NULL;
++    return;
++  }
++
++  if (! handle->key)
++    handle->key = GNUNET_new (struct GNUNET_CRYPTO_PrivateKey);
++
++  if (! handle->pubkey)
++    handle->pubkey = GNUNET_new (struct GNUNET_CRYPTO_PublicKey);
++
++  GNUNET_memcpy (handle->key, key, sizeof(*key));
++  GNUNET_CRYPTO_key_get_public (key, handle->pubkey);
+ }
+ 
 -const struct GNUNET_CRYPTO_PublicKey*
++
++const struct GNUNET_CRYPTO_PrivateKey*
+ get_handle_key (const struct GNUNET_MESSENGER_Handle *handle)
+ {
 -  GNUNET_assert(handle);
++  GNUNET_assert (handle);
++
++  if (handle->key)
++    return handle->key;
++
++  return get_anonymous_private_key ();
++}
++
++
++const struct GNUNET_CRYPTO_PublicKey*
++get_handle_pubkey (const struct GNUNET_MESSENGER_Handle *handle)
++{
++  GNUNET_assert (handle);
+ 
+   if (handle->pubkey)
+     return handle->pubkey;
+ 
+   return get_anonymous_public_key ();
+ }
+ 
++
+ struct GNUNET_MESSENGER_ContactStore*
+ get_handle_contact_store (struct GNUNET_MESSENGER_Handle *handle)
+ {
 -  GNUNET_assert(handle);
++  GNUNET_assert (handle);
+ 
+   return &(handle->contact_store);
+ }
+ 
++
+ struct GNUNET_MESSENGER_Contact*
+ get_handle_contact (struct GNUNET_MESSENGER_Handle *handle,
+                     const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (key));
++  GNUNET_assert ((handle) && (key));
++
++  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (
++    handle->rooms, key);
++
++  if (! room)
++    return NULL;
+ 
 -  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get 
(handle->rooms, key);
++  const struct GNUNET_ShortHashCode *contact_id = get_room_sender_id (room);
+ 
 -  if ((!room) || (!(room->contact_id)))
++  if (! contact_id)
+     return NULL;
+ 
+   struct GNUNET_HashCode context;
 -  get_context_from_member (key, room->contact_id, &context);
++  get_context_from_member (key, contact_id, &context);
+ 
 -  return get_store_contact(get_handle_contact_store(handle), &context, 
get_handle_key(handle));
++  return get_store_contact (get_handle_contact_store (handle), &context,
++                            get_handle_pubkey (handle));
+ }
+ 
++
+ void
+ open_handle_room (struct GNUNET_MESSENGER_Handle *handle,
+                   const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (key));
++  GNUNET_assert ((handle) && (key));
+ 
 -  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get 
(handle->rooms, key);
++  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (
++    handle->rooms, key);
+ 
+   if (room)
+     room->opened = GNUNET_YES;
+ }
+ 
++
+ void
+ entry_handle_room_at (struct GNUNET_MESSENGER_Handle *handle,
+                       const struct GNUNET_PeerIdentity *door,
+                       const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (door) && (key));
++  GNUNET_assert ((handle) && (door) && (key));
+ 
 -  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get 
(handle->rooms, key);
++  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (
++    handle->rooms, key);
+ 
+   if (room)
 -    add_to_list_tunnels (&(room->entries), door);
++    add_to_list_tunnels (&(room->entries), door, NULL);
+ }
+ 
++
+ void
+ close_handle_room (struct GNUNET_MESSENGER_Handle *handle,
+                    const struct GNUNET_HashCode *key)
+ {
 -  GNUNET_assert((handle) && (key));
++  GNUNET_assert ((handle) && (key));
+ 
 -  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get 
(handle->rooms, key);
++  struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (
++    handle->rooms, key);
+ 
 -  if ((room) && (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove 
(handle->rooms, key, room)))
++  if ((room) && (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (
++                   handle->rooms, key, room)))
+     destroy_room (room);
+ }
++
++
++struct GNUNET_MESSENGER_Room*
++get_handle_room (struct GNUNET_MESSENGER_Handle *handle,
++                 const struct GNUNET_HashCode *key)
++{
++  GNUNET_assert ((handle) && (key));
++
++  return GNUNET_CONTAINER_multihashmap_get (handle->rooms, key);
++}
diff --cc src/service/messenger/messenger_api_handle.h
index 000000000,09f44be8a..fb4e4c580
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_handle.h
+++ b/src/service/messenger/messenger_api_handle.h
@@@ -1,0 -1,178 +1,193 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_handle.h
+  * @brief messenger api: client implementation of GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_MESSENGER_API_HANDLE_H
+ #define GNUNET_MESSENGER_API_HANDLE_H
+ 
+ #include "platform.h"
+ #include "gnunet_cadet_service.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ 
+ #include "gnunet_messenger_service.h"
+ 
+ #include "messenger_api_contact_store.h"
 -#include "messenger_api_room.h"
+ 
+ struct GNUNET_MESSENGER_Handle
+ {
+   const struct GNUNET_CONFIGURATION_Handle *cfg;
+ 
+   struct GNUNET_MQ_Handle *mq;
+ 
 -  GNUNET_MESSENGER_IdentityCallback identity_callback;
 -  void *identity_cls;
 -
+   GNUNET_MESSENGER_MessageCallback msg_callback;
+   void *msg_cls;
+ 
+   char *name;
++  struct GNUNET_CRYPTO_PrivateKey *key;
+   struct GNUNET_CRYPTO_PublicKey *pubkey;
+ 
+   struct GNUNET_TIME_Relative reconnect_time;
+   struct GNUNET_SCHEDULER_Task *reconnect_task;
+ 
+   struct GNUNET_MESSENGER_ContactStore contact_store;
+ 
+   struct GNUNET_CONTAINER_MultiHashMap *rooms;
+ };
+ 
+ /**
+  * Creates and allocates a new handle using a given configuration and a 
custom message callback
+  * with a given closure for the client API.
+  *
+  * @param[in] cfg Configuration
+  * @param[in] msg_callback Message callback
+  * @param[in,out] msg_cls Closure
+  * @return New handle
+  */
+ struct GNUNET_MESSENGER_Handle*
+ create_handle (const struct GNUNET_CONFIGURATION_Handle *cfg,
 -               GNUNET_MESSENGER_IdentityCallback identity_callback,
 -               void *identity_cls,
+                GNUNET_MESSENGER_MessageCallback msg_callback,
+                void *msg_cls);
+ 
+ /**
+  * Destroys a <i>handle</i> and frees its memory fully from the client API.
+  *
+  * @param[in,out] handle Handle
+  */
+ void
+ destroy_handle (struct GNUNET_MESSENGER_Handle *handle);
+ 
+ /**
+  * Sets the name of a <i>handle</i> to a specific <i>name</i>.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] name New name
+  */
+ void
+ set_handle_name (struct GNUNET_MESSENGER_Handle *handle,
+                  const char *name);
+ 
+ /**
+  * Returns the current name of a given <i>handle</i> or NULL if no valid name 
was assigned yet.
+  *
+  * @param[in] handle Handle
+  * @return Name of the handle or NULL
+  */
+ const char*
+ get_handle_name (const struct GNUNET_MESSENGER_Handle *handle);
+ 
+ /**
 - * Sets the public key of a given <i>handle</i> to a specific public key.
++ * Sets the keypair of a given <i>handle</i> to the keypair of a specific 
private <i>key</i>.
+  *
+  * @param[in,out] handle Handle
 - * @param[in] pubkey Public key
++ * @param[in] key Private key or NULL
+  */
+ void
+ set_handle_key (struct GNUNET_MESSENGER_Handle *handle,
 -                const struct GNUNET_CRYPTO_PublicKey *pubkey);
++                const struct GNUNET_CRYPTO_PrivateKey *key);
++
++/**
++ * Returns the private key of a given <i>handle</i>.
++ *
++ * @param[in] handle Handle
++ * @return Private key of the handle
++ */
++const struct GNUNET_CRYPTO_PrivateKey*
++get_handle_key (const struct GNUNET_MESSENGER_Handle *handle);
+ 
+ /**
+  * Returns the public key of a given <i>handle</i>.
+  *
+  * @param[in] handle Handle
+  * @return Public key of the handle
+  */
+ const struct GNUNET_CRYPTO_PublicKey*
 -get_handle_key (const struct GNUNET_MESSENGER_Handle *handle);
++get_handle_pubkey (const struct GNUNET_MESSENGER_Handle *handle);
+ 
+ /**
+  * Returns the used contact store of a given <i>handle</i>.
+  *
+  * @param[in,out] handle Handle
+  * @return Contact store
+  */
+ struct GNUNET_MESSENGER_ContactStore*
+ get_handle_contact_store (struct GNUNET_MESSENGER_Handle *handle);
+ 
+ /**
+  * Returns the contact of a given <i>handle</i> in a room identified by a
+  * given <i>key</i>.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] key Key of room
+  * @return Contact
+  */
+ struct GNUNET_MESSENGER_Contact*
+ get_handle_contact (struct GNUNET_MESSENGER_Handle *handle,
+                     const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Marks a room known to a <i>handle</i> identified by a given <i>key</i> as 
open.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] key Key of room
+  */
+ void
+ open_handle_room (struct GNUNET_MESSENGER_Handle *handle,
+                   const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Adds a tunnel for a room known to a <i>handle</i> identified by a given 
<i>key</i> to a
+  * list of opened connections.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] door Peer identity
+  * @param[in] key Key of room
+  */
+ void
+ entry_handle_room_at (struct GNUNET_MESSENGER_Handle *handle,
+                       const struct GNUNET_PeerIdentity *door,
+                       const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Destroys and so implicitly closes a room known to a <i>handle</i> 
identified by a given <i>key</i>.
+  *
+  * @param[in,out] handle Handle
+  * @param[in] key Key of room
+  */
+ void
+ close_handle_room (struct GNUNET_MESSENGER_Handle *handle,
+                    const struct GNUNET_HashCode *key);
+ 
++/**
++ * Returns the room known to a <i>handle</i> identified by a given <i>key</i>.
++ *
++ * @param[in,out] handle handle Handle
++ * @param[in] key Key of room
++ * @return Room or NULL
++ */
++struct GNUNET_MESSENGER_Room*
++get_handle_room (struct GNUNET_MESSENGER_Handle *handle,
++                 const struct GNUNET_HashCode *key);
++
+ #endif //GNUNET_MESSENGER_API_HANDLE_H
diff --cc src/service/messenger/messenger_api_message.c
index 000000000,1f7e8dbf2..f77d171f6
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_message.c
+++ b/src/service/messenger/messenger_api_message.c
@@@ -1,0 -1,1026 +1,1149 @@@
+ /*
+    This file is part of GNUnet.
+    Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_message.c
+  * @brief messenger api: client and service implementation of GNUnet 
MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "messenger_api_message.h"
+ 
+ struct GNUNET_MESSENGER_MessageSignature
+ {
+   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+   struct GNUNET_HashCode hash;
+ };
+ 
+ struct GNUNET_MESSENGER_ShortMessage
+ {
+   enum GNUNET_MESSENGER_MessageKind kind;
+   struct GNUNET_MESSENGER_MessageBody body;
+ };
+ 
+ struct GNUNET_MESSENGER_Message*
+ create_message (enum GNUNET_MESSENGER_MessageKind kind)
+ {
+   struct GNUNET_MESSENGER_Message *message = GNUNET_new (struct
+                                                          
GNUNET_MESSENGER_Message);
+ 
+   message->header.kind = kind;
+ 
+   switch (message->header.kind)
+   {
+   case GNUNET_MESSENGER_KIND_NAME:
+     message->body.name.name = NULL;
+     break;
+   case GNUNET_MESSENGER_KIND_TEXT:
+     message->body.text.text = NULL;
+     break;
+   case GNUNET_MESSENGER_KIND_FILE:
+     message->body.file.uri = NULL;
+     break;
+   case GNUNET_MESSENGER_KIND_PRIVATE:
+     message->body.privacy.length = 0;
+     message->body.privacy.data = NULL;
+     break;
+   default:
+     break;
+   }
+ 
+   return message;
+ }
+ 
+ 
+ struct GNUNET_MESSENGER_Message*
+ copy_message (const struct GNUNET_MESSENGER_Message *message)
+ {
+   GNUNET_assert (message);
+ 
+   struct GNUNET_MESSENGER_Message *copy = GNUNET_new (struct
+                                                       
GNUNET_MESSENGER_Message);
+ 
+   GNUNET_memcpy (copy, message, sizeof(struct GNUNET_MESSENGER_Message));
+ 
+   switch (message->header.kind)
+   {
+   case GNUNET_MESSENGER_KIND_NAME:
+     copy->body.name.name = GNUNET_strdup (message->body.name.name);
+     break;
+   case GNUNET_MESSENGER_KIND_TEXT:
+     copy->body.text.text = GNUNET_strdup (message->body.text.text);
+     break;
+   case GNUNET_MESSENGER_KIND_FILE:
+     copy->body.file.uri = GNUNET_strdup (message->body.file.uri);
+     break;
+   case GNUNET_MESSENGER_KIND_PRIVATE:
+     copy->body.privacy.data = copy->body.privacy.length ? GNUNET_malloc (
+       copy->body.privacy.length) : NULL;
+ 
+     if (copy->body.privacy.data)
+     {
+       GNUNET_memcpy (copy->body.privacy.data, message->body.privacy.data,
+                      copy->body.privacy.length);
+     }
+ 
+     break;
+   default:
+     break;
+   }
+ 
+   return copy;
+ }
+ 
+ 
+ static void
+ destroy_message_body (enum GNUNET_MESSENGER_MessageKind kind,
+                       struct GNUNET_MESSENGER_MessageBody *body)
+ {
+   switch (kind)
+   {
+   case GNUNET_MESSENGER_KIND_NAME:
+     GNUNET_free (body->name.name);
+     break;
+   case GNUNET_MESSENGER_KIND_TEXT:
+     GNUNET_free (body->text.text);
+     break;
+   case GNUNET_MESSENGER_KIND_FILE:
+     GNUNET_free (body->file.uri);
+     break;
+   case GNUNET_MESSENGER_KIND_PRIVATE:
+     GNUNET_free (body->privacy.data);
+     break;
+   default:
+     break;
+   }
+ }
+ 
+ 
+ void
+ cleanup_message (struct GNUNET_MESSENGER_Message *message)
+ {
+   GNUNET_assert (message);
+ 
+   destroy_message_body (message->header.kind, &(message->body));
+ }
+ 
+ 
+ void
+ destroy_message (struct GNUNET_MESSENGER_Message *message)
+ {
+   GNUNET_assert (message);
+ 
+   destroy_message_body (message->header.kind, &(message->body));
+ 
+   GNUNET_free (message);
+ }
+ 
+ 
+ int
+ is_message_session_bound (const struct GNUNET_MESSENGER_Message *message)
+ {
+   GNUNET_assert (message);
+ 
+   if ((GNUNET_MESSENGER_KIND_JOIN == message->header.kind) ||
+       (GNUNET_MESSENGER_KIND_LEAVE == message->header.kind) ||
+       (GNUNET_MESSENGER_KIND_NAME == message->header.kind) ||
+       (GNUNET_MESSENGER_KIND_KEY == message->header.kind) ||
+       (GNUNET_MESSENGER_KIND_ID == message->header.kind))
+     return GNUNET_YES;
+   else
+     return GNUNET_NO;
+ }
+ 
+ 
+ static void
+ fold_short_message (const struct GNUNET_MESSENGER_Message *message,
+                     struct GNUNET_MESSENGER_ShortMessage *shortened)
+ {
+   shortened->kind = message->header.kind;
+ 
+   GNUNET_memcpy (&(shortened->body), &(message->body), sizeof(struct
+                                                               
GNUNET_MESSENGER_MessageBody));
+ }
+ 
+ 
+ static void
+ unfold_short_message (struct GNUNET_MESSENGER_ShortMessage *shortened,
+                       struct GNUNET_MESSENGER_Message *message)
+ {
+   destroy_message_body (message->header.kind, &(message->body));
+ 
+   message->header.kind = shortened->kind;
+ 
+   GNUNET_memcpy (&(message->body), &(shortened->body), sizeof(struct
+                                                               
GNUNET_MESSENGER_MessageBody));
+ }
+ 
+ 
+ #define member_size(type, member) sizeof(((type*) NULL)->member)
+ 
+ static uint16_t
+ get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind)
+ {
+   uint16_t length = 0;
+ 
+   switch (kind)
+   {
+   case GNUNET_MESSENGER_KIND_INFO:
+     length += member_size (struct GNUNET_MESSENGER_Message,
+                            body.info.messenger_version);
+     break;
+   case GNUNET_MESSENGER_KIND_PEER:
+     length += member_size (struct GNUNET_MESSENGER_Message, body.peer.peer);
+     break;
+   case GNUNET_MESSENGER_KIND_ID:
+     length += member_size (struct GNUNET_MESSENGER_Message, body.id.id);
+     break;
+   case GNUNET_MESSENGER_KIND_MISS:
+     length += member_size (struct GNUNET_MESSENGER_Message, body.miss.peer);
+     break;
+   case GNUNET_MESSENGER_KIND_MERGE:
+     length += member_size (struct GNUNET_MESSENGER_Message,
+                            body.merge.previous);
+     break;
+   case GNUNET_MESSENGER_KIND_REQUEST:
+     length += member_size (struct GNUNET_MESSENGER_Message, 
body.request.hash);
+     break;
+   case GNUNET_MESSENGER_KIND_INVITE:
+     length += member_size (struct GNUNET_MESSENGER_Message, body.invite.door);
+     length += member_size (struct GNUNET_MESSENGER_Message, body.invite.key);
+     break;
+   case GNUNET_MESSENGER_KIND_TEXT:
+     break;
+   case GNUNET_MESSENGER_KIND_FILE:
+     length += member_size (struct GNUNET_MESSENGER_Message, body.file.key);
+     length += member_size (struct GNUNET_MESSENGER_Message, body.file.hash);
+     length += member_size (struct GNUNET_MESSENGER_Message, body.file.name);
+     break;
++  case GNUNET_MESSENGER_KIND_PRIVATE:
++    length += member_size (struct GNUNET_MESSENGER_Message, body.privacy.key);
++    break;
+   case GNUNET_MESSENGER_KIND_DELETE:
+     length += member_size (struct GNUNET_MESSENGER_Message, 
body.deletion.hash);
+     length += member_size (struct GNUNET_MESSENGER_Message,
+                            body.deletion.delay);
+     break;
+   default:
+     break;
+   }
+ 
+   return length;
+ }
+ 
+ 
+ typedef uint32_t kind_t;
+ 
+ uint16_t
+ get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind,
+                        int include_header)
+ {
+   uint16_t length = 0;
+ 
+   if (GNUNET_YES == include_header)
+   {
+     length += member_size (struct GNUNET_MESSENGER_Message, header.timestamp);
+     length += member_size (struct GNUNET_MESSENGER_Message, header.sender_id);
+     length += member_size (struct GNUNET_MESSENGER_Message, header.previous);
+   }
+ 
+   length += sizeof(kind_t);
+ 
+   return length + get_message_body_kind_size (kind);
+ }
+ 
+ 
+ static uint16_t
+ get_message_body_size (enum GNUNET_MESSENGER_MessageKind kind,
+                        const struct GNUNET_MESSENGER_MessageBody *body)
+ {
+   uint16_t length = 0;
+ 
+   switch (kind)
+   {
 -  case GNUNET_MESSENGER_KIND_INFO:
 -    length += GNUNET_CRYPTO_public_key_get_length (&(body->info.host_key));
 -    break;
+   case GNUNET_MESSENGER_KIND_JOIN:
+     length += GNUNET_CRYPTO_public_key_get_length (&(body->join.key));
+     break;
+   case GNUNET_MESSENGER_KIND_NAME:
+     length += (body->name.name ? strlen (body->name.name) : 0);
+     break;
+   case GNUNET_MESSENGER_KIND_KEY:
+     length += GNUNET_CRYPTO_public_key_get_length (&(body->key.key));
+     break;
+   case GNUNET_MESSENGER_KIND_TEXT:
+     length += strlen (body->text.text);
+     break;
+   case GNUNET_MESSENGER_KIND_FILE:
+     length += strlen (body->file.uri);
+     break;
+   case GNUNET_MESSENGER_KIND_PRIVATE:
+     length += body->privacy.length;
+     break;
+   default:
+     break;
+   }
+ 
+   return length;
+ }
+ 
+ 
+ uint16_t
+ get_message_size (const struct GNUNET_MESSENGER_Message *message,
+                   int include_header)
+ {
+   GNUNET_assert (message);
+ 
+   uint16_t length = 0;
+ 
+   if (GNUNET_YES == include_header)
+     length += GNUNET_CRYPTO_signature_get_length (
+       &(message->header.signature));
+ 
+   length += get_message_kind_size (message->header.kind, include_header);
+   length += get_message_body_size (message->header.kind, &(message->body));
+ 
+   return length;
+ }
+ 
+ 
+ static uint16_t
+ get_short_message_size (const struct GNUNET_MESSENGER_ShortMessage *message,
+                         int include_body)
+ {
+   const uint16_t minimum_size = sizeof(struct GNUNET_HashCode) + 
sizeof(kind_t);
+ 
+   if (message)
+     return minimum_size + get_message_body_kind_size (message->kind)
+            + (include_body == GNUNET_YES? get_message_body_size 
(message->kind,
+                                                                  
&(message->body))
+     : 0);
+   else
+     return minimum_size;
+ }
+ 
+ 
+ static uint16_t
+ calc_usual_padding ()
+ {
+   uint16_t padding = 0;
+   uint16_t kind_size;
+ 
+   for (int i = 0; i <= GNUNET_MESSENGER_KIND_MAX; i++)
+   {
+     kind_size = get_message_kind_size ((enum GNUNET_MESSENGER_MessageKind) i,
+                                        GNUNET_YES);
+ 
+     if (kind_size > padding)
+       padding = kind_size;
+   }
+ 
+   return padding + GNUNET_MESSENGER_PADDING_MIN;
+ }
+ 
+ 
+ #define max(x, y) (x > y? x : y)
+ 
+ static uint16_t
+ calc_padded_length (uint16_t length)
+ {
+   static uint16_t usual_padding = 0;
+ 
+   if (! usual_padding)
+     usual_padding = calc_usual_padding ();
+ 
+   const uint16_t padded_length = max (
+     length + GNUNET_MESSENGER_PADDING_MIN,
+     usual_padding
+     );
+ 
+   if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL0)
+     return GNUNET_MESSENGER_PADDING_LEVEL0;
+ 
+   if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL1)
+     return GNUNET_MESSENGER_PADDING_LEVEL1;
+ 
+   if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL2)
+     return GNUNET_MESSENGER_PADDING_LEVEL2;
+ 
+   return GNUNET_MESSENGER_MAX_MESSAGE_SIZE;
+ 
+ }
+ 
+ 
+ #define min(x, y) (x < y? x : y)
+ 
+ #define encode_step_ext(dst, offset, src, size) do { \
 -    GNUNET_memcpy (dst + offset, src, size);            \
 -    offset += size;                                    \
 -} while (0)
 -
 -#define encode_step(dst, offset, src) do {         \
 -    encode_step_ext (dst, offset, src, sizeof(*src)); \
++  GNUNET_memcpy (dst + offset, src, size);           \
++  offset += size;                                    \
+ } while (0)
+ 
 -#define encode_step_key(dst, offset, src, length) do {  \
 -    ssize_t result = GNUNET_CRYPTO_write_public_key_to_buffer ( \
 -      src, dst + offset, length - offset                \
 -      );                                                    \
 -    if (result < 0)                                       \
 -    GNUNET_break (0);                                   \
 -    else                                                  \
 -    offset += result;                                   \
++#define encode_step(dst, offset, src) do {          \
++  encode_step_ext (dst, offset, src, sizeof(*src)); \
+ } while (0)
+ 
 -#define encode_step_signature(dst, offset, src, length) do {  \
 -    ssize_t result = GNUNET_CRYPTO_write_signature_to_buffer ( \
 -      src, dst + offset, length - offset                      \
 -      );                                                          \
 -    if (result < 0)                                             \
++#define encode_step_key(dst, offset, src, length) do {        \
++  ssize_t result = GNUNET_CRYPTO_write_public_key_to_buffer ( \
++    src, dst + offset, length - offset                        \
++  );                                                          \
++  if (result < 0)                                             \
+     GNUNET_break (0);                                         \
 -    else                                                        \
++  else                                                        \
+     offset += result;                                         \
+ } while (0)
+ 
++#define encode_step_signature(dst, offset, src, length) do { \
++  ssize_t result = GNUNET_CRYPTO_write_signature_to_buffer ( \
++    src, dst + offset, length - offset                       \
++  );                                                         \
++  if (result < 0)                                            \
++    GNUNET_break (0);                                        \
++  else                                                       \
++    offset += result;                                        \
++} while (0)
++
+ static void
+ encode_message_body (enum GNUNET_MESSENGER_MessageKind kind,
+                      const struct GNUNET_MESSENGER_MessageBody *body,
+                      uint16_t length,
+                      char *buffer,
+                      uint16_t offset)
+ {
+   uint32_t version;
+   switch (kind)
+   {
+   case GNUNET_MESSENGER_KIND_INFO:
+     version = GNUNET_htobe32 (body->info.messenger_version);
+ 
 -    encode_step_key (buffer, offset, &(body->info.host_key), length);
+     encode_step (buffer, offset, &version);
+     break;
+   case GNUNET_MESSENGER_KIND_JOIN:
+     encode_step_key (buffer, offset, &(body->join.key), length);
+     break;
+   case GNUNET_MESSENGER_KIND_NAME:
+     if (body->name.name)
+       encode_step_ext (buffer, offset, body->name.name, min (length - offset,
+                                                              strlen (
+                                                                
body->name.name)));
+     break;
+   case GNUNET_MESSENGER_KIND_KEY:
+     encode_step_key (buffer, offset, &(body->key.key), length);
+     break;
+   case GNUNET_MESSENGER_KIND_PEER:
+     encode_step (buffer, offset, &(body->peer.peer));
+     break;
+   case GNUNET_MESSENGER_KIND_ID:
+     encode_step (buffer, offset, &(body->id.id));
+     break;
+   case GNUNET_MESSENGER_KIND_MISS:
+     encode_step (buffer, offset, &(body->miss.peer));
+     break;
+   case GNUNET_MESSENGER_KIND_MERGE:
+     encode_step (buffer, offset, &(body->merge.previous));
+     break;
+   case GNUNET_MESSENGER_KIND_REQUEST:
+     encode_step (buffer, offset, &(body->request.hash));
+     break;
+   case GNUNET_MESSENGER_KIND_INVITE:
+     encode_step (buffer, offset, &(body->invite.door));
+     encode_step (buffer, offset, &(body->invite.key));
+     break;
+   case GNUNET_MESSENGER_KIND_TEXT:
+     encode_step_ext (buffer, offset, body->text.text, min (length - offset,
+                                                            strlen (
+                                                              
body->text.text)));
+     break;
+   case GNUNET_MESSENGER_KIND_FILE:
+     encode_step (buffer, offset, &(body->file.key));
+     encode_step (buffer, offset, &(body->file.hash));
+     encode_step_ext (buffer, offset, body->file.name, 
sizeof(body->file.name));
+     encode_step_ext (buffer, offset, body->file.uri, min (length - offset,
+                                                           strlen (
+                                                             body->file.uri)));
+     break;
+   case GNUNET_MESSENGER_KIND_PRIVATE:
++    encode_step (buffer, offset, &(body->privacy.key));
+     encode_step_ext (buffer, offset, body->privacy.data, min (length - offset,
+                                                               body->privacy.
+                                                               length));
+     break;
+   case GNUNET_MESSENGER_KIND_DELETE:
+     encode_step (buffer, offset, &(body->deletion.hash));
+     encode_step (buffer, offset, &(body->deletion.delay));
+     break;
+   default:
+     break;
+   }
+ 
+   if (offset >= length)
+     return;
+ 
+   const uint16_t padding = length - offset;
+   const uint16_t used_padding = sizeof(padding) + sizeof(char);
+ 
+   GNUNET_assert (padding >= used_padding);
+ 
+   buffer[offset++] = '\0';
+ 
+   if (padding > used_padding)
+     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, buffer + offset,
+                                 padding - used_padding);
+ 
+   GNUNET_memcpy (buffer + length - sizeof(padding), &padding, 
sizeof(padding));
+ }
+ 
+ 
+ void
+ encode_message (const struct GNUNET_MESSENGER_Message *message,
+                 uint16_t length,
+                 char *buffer,
+                 int include_header)
+ {
+   GNUNET_assert ((message) && (buffer));
+ 
+   uint16_t offset = 0;
+ 
+   if (GNUNET_YES == include_header)
+     encode_step_signature (buffer, offset, &(message->header.signature),
+                            length);
+ 
+   const kind_t kind = GNUNET_htobe32 ((kind_t) message->header.kind);
+ 
+   if (GNUNET_YES == include_header)
+   {
+     encode_step (buffer, offset, &(message->header.timestamp));
+     encode_step (buffer, offset, &(message->header.sender_id));
+     encode_step (buffer, offset, &(message->header.previous));
+   }
+ 
+   encode_step (buffer, offset, &kind);
+ 
+   encode_message_body (message->header.kind, &(message->body), length, buffer,
+                        offset);
+ }
+ 
+ 
+ static void
+ encode_short_message (const struct GNUNET_MESSENGER_ShortMessage *message,
+                       uint16_t length,
+                       char *buffer)
+ {
+   struct GNUNET_HashCode hash;
+   uint16_t offset = sizeof(hash);
+ 
+   const kind_t kind = GNUNET_htobe32 ((kind_t) message->kind);
+ 
+   encode_step (buffer, offset, &kind);
+ 
+   encode_message_body (message->kind, &(message->body), length, buffer, 
offset);
+ 
+   GNUNET_CRYPTO_hash (
+     buffer + sizeof(hash),
+     length - sizeof(hash),
+     &hash
+     );
+ 
+   GNUNET_memcpy (buffer, &hash, sizeof(hash));
+ }
+ 
+ 
+ #define decode_step_ext(src, offset, dst, size) do { \
 -    GNUNET_memcpy (dst, src + offset, size);            \
 -    offset += size;                                    \
++  GNUNET_memcpy (dst, src + offset, size);           \
++  offset += size;                                    \
+ } while (0)
+ 
 -#define decode_step(src, offset, dst) do {         \
 -    decode_step_ext (src, offset, dst, sizeof(*dst)); \
++#define decode_step(src, offset, dst) do {          \
++  decode_step_ext (src, offset, dst, sizeof(*dst)); \
+ } while (0)
+ 
+ #define decode_step_malloc(src, offset, dst, size, zero) do { \
 -    dst = GNUNET_malloc (size + zero);                           \
 -    if (zero) dst[size] = 0;                                    \
 -    decode_step_ext (src, offset, dst, size);                    \
++  dst = GNUNET_malloc (size + zero);                          \
++  if (zero) dst[size] = 0;                                    \
++    decode_step_ext (src, offset, dst, size);                 \
+ } while (0)
+ 
+ #define decode_step_key(src, offset, dst, length) do {   \
 -    enum GNUNET_GenericReturnValue result;                 \
 -    size_t read;                                           \
 -    result = GNUNET_CRYPTO_read_public_key_from_buffer (  \
 -      src + offset, length - offset, dst, &read            \
 -      );                                                     \
 -    if (GNUNET_SYSERR == result)                                        \
 -    GNUNET_break (0);                                     \
 -    else                                                   \
 -    offset += read;                                    \
++  enum GNUNET_GenericReturnValue result;                 \
++  size_t read;                                           \
++  result = GNUNET_CRYPTO_read_public_key_from_buffer (   \
++    src + offset, length - offset, dst, &read            \
++  );                                                     \
++  if (GNUNET_SYSERR == result)                           \
++    GNUNET_break (0);                                    \
++  else                                                   \
++    offset += read;                                      \
+ } while (0)
+ 
+ static uint16_t
+ decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind,
+                      struct GNUNET_MESSENGER_MessageBody *body,
+                      uint16_t length,
+                      const char *buffer,
+                      uint16_t offset)
+ {
+   uint16_t padding = 0;
+ 
+   GNUNET_memcpy (&padding, buffer + length - sizeof(padding), 
sizeof(padding));
+ 
+   if (padding > length - offset)
+     padding = 0;
+ 
+   const uint16_t end_zero = length - padding;
+ 
+   if ((padding) && (buffer[end_zero] != '\0'))
+     padding = 0;
+ 
+   length -= padding;
+ 
+   uint32_t version;
+   switch (*kind)
+   {
+   case GNUNET_MESSENGER_KIND_INFO: {
 -      decode_step_key (buffer, offset, &(body->info.host_key), length);
+       decode_step (buffer, offset, &version);
+ 
+       body->info.messenger_version = GNUNET_be32toh (version);
+       break;
+     } case GNUNET_MESSENGER_KIND_JOIN: {
+       decode_step_key (buffer, offset, &(body->join.key), length);
+       break;
+     } case GNUNET_MESSENGER_KIND_NAME:
+     if (length - offset > 0)
+       decode_step_malloc (buffer, offset, body->name.name, length - offset, 
1);
+     else
+       body->name.name = NULL;
+     break;
+   case GNUNET_MESSENGER_KIND_KEY:
+     decode_step_key (buffer, offset, &(body->key.key), length);
+     break;
+   case GNUNET_MESSENGER_KIND_PEER:
+     decode_step (buffer, offset, &(body->peer.peer));
+     break;
+   case GNUNET_MESSENGER_KIND_ID:
+     decode_step (buffer, offset, &(body->id.id));
+     break;
+   case GNUNET_MESSENGER_KIND_MISS:
+     decode_step (buffer, offset, &(body->miss.peer));
+     break;
+   case GNUNET_MESSENGER_KIND_MERGE:
+     decode_step (buffer, offset, &(body->merge.previous));
+     break;
+   case GNUNET_MESSENGER_KIND_REQUEST:
+     decode_step (buffer, offset, &(body->request.hash));
+     break;
+   case GNUNET_MESSENGER_KIND_INVITE:
+     decode_step (buffer, offset, &(body->invite.door));
+     decode_step (buffer, offset, &(body->invite.key));
+     break;
+   case GNUNET_MESSENGER_KIND_TEXT:
+     decode_step_malloc (buffer, offset, body->text.text, length - offset, 1);
+     break;
+   case GNUNET_MESSENGER_KIND_FILE:
+     decode_step (buffer, offset, &(body->file.key));
+     decode_step (buffer, offset, &(body->file.hash));
+     decode_step_ext (buffer, offset, body->file.name, 
sizeof(body->file.name));
+     decode_step_malloc (buffer, offset, body->file.uri, length - offset, 1);
+     break;
+   case GNUNET_MESSENGER_KIND_PRIVATE:
++    decode_step (buffer, offset, &(body->privacy.key));
++
+     body->privacy.length = (length - offset);
+     decode_step_malloc (buffer, offset, body->privacy.data, length - offset, 
0);
+     break;
+   case GNUNET_MESSENGER_KIND_DELETE:
+     decode_step (buffer, offset, &(body->deletion.hash));
+     decode_step (buffer, offset, &(body->deletion.delay));
+     break;
+   default:
+     *kind = GNUNET_MESSENGER_KIND_UNKNOWN;
+     break;
+   }
+ 
+   return padding;
+ }
+ 
+ 
+ int
+ decode_message (struct GNUNET_MESSENGER_Message *message,
+                 uint16_t length,
+                 const char *buffer,
+                 int include_header,
+                 uint16_t *padding)
+ {
+   GNUNET_assert (
+     (message) &&
+     (buffer) &&
+     (length >= get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN,
+                                       include_header))
+     );
+ 
+   uint16_t offset = 0;
+ 
+   if (GNUNET_YES == include_header)
+   {
+     ssize_t result = GNUNET_CRYPTO_read_signature_from_buffer (
+       &(message->header.signature), buffer, length - offset
 -      );
++    );
+ 
+     if (result < 0)
+       return GNUNET_NO;
+     else
+       offset += result;
+   }
+ 
+   const uint16_t count = length - offset;
+ 
+   if (count < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN,
+                                      include_header))
+     return GNUNET_NO;
+ 
+   kind_t kind;
+ 
+   if (GNUNET_YES == include_header)
+   {
+     decode_step (buffer, offset, &(message->header.timestamp));
+     decode_step (buffer, offset, &(message->header.sender_id));
+     decode_step (buffer, offset, &(message->header.previous));
+   }
+ 
+   decode_step (buffer, offset, &kind);
+ 
+   message->header.kind = (enum GNUNET_MESSENGER_MessageKind) GNUNET_be32toh (
+     kind);
+ 
+   if (count < get_message_kind_size (message->header.kind, include_header))
+     return GNUNET_NO;
+ 
+   const uint16_t result = decode_message_body (&(message->header.kind),
+                                                &(message->body), length, 
buffer,
+                                                offset);
+ 
+   if (padding)
+     *padding = result;
+ 
+   return GNUNET_YES;
+ }
+ 
+ 
+ static int
+ decode_short_message (struct GNUNET_MESSENGER_ShortMessage *message,
+                       uint16_t length,
+                       const char *buffer)
+ {
+   struct GNUNET_HashCode expected, hash;
+   uint16_t offset = sizeof(hash);
+ 
+   if (length < get_short_message_size (NULL, GNUNET_NO))
+     return GNUNET_NO;
+ 
+   GNUNET_memcpy (&hash, buffer, sizeof(hash));
+ 
+   GNUNET_CRYPTO_hash (
+     buffer + sizeof(hash),
+     length - sizeof(hash),
+     &expected
+     );
+ 
+   if (0 != GNUNET_CRYPTO_hash_cmp (&hash, &expected))
+     return GNUNET_NO;
+ 
+   kind_t kind;
+ 
+   decode_step (buffer, offset, &kind);
+ 
+   message->kind = (enum GNUNET_MESSENGER_MessageKind) GNUNET_be32toh (kind);
+ 
+   if (length < get_short_message_size (message, GNUNET_NO))
+     return GNUNET_NO;
+ 
+   decode_message_body (&(message->kind), &(message->body), length, buffer,
+                        offset);
+ 
+   if (GNUNET_MESSENGER_KIND_UNKNOWN == message->kind)
+     return GNUNET_NO;
+ 
+   return GNUNET_YES;
+ }
+ 
+ 
+ void
+ hash_message (const struct GNUNET_MESSENGER_Message *message,
+               uint16_t length,
+               const char *buffer,
+               struct GNUNET_HashCode *hash)
+ {
+   GNUNET_assert ((message) && (buffer) && (hash));
+ 
+   const ssize_t offset = GNUNET_CRYPTO_signature_get_length (
+     &(message->header.signature)
+     );
+ 
+   GNUNET_CRYPTO_hash (buffer + offset, length - offset, hash);
+ }
+ 
+ 
+ void
+ sign_message (struct GNUNET_MESSENGER_Message *message,
+               uint16_t length,
+               char *buffer,
+               const struct GNUNET_HashCode *hash,
 -              const struct GNUNET_MESSENGER_Ego *ego)
++              const struct GNUNET_CRYPTO_PrivateKey *key)
++{
++  GNUNET_assert ((message) && (buffer) && (hash) && (key));
++
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sign message by member: %s\n",
++              GNUNET_h2s (hash));
++
++  struct GNUNET_MESSENGER_MessageSignature signature;
++
++  signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
++  signature.purpose.size = htonl (sizeof(signature));
++
++  GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode));
++  GNUNET_CRYPTO_sign (key, &signature, &(message->header.signature));
++
++  message->header.signature.type = key->type;
++
++  uint16_t offset = 0;
++  encode_step_signature (buffer, offset, &(message->header.signature), 
length);
++}
++
++
++void
++sign_message_by_peer (struct GNUNET_MESSENGER_Message *message,
++                      uint16_t length,
++                      char *buffer,
++                      const struct GNUNET_HashCode *hash,
++                      const struct GNUNET_CONFIGURATION_Handle *cfg)
+ {
 -  GNUNET_assert ((message) && (buffer) && (hash) && (ego));
++  GNUNET_assert ((message) && (buffer) && (hash) && (cfg));
++
++  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sign message by peer: %s\n",
++              GNUNET_h2s (hash));
+ 
+   struct GNUNET_MESSENGER_MessageSignature signature;
+ 
+   signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
+   signature.purpose.size = htonl (sizeof(signature));
+ 
+   GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode));
 -  GNUNET_CRYPTO_sign (&(ego->priv), &signature, &(message->header.signature));
++  GNUNET_CRYPTO_sign_by_peer_identity (cfg, &signature.purpose,
++                                       &(message->header.signature.
++                                         eddsa_signature));
++
++  message->header.signature.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
+ 
+   uint16_t offset = 0;
+   encode_step_signature (buffer, offset, &(message->header.signature), 
length);
+ }
+ 
+ 
+ int
+ verify_message (const struct GNUNET_MESSENGER_Message *message,
+                 const struct GNUNET_HashCode *hash,
+                 const struct GNUNET_CRYPTO_PublicKey *key)
+ {
+   GNUNET_assert ((message) && (hash) && (key));
+ 
 -  if (ntohl (key->type) != ntohl (message->header.signature.type))
++  if (key->type != message->header.signature.type)
+     return GNUNET_SYSERR;
+ 
+   struct GNUNET_MESSENGER_MessageSignature signature;
+ 
+   signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
+   signature.purpose.size = htonl (sizeof(signature));
+ 
+   GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode));
+ 
+   return GNUNET_CRYPTO_signature_verify (
+     GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature,
+     &(message->header.signature), key);
+ }
+ 
+ 
++int
++verify_message_by_peer (const struct GNUNET_MESSENGER_Message *message,
++                        const struct GNUNET_HashCode *hash,
++                        const struct GNUNET_PeerIdentity *identity)
++{
++  GNUNET_assert ((message) && (hash) && (identity));
++
++  if (ntohl (GNUNET_PUBLIC_KEY_TYPE_EDDSA) != message->header.signature.type)
++    return GNUNET_SYSERR;
++
++  struct GNUNET_MESSENGER_MessageSignature signature;
++
++  signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
++  signature.purpose.size = htonl (sizeof(signature));
++
++  GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode));
++
++  return GNUNET_CRYPTO_verify_peer_identity (
++    GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature.purpose,
++    &(message->header.signature.
++      eddsa_signature), identity);
++}
++
++
+ int
+ encrypt_message (struct GNUNET_MESSENGER_Message *message,
+                  const struct GNUNET_CRYPTO_PublicKey *key)
+ {
+   GNUNET_assert ((message) && (key));
+ 
++  if (GNUNET_YES == is_service_message (message))
++    return GNUNET_NO;
++
+   struct GNUNET_MESSENGER_ShortMessage shortened;
+ 
+   fold_short_message (message, &shortened);
+ 
+   const uint16_t length = get_short_message_size (&shortened, GNUNET_YES);
+   const uint16_t padded_length = calc_padded_length (
+     length + GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES
+     );
+ 
+   message->header.kind = GNUNET_MESSENGER_KIND_PRIVATE;
+   message->body.privacy.data = GNUNET_malloc (padded_length);
+   message->body.privacy.length = padded_length;
+ 
+   const uint16_t encoded_length = (
+     padded_length - GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES
+     );
+ 
+   encode_short_message (&shortened, encoded_length, 
message->body.privacy.data);
+ 
+   if (GNUNET_OK != GNUNET_CRYPTO_encrypt (message->body.privacy.data,
 -                                            encoded_length,
 -                                            key,
 -                                            message->body.privacy.data,
 -                                            padded_length))
++                                          encoded_length,
++                                          key,
++                                          message->body.privacy.data,
++                                          padded_length))
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Encrypting message failed!\n");
+ 
+     unfold_short_message (&shortened, message);
+     return GNUNET_NO;
+   }
+ 
+   destroy_message_body (shortened.kind, &(shortened.body));
+   return GNUNET_YES;
+ }
+ 
+ 
+ int
+ decrypt_message (struct GNUNET_MESSENGER_Message *message,
+                  const struct GNUNET_CRYPTO_PrivateKey *key)
+ {
+   GNUNET_assert ((message) && (key));
+ 
+   const uint16_t padded_length = message->body.privacy.length;
+ 
+   if (padded_length < GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES)
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                 "Message length too short to decrypt!\n");
+ 
+     return GNUNET_NO;
+   }
+ 
+   const uint16_t encoded_length = (
+     padded_length - GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES
+     );
+ 
+   if (GNUNET_OK != GNUNET_CRYPTO_decrypt (message->body.privacy.data,
 -                                            padded_length,
 -                                            key,
 -                                            message->body.privacy.data,
 -                                            encoded_length))
++                                          padded_length,
++                                          key,
++                                          message->body.privacy.data,
++                                          encoded_length))
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Decrypting message failed!\n");
+ 
+     return GNUNET_NO;
+   }
+ 
+   struct GNUNET_MESSENGER_ShortMessage shortened;
+ 
+   if (GNUNET_YES != decode_short_message (&shortened,
+                                           encoded_length,
+                                           message->body.privacy.data))
+   {
+     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                 "Decoding decrypted message failed!\n");
+ 
+     return GNUNET_NO;
+   }
+ 
+   unfold_short_message (&shortened, message);
+   return GNUNET_YES;
+ }
+ 
+ 
+ struct GNUNET_MQ_Envelope*
+ pack_message (struct GNUNET_MESSENGER_Message *message,
+               struct GNUNET_HashCode *hash,
 -              const struct GNUNET_MESSENGER_Ego *ego,
 -              int mode)
++              const GNUNET_MESSENGER_SignFunction sign,
++              int mode,
++              const void *cls)
+ {
+   GNUNET_assert (message);
+ 
 -  if (ego)
 -    message->header.signature.type = ego->priv.type;
 -
 -  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
++  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+               "Packing message kind=%u and sender: %s\n",
+               message->header.kind, GNUNET_sh2s 
(&(message->header.sender_id)));
+ 
+   struct GNUNET_MessageHeader *header;
+ 
+   const uint16_t length = get_message_size (message, GNUNET_YES);
+   const uint16_t padded_length = calc_padded_length (length);
+ 
+   struct GNUNET_MQ_Envelope *env;
+   char *buffer;
+ 
+   if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE == mode)
+   {
+     env = GNUNET_MQ_msg_extra (header, padded_length,
+                                GNUNET_MESSAGE_TYPE_CADET_CLI);
+ 
+     buffer = (char*) &(header[1]);
+   }
+   else
+   {
+     env = NULL;
+ 
+     buffer = GNUNET_malloc (padded_length);
+   }
+ 
+   encode_message (message, padded_length, buffer, GNUNET_YES);
+ 
+   if (hash)
+   {
+     hash_message (message, length, buffer, hash);
+ 
 -    if (ego)
 -      sign_message (message, length, buffer, hash, ego);
++    if (sign)
++      sign (cls, message, length, buffer, hash);
+   }
+ 
+   if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE != mode)
+     GNUNET_free (buffer);
+ 
+   return env;
+ }
+ 
+ 
++int
++is_peer_message (const struct GNUNET_MESSENGER_Message *message)
++{
++  switch (message->header.kind)
++  {
++  case GNUNET_MESSENGER_KIND_INFO:
++  case GNUNET_MESSENGER_KIND_PEER:
++  case GNUNET_MESSENGER_KIND_MISS:
++  case GNUNET_MESSENGER_KIND_MERGE:
++    return GNUNET_YES;
++  default:
++    return GNUNET_NO;
++  }
++}
++
++
++int
++is_service_message (const struct GNUNET_MESSENGER_Message *message)
++{
++  if (GNUNET_YES == is_peer_message (message))
++    return GNUNET_YES;
++
++  switch (message->header.kind)
++  {
++  case GNUNET_MESSENGER_KIND_INFO:
++    return GNUNET_YES; // Reserved for connection handling only!
++  case GNUNET_MESSENGER_KIND_JOIN:
++    return GNUNET_YES; // Reserved for member handling only!
++  case GNUNET_MESSENGER_KIND_LEAVE:
++    return GNUNET_YES; // Reserved for member handling only!
++  case GNUNET_MESSENGER_KIND_NAME:
++    return GNUNET_YES; // Reserved for member name handling only!
++  case GNUNET_MESSENGER_KIND_KEY:
++    return GNUNET_YES; // Reserved for member key handling only!
++  case GNUNET_MESSENGER_KIND_PEER:
++    return GNUNET_YES; // Reserved for connection handling only!
++  case GNUNET_MESSENGER_KIND_ID:
++    return GNUNET_YES; // Reserved for member id handling only!
++  case GNUNET_MESSENGER_KIND_MISS:
++    return GNUNET_YES; // Reserved for connection handling only!
++  case GNUNET_MESSENGER_KIND_MERGE:
++    return GNUNET_YES; // Reserved for peers only!
++  case GNUNET_MESSENGER_KIND_REQUEST:
++    return GNUNET_YES; // Requests should not apply individually! 
(inefficieny)
++  case GNUNET_MESSENGER_KIND_INVITE:
++    return GNUNET_NO;
++  case GNUNET_MESSENGER_KIND_TEXT:
++    return GNUNET_NO;
++  case GNUNET_MESSENGER_KIND_FILE:
++    return GNUNET_NO;
++  case GNUNET_MESSENGER_KIND_PRIVATE:
++    return GNUNET_YES; // Prevent duplicate encryption breaking all access!
++  case GNUNET_MESSENGER_KIND_DELETE:
++    return GNUNET_YES; // Deletion should not apply individually! 
(inefficieny)
++  default:
++    return GNUNET_SYSERR;
++  }
++}
++
++
+ int
+ filter_message_sending (const struct GNUNET_MESSENGER_Message *message)
+ {
++  if (GNUNET_YES == is_peer_message (message))
++    return GNUNET_SYSERR; // Requires signature of peer rather than ego!
++
+   switch (message->header.kind)
+   {
+   case GNUNET_MESSENGER_KIND_INFO:
+     return GNUNET_SYSERR; // Reserved for connection handling only!
+   case GNUNET_MESSENGER_KIND_JOIN:
+     return GNUNET_NO; // Use #GNUNET_MESSENGER_enter_room(...) instead!
+   case GNUNET_MESSENGER_KIND_LEAVE:
+     return GNUNET_NO; // Use #GNUNET_MESSENGER_close_room(...) instead!
+   case GNUNET_MESSENGER_KIND_NAME:
+     return GNUNET_YES;
+   case GNUNET_MESSENGER_KIND_KEY:
 -    return GNUNET_NO; // Use #GNUNET_MESSENGER_update(...) instead!
++    return GNUNET_NO; // Use #GNUNET_MESSENGER_set_key_by_ego(...) instead!
+   case GNUNET_MESSENGER_KIND_PEER:
 -    return GNUNET_NO; // Use #GNUNET_MESSENGER_open_room(...) instead!
++    return GNUNET_SYSERR; // Use #GNUNET_MESSENGER_open_room(...) instead!
+   case GNUNET_MESSENGER_KIND_ID:
 -    return GNUNET_SYSERR; // Reserved for member id handling only!
++    return GNUNET_NO; // Reserved for member id handling only!
+   case GNUNET_MESSENGER_KIND_MISS:
+     return GNUNET_SYSERR; // Reserved for connection handling only!
+   case GNUNET_MESSENGER_KIND_MERGE:
 -    return GNUNET_YES;
++    return GNUNET_SYSERR; // Reserved for peers only!
+   case GNUNET_MESSENGER_KIND_REQUEST:
+     return GNUNET_YES;
+   case GNUNET_MESSENGER_KIND_INVITE:
+     return GNUNET_YES;
+   case GNUNET_MESSENGER_KIND_TEXT:
+     return GNUNET_YES;
+   case GNUNET_MESSENGER_KIND_FILE:
+     return GNUNET_YES;
+   case GNUNET_MESSENGER_KIND_PRIVATE:
+     return GNUNET_NO; // Use #GNUNET_MESSENGER_send_message(...) with a 
contact instead!
+   case GNUNET_MESSENGER_KIND_DELETE:
+     return GNUNET_YES;
+   default:
+     return GNUNET_SYSERR;
+   }
+ }
diff --cc src/service/messenger/messenger_api_message.h
index 000000000,0c2d4acf2..ca507f8c9
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_message.h
+++ b/src/service/messenger/messenger_api_message.h
@@@ -1,0 -1,250 +1,317 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_message.h
+  * @brief messenger api: client and service implementation of GNUnet 
MESSENGER service
+  */
+ 
+ #ifndef GNUNET_MESSENGER_API_MESSAGE_H
+ #define GNUNET_MESSENGER_API_MESSAGE_H
+ 
+ #include "platform.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ #include "gnunet_signatures.h"
+ 
+ #include "gnunet_messenger_service.h"
+ 
 -#include "messenger_api_ego.h"
 -
 -#define GNUNET_MESSENGER_MAX_MESSAGE_SIZE (GNUNET_MAX_MESSAGE_SIZE - 
GNUNET_MIN_MESSAGE_SIZE)
++#define GNUNET_MESSENGER_MAX_MESSAGE_SIZE (GNUNET_MAX_MESSAGE_SIZE \
++                                           - GNUNET_MIN_MESSAGE_SIZE)
+ 
+ #define GNUNET_MESSENGER_PADDING_MIN (sizeof(uint16_t) + sizeof(char))
+ #define GNUNET_MESSENGER_PADDING_LEVEL0 (512)
+ #define GNUNET_MESSENGER_PADDING_LEVEL1 (4096)
+ #define GNUNET_MESSENGER_PADDING_LEVEL2 (32768)
+ 
+ /**
+  * Creates and allocates a new message with a specific <i>kind</i>.
+  *
+  * @param[in] kind Kind of message
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message (enum GNUNET_MESSENGER_MessageKind kind);
+ 
+ /**
+  * Creates and allocates a copy of a given <i>message</i>.
+  *
+  * @param[in] message Message
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ copy_message (const struct GNUNET_MESSENGER_Message *message);
+ 
+ /**
+  * Frees the messages body memory.
+  *
+  * @param[in,out] message Message
+  */
+ void
+ cleanup_message (struct GNUNET_MESSENGER_Message *message);
+ 
+ /**
+  * Destroys a message and frees its memory fully.
+  *
+  * @param[in,out] message Message
+  */
+ void
+ destroy_message (struct GNUNET_MESSENGER_Message *message);
+ 
+ /**
+  * Returns if the message should be bound to a member session.
+  *
+  * @param[in] message Message
+  * @return #GNUNET_YES or #GNUNET_NO
+  */
+ int
+ is_message_session_bound (const struct GNUNET_MESSENGER_Message *message);
+ 
+ /**
+  * Returns the minimal size in bytes to encode a message of a specific 
<i>kind</i>.
+  *
+  * @param[in] kind Kind of message
+  * @param[in] include_header Flag to include header
+  * @return Minimal size to encode
+  */
+ uint16_t
+ get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind,
+                        int include_header);
+ 
+ /**
+  * Returns the exact size in bytes to encode a given <i>message</i>.
+  *
+  * @param[in] message Message
+  * @param[in] include_header Flag to include header
+  * @return Size to encode
+  */
+ uint16_t
+ get_message_size (const struct GNUNET_MESSENGER_Message *message,
+                   int include_header);
+ 
+ /**
+  * Encodes a given <i>message</i> into a <i>buffer</i> of a maximal 
<i>length</i> in bytes.
+  *
+  * @param[in] message Message
+  * @param[in] length Maximal length to encode
+  * @param[out] buffer Buffer
+  * @param[in] include_header Flag to include header
+  */
+ void
+ encode_message (const struct GNUNET_MESSENGER_Message *message,
+                 uint16_t length,
+                 char *buffer,
+                 int include_header);
+ 
+ /**
+  * Decodes a <i>message</i> from a given <i>buffer</i> of a maximal 
<i>length</i> in bytes.
+  *
+  * If the buffer is too small for a message of its decoded kind the function 
fails with
+  * resulting #GNUNET_NO after decoding only the messages header.
+  *
+  * On success the function returns #GNUNET_YES.
+  *
+  * @param[out] message Message
+  * @param[in] length Maximal length to decode
+  * @param[in] buffer Buffer
+  * @param[in] include_header Flag to include header
+  * @param[out] padding Padding
+  * @return #GNUNET_YES on success, otherwise #GNUNET_NO
+  */
+ int
+ decode_message (struct GNUNET_MESSENGER_Message *message,
+                 uint16_t length,
+                 const char *buffer,
+                 int include_header,
+                 uint16_t *padding);
+ 
+ /**
+  * Calculates a <i>hash</i> of a given <i>buffer</i> with a <i>length</i> in 
bytes
+  * from a <i>message</i>.
+  *
+  * @param[in] message Message
+  * @param[in] length Length of buffer
+  * @param[in] buffer Buffer
+  * @param[out] hash Hash
+  */
+ void
+ hash_message (const struct GNUNET_MESSENGER_Message *message,
+               uint16_t length,
+               const char *buffer,
+               struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Signs the <i>hash</i> of a <i>message</i> with a given <i>ego</i> and 
writes the signature
+  * into the <i>buffer</i> as well.
+  *
+  * @param[in,out] message Message
+  * @param[in] length Length of buffer
+  * @param[out] buffer Buffer
+  * @param[in] hash Hash of message
 - * @param[in] ego EGO
++ * @param[in] key Private key of EGO
+  */
+ void
+ sign_message (struct GNUNET_MESSENGER_Message *message,
+               uint16_t length,
+               char *buffer,
+               const struct GNUNET_HashCode *hash,
 -              const struct GNUNET_MESSENGER_Ego *ego);
++              const struct GNUNET_CRYPTO_PrivateKey *key);
++
++/**
++ * Signs the <i>hash</i> of a <i>message</i> with the peer identity of a 
given <i>config</i>
++ * and writes the signature into the <i>buffer</i> as well.
++ *
++ * @param[in,out] message Message
++ * @param[in] length Length of buffer
++ * @param[out] buffer Buffer
++ * @param[in] hash Hash of message
++ * @param[in] cfg Peer configuration
++ */
++void
++sign_message_by_peer (struct GNUNET_MESSENGER_Message *message,
++                      uint16_t length,
++                      char *buffer,
++                      const struct GNUNET_HashCode *hash,
++                      const struct GNUNET_CONFIGURATION_Handle *cfg);
+ 
+ /**
+  * Verifies the signature of a given <i>message</i> and its <i>hash</i> with 
a specific
+  * public key. The function returns #GNUNET_OK if the signature was valid, 
otherwise
+  * #GNUNET_SYSERR.
+  *
+  * @param[in] message Message
+  * @param[in] hash Hash of message
+  * @param[in] key Public key of EGO
+  * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR
+  */
+ int
+ verify_message (const struct GNUNET_MESSENGER_Message *message,
+                 const struct GNUNET_HashCode *hash,
+                 const struct GNUNET_CRYPTO_PublicKey *key);
+ 
++/**
++ * Verifies the signature of a given <i>message</i> and its <i>hash</i> with 
a specific
++ * peer's <i>identity</i>. The function returns #GNUNET_OK if the signature 
was valid,
++ * otherwise #GNUNET_SYSERR.
++ *
++ * @param[in] message Message
++ * @param[in] hash Hash of message
++ * @param[in] identity Peer identity
++ * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR
++ */
++int
++verify_message_by_peer (const struct GNUNET_MESSENGER_Message *message,
++                        const struct GNUNET_HashCode *hash,
++                        const struct GNUNET_PeerIdentity *identity);
++
+ /**
+  * Encrypts a <i>message</i> using a given public <i>key</i> and replaces its 
body
+  * and kind with the now private encrypted <i>message</i>. The function 
returns
+  * #GNUNET_YES if the operation succeeded, otherwise #GNUNET_NO.
+  *
+  * @param[in,out] message Message
+  * @param[in] key Public key of EGO
+  * @return #GNUNET_YES on success, otherwise #GNUNET_NO
+  */
+ int
+ encrypt_message (struct GNUNET_MESSENGER_Message *message,
+                  const struct GNUNET_CRYPTO_PublicKey *key);
+ 
+ /**
+  * Decrypts a private <i>message</i> using a given private <i>key</i> and 
replaces its body
+  * and kind with the inner encrypted message. The function returns 
#GNUNET_YES if the
+  * operation succeeded, otherwise #GNUNET_NO.
+  *
+  * @param[in,out] message Message
+  * @param[in] key Private key of EGO
+  * @return #GNUNET_YES on success, otherwise #GNUNET_NO
+  */
+ int
+ decrypt_message (struct GNUNET_MESSENGER_Message *message,
+                  const struct GNUNET_CRYPTO_PrivateKey *key);
+ 
++typedef void (*GNUNET_MESSENGER_SignFunction)(
++  const void *cls,
++  struct GNUNET_MESSENGER_Message *message,
++  uint16_t length,
++  char *buffer,
++  const struct GNUNET_HashCode *hash
++  );
++
+ #define GNUNET_MESSENGER_PACK_MODE_ENVELOPE 0x1
+ #define GNUNET_MESSENGER_PACK_MODE_UNKNOWN 0x0
+ 
+ /**
+  * Encodes the <i>message</i> to pack it into a newly allocated envelope if 
<i>mode</i>
+  * is equal to #GNUNET_MESSENGER_PACK_MODE_ENVELOPE. Independent of the mode 
the message
 - * will be hashed if <i>hash</i> is not NULL and it will be signed if the 
<i>ego</i> is
 - * not NULL.
++ * will be hashed if <i>hash</i> is not NULL and it will be signed if the 
<i>sign</i>
++ * function is not NULL.
+  *
+  * @param[out] message Message
+  * @param[out] hash Hash of message
 - * @param[in] ego EGO to sign
++ * @param[in] sign Function to sign
+  * @param[in] mode Mode of packing
++ * @param[in,out] cls Closure for signing
+  * @return Envelope or NULL
+  */
+ struct GNUNET_MQ_Envelope*
+ pack_message (struct GNUNET_MESSENGER_Message *message,
+               struct GNUNET_HashCode *hash,
 -              const struct GNUNET_MESSENGER_Ego *ego,
 -              int mode);
++              const GNUNET_MESSENGER_SignFunction sign,
++              int mode,
++              const void *cls);
++
++/**
++ * Returns whether a specific kind of message can be sent by the service 
without usage of a
++ * clients EGO. The function returns #GNUNET_YES if the kind of message can 
be signed
++ * via a peer's identity, otherwise #GNUNET_NO.
++ *
++ * @param[in] message Message
++ * @return #GNUNET_YES if sending is allowed, #GNUNET_NO otherwise
++ */
++int
++is_peer_message (const struct GNUNET_MESSENGER_Message *message);
++
++/**
++ * Returns whether a specific kind of message contains service critical 
information. That kind
++ * of information should not be encrypted via private messages for example to 
guarantee the
++ * service to work properly. The function returns #GNUNET_YES if the kind of 
message needs to
++ * be transferred accessible to all peers and their running service. It 
returns #GNUNET_NO
++ * if the message can be encrypted to specific subgroups of members without 
issues. If the kind
++ * of message is unknown it returns #GNUNET_SYSERR.
++ *
++ * @param[in] message Message
++ * @return #GNUNET_YES if encrypting is disallowed, #GNUNET_NO or 
#GNUNET_SYSERR otherwise
++ */
++int
++is_service_message (const struct GNUNET_MESSENGER_Message *message);
+ 
+ /**
 - * Returns if a specific kind of message should be sent by a client. The 
function returns
++ * Returns whether a specific kind of message should be sent by a client. The 
function returns
+  * #GNUNET_YES or #GNUNET_NO for recommendations and #GNUNET_SYSERR for 
specific kinds
+  * of messages which should not be sent manually at all.
+  *
+  * @param[in] message Message
++ * @return #GNUNET_YES if sending is allowed, #GNUNET_NO or #GNUNET_SYSERR 
otherwise
+  */
+ int
+ filter_message_sending (const struct GNUNET_MESSENGER_Message *message);
+ 
+ #endif //GNUNET_MESSENGER_API_MESSAGE_H
diff --cc src/service/messenger/messenger_api_message_kind.c
index 000000000,000000000..d2c11bbc5
new file mode 100644
--- /dev/null
+++ b/src/service/messenger/messenger_api_message_kind.c
@@@ -1,0 -1,0 +1,190 @@@
++/*
++   This file is part of GNUnet.
++   Copyright (C) 2020--2023 GNUnet e.V.
++
++   GNUnet is free software: you can redistribute it and/or modify it
++   under the terms of the GNU Affero General Public License as published
++   by the Free Software Foundation, either version 3 of the License,
++   or (at your option) any later version.
++
++   GNUnet is distributed in the hope that it will be useful, but
++   WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Affero General Public License for more details.
++
++   You should have received a copy of the GNU Affero General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.
++
++   SPDX-License-Identifier: AGPL3.0-or-later
++ */
++/**
++ * @author Tobias Frisch
++ * @file src/messenger/gnunet-service-messenger_message_kind.c
++ * @brief GNUnet MESSENGER service
++ */
++
++#include "messenger_api_message_kind.h"
++
++#include "platform.h"
++#include "messenger_api_util.h"
++
++struct GNUNET_MESSENGER_Message*
++create_message_join (const struct GNUNET_CRYPTO_PrivateKey *key)
++{
++  if (! key)
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = create_message (
++    GNUNET_MESSENGER_KIND_JOIN);
++
++  if (! message)
++    return NULL;
++
++  GNUNET_CRYPTO_key_get_public (key, &(message->body.join.key));
++  return message;
++}
++
++
++struct GNUNET_MESSENGER_Message*
++create_message_leave ()
++{
++  return create_message (GNUNET_MESSENGER_KIND_LEAVE);
++}
++
++
++struct GNUNET_MESSENGER_Message*
++create_message_name (const char *name)
++{
++  if (! name)
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = create_message (
++    GNUNET_MESSENGER_KIND_NAME);
++
++  if (! message)
++    return NULL;
++
++  message->body.name.name = GNUNET_strdup (name);
++  return message;
++}
++
++
++struct GNUNET_MESSENGER_Message*
++create_message_key (const struct GNUNET_CRYPTO_PrivateKey *key)
++{
++  if (! key)
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = create_message (
++    GNUNET_MESSENGER_KIND_KEY);
++
++  if (! message)
++    return NULL;
++
++  GNUNET_CRYPTO_key_get_public (key, &(message->body.key.key));
++  return message;
++}
++
++
++struct GNUNET_MESSENGER_Message*
++create_message_id (const struct GNUNET_ShortHashCode *unique_id)
++{
++  if (! unique_id)
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = create_message (
++    GNUNET_MESSENGER_KIND_ID);
++
++  if (! message)
++    return NULL;
++
++  GNUNET_memcpy (&(message->body.id.id), unique_id, sizeof(struct
++                                                           
GNUNET_ShortHashCode));
++
++  return message;
++}
++
++
++struct GNUNET_MESSENGER_Message*
++create_message_request (const struct GNUNET_HashCode *hash)
++{
++  if (! hash)
++    return NULL;
++
++  struct GNUNET_HashCode zero;
++  memset (&zero, 0, sizeof(zero));
++
++  if (0 == GNUNET_CRYPTO_hash_cmp (hash, &zero))
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = create_message (
++    GNUNET_MESSENGER_KIND_REQUEST);
++
++  if (! message)
++    return NULL;
++
++  GNUNET_memcpy (&(message->body.request.hash), hash, sizeof(struct
++                                                             
GNUNET_HashCode));
++
++  return message;
++}
++
++
++struct GNUNET_MESSENGER_Message*
++create_message_invite (const struct GNUNET_PeerIdentity *door,
++                       const struct GNUNET_HashCode *key)
++{
++  if ((! door) || (! key))
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = create_message (
++    GNUNET_MESSENGER_KIND_INVITE);
++
++  if (! message)
++    return NULL;
++
++  GNUNET_memcpy (&(message->body.invite.door), door, sizeof(struct
++                                                            
GNUNET_PeerIdentity));
++  GNUNET_memcpy (&(message->body.invite.key), key, sizeof(struct
++                                                          GNUNET_HashCode));
++
++  return message;
++}
++
++
++struct GNUNET_MESSENGER_Message*
++create_message_text (const char *text)
++{
++  if (! text)
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = create_message (
++    GNUNET_MESSENGER_KIND_TEXT);
++
++  if (! message)
++    return NULL;
++
++  message->body.text.text = GNUNET_strdup (text);
++  return message;
++}
++
++
++struct GNUNET_MESSENGER_Message*
++create_message_delete (const struct GNUNET_HashCode *hash,
++                       const struct GNUNET_TIME_Relative delay)
++{
++  if (! hash)
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = create_message (
++    GNUNET_MESSENGER_KIND_DELETE);
++
++  if (! message)
++    return NULL;
++
++  GNUNET_memcpy (&(message->body.deletion.hash), hash, sizeof(struct
++                                                              
GNUNET_HashCode));
++  message->body.deletion.delay = GNUNET_TIME_relative_hton (delay);
++
++  return message;
++}
diff --cc src/service/messenger/messenger_api_message_kind.h
index 000000000,d50317844..5a544a41b
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_message_kind.h
+++ b/src/service/messenger/messenger_api_message_kind.h
@@@ -1,0 -1,173 +1,130 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/gnunet-service-messenger_message_kind.h
+  * @brief GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H
+ #define GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H
+ 
+ #include "platform.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ #include "gnunet_time_lib.h"
+ 
+ #include "messenger_api_message.h"
+ #include "gnunet-service-messenger_service.h"
 -#include "messenger_api_ego.h"
+ 
+ /**
 - * Creates and allocates a new info message containing the hosts EGO public 
key and a newly generated unique member id.
++ * Creates and allocates a new join message containing the clients EGO public 
<i>key</i>.
+  * (all values are stored as copy)
+  *
 - * @param[in] ego EGO of the host
 - * @param[in] members Map of all assigned member ids
 - * @return New message
 - */
 -struct GNUNET_MESSENGER_Message*
 -create_message_info (const struct GNUNET_MESSENGER_Ego *ego);
 -
 -/**
 - * Creates and allocates a new join message containing the clients EGO public 
key.
 - * (all values are stored as copy)
 - *
 - * @param[in] ego EGO of the client
++ * @param[in] key Private key of EGO
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
 -create_message_join (const struct GNUNET_MESSENGER_Ego *ego);
++create_message_join (const struct GNUNET_CRYPTO_PrivateKey *key);
+ 
+ /**
+  * Creates and allocates a new leave message.
+  *
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message_leave ();
+ 
+ /**
+  * Creates and allocates a new name message containing the <i>name</i> to 
change to.
+  * (all values are stored as copy)
+  *
+  * @param[in] name New name
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message_name (const char *name);
+ 
+ /**
+  * Creates and allocates a new key message containing the public <i>key</i> 
to change to derived
+  * from its private counterpart. (all values are stored as copy)
+  *
+  * @param[in] key Private key of EGO
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message_key (const struct GNUNET_CRYPTO_PrivateKey *key);
+ 
 -/**
 - * Creates and allocates a new peer message containing a services peer 
identity.
 - * (all values are stored as copy)
 - *
 - * @param[in] service Service
 - * @return New message
 - */
 -struct GNUNET_MESSENGER_Message*
 -create_message_peer (const struct GNUNET_MESSENGER_Service *service);
 -
+ /**
+  * Creates and allocates a new id message containing the unique member id to 
change to.
+  * (all values are stored as copy)
+  *
+  * @param[in] unique_id Unique member id
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message_id (const struct GNUNET_ShortHashCode *unique_id);
+ 
 -/**
 - * Creates and allocates a new miss message containing the missing 
<i>peer</i> identity.
 - * (all values are stored as copy)
 - *
 - * @param[in] peer Missing peer identity
 - * @return New message
 - */
 -struct GNUNET_MESSENGER_Message*
 -create_message_miss (const struct GNUNET_PeerIdentity *peer);
 -
 -/**
 - * Creates and allocates a new merge message containing the hash of a second 
<i>previous</i> message
 - * besides the regular previous message mentioned in a messages header.
 - * (all values are stored as copy)
 - *
 - * @param[in] previous Hash of message
 - * @return New message
 - */
 -struct GNUNET_MESSENGER_Message*
 -create_message_merge (const struct GNUNET_HashCode *previous);
 -
+ /**
+  * Creates and allocates a new request message containing the <i>hash</i> of 
a missing message.
+  * (all values are stored as copy)
+  *
+  * @param[in] hash Hash of message
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message_request (const struct GNUNET_HashCode *hash);
+ 
+ /**
+  * Creates and allocates a new invite message containing the peer identity of 
an entrance peer
+  * to a room using a given <i>key</i> as shared secret for communication.
+  * (all values are stored as copy)
+  *
+  * @param[in] door Peer identity
+  * @param[in] key Shared secret of a room
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message_invite (const struct GNUNET_PeerIdentity *door,
+                        const struct GNUNET_HashCode *key);
+ 
+ /**
+  * Creates and allocates a new <i>text</i> message containing a string 
representing text.
+  * (all values are stored as copy)
+  *
+  * @param[in] text Text
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message_text (const char *text);
+ 
+ /**
+  * Creates and allocates a new delete message containing the <i>hash</i> of a 
message to delete after a specific <i>delay</i>.
+  * (all values are stored as copy)
+  *
+  * @param[in] hash Hash of message
+  * @param[in] delay Delay of deletion
+  * @return New message
+  */
+ struct GNUNET_MESSENGER_Message*
+ create_message_delete (const struct GNUNET_HashCode *hash,
+                        const struct GNUNET_TIME_Relative delay);
+ 
+ #endif //GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H
diff --cc src/service/messenger/messenger_api_peer_store.c
index 949510960,000000000..949510960
mode 100644,000000..100644
--- a/src/service/messenger/messenger_api_peer_store.c
+++ b/src/service/messenger/messenger_api_peer_store.c
diff --cc src/service/messenger/messenger_api_peer_store.h
index f4f948cb9,000000000..f4f948cb9
mode 100644,000000..100644
--- a/src/service/messenger/messenger_api_peer_store.h
+++ b/src/service/messenger/messenger_api_peer_store.h
diff --cc src/service/messenger/messenger_api_queue_messages.c
index 000000000,000000000..f6a69366c
new file mode 100644
--- /dev/null
+++ b/src/service/messenger/messenger_api_queue_messages.c
@@@ -1,0 -1,0 +1,108 @@@
++/*
++   This file is part of GNUnet.
++   Copyright (C) 2023 GNUnet e.V.
++
++   GNUnet is free software: you can redistribute it and/or modify it
++   under the terms of the GNU Affero General Public License as published
++   by the Free Software Foundation, either version 3 of the License,
++   or (at your option) any later version.
++
++   GNUnet is distributed in the hope that it will be useful, but
++   WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Affero General Public License for more details.
++
++   You should have received a copy of the GNU Affero General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.
++
++   SPDX-License-Identifier: AGPL3.0-or-later
++ */
++/**
++ * @author Tobias Frisch
++ * @file src/messenger/messenger_api_queue_messages.c
++ * @brief messenger api: client implementation of GNUnet MESSENGER service
++ */
++
++#include "messenger_api_queue_messages.h"
++
++void
++init_queue_messages (struct GNUNET_MESSENGER_QueueMessages *messages)
++{
++  GNUNET_assert (messages);
++
++  messages->head = NULL;
++  messages->tail = NULL;
++}
++
++
++void
++clear_queue_messages (struct GNUNET_MESSENGER_QueueMessages *messages)
++{
++  GNUNET_assert (messages);
++
++  while (messages->head)
++  {
++    struct GNUNET_MESSENGER_QueueMessage *element = messages->head;
++
++    GNUNET_CONTAINER_DLL_remove (messages->head, messages->tail, element);
++
++    if (element->message)
++      destroy_message (element->message);
++
++    GNUNET_free (element);
++  }
++
++  messages->head = NULL;
++  messages->tail = NULL;
++}
++
++
++void
++enqueue_to_messages (struct GNUNET_MESSENGER_QueueMessages *messages,
++                     const struct GNUNET_CRYPTO_PrivateKey *sender,
++                     const struct GNUNET_MESSENGER_Message *message)
++{
++  GNUNET_assert ((messages) && (message));
++
++  struct GNUNET_MESSENGER_QueueMessage *element = GNUNET_new (struct
++                                                              
GNUNET_MESSENGER_QueueMessage);
++
++  if (! element)
++    return;
++
++  element->message = copy_message (message);
++
++  if (sender)
++    GNUNET_memcpy (&(element->sender), sender, sizeof (element->sender));
++
++  if (! element->message)
++  {
++    GNUNET_free (element);
++    return;
++  }
++
++  GNUNET_CONTAINER_DLL_insert_tail (messages->head, messages->tail, element);
++}
++
++
++struct GNUNET_MESSENGER_Message*
++dequeue_from_messages (struct GNUNET_MESSENGER_QueueMessages *messages,
++                       struct GNUNET_CRYPTO_PrivateKey *sender)
++{
++  GNUNET_assert (messages);
++
++  struct GNUNET_MESSENGER_QueueMessage *element = messages->head;
++
++  if (! element)
++    return NULL;
++
++  struct GNUNET_MESSENGER_Message *message = element->message;
++
++  GNUNET_CONTAINER_DLL_remove (messages->head, messages->tail, element);
++
++  if (sender)
++    GNUNET_memcpy (sender, &(element->sender), sizeof (*sender));
++
++  GNUNET_free (element);
++  return message;
++}
diff --cc src/service/messenger/messenger_api_queue_messages.h
index 000000000,000000000..e0b6010fa
new file mode 100644
--- /dev/null
+++ b/src/service/messenger/messenger_api_queue_messages.h
@@@ -1,0 -1,0 +1,89 @@@
++/*
++   This file is part of GNUnet.
++   Copyright (C) 2023 GNUnet e.V.
++
++   GNUnet is free software: you can redistribute it and/or modify it
++   under the terms of the GNU Affero General Public License as published
++   by the Free Software Foundation, either version 3 of the License,
++   or (at your option) any later version.
++
++   GNUnet is distributed in the hope that it will be useful, but
++   WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Affero General Public License for more details.
++
++   You should have received a copy of the GNU Affero General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.
++
++   SPDX-License-Identifier: AGPL3.0-or-later
++ */
++/**
++ * @author Tobias Frisch
++ * @file src/messenger/messenger_api_queue_messages.h
++ * @brief messenger api: client implementation of GNUnet MESSENGER service
++ */
++
++#ifndef GNUNET_MESSENGER_API_QUEUE_MESSAGES_H
++#define GNUNET_MESSENGER_API_QUEUE_MESSAGES_H
++
++#include "platform.h"
++#include "gnunet_identity_service.h"
++#include "gnunet_util_lib.h"
++
++#include "messenger_api_message.h"
++
++struct GNUNET_MESSENGER_QueueMessage
++{
++  struct GNUNET_MESSENGER_QueueMessage *prev;
++  struct GNUNET_MESSENGER_QueueMessage *next;
++
++  struct GNUNET_CRYPTO_PrivateKey sender;
++  struct GNUNET_MESSENGER_Message *message;
++};
++
++struct GNUNET_MESSENGER_QueueMessages
++{
++  struct GNUNET_MESSENGER_QueueMessage *head;
++  struct GNUNET_MESSENGER_QueueMessage *tail;
++};
++
++/**
++ * Initializes queue of messages as empty queue.
++ *
++ * @param[out] messages Queue of messages
++ */
++void
++init_queue_messages (struct GNUNET_MESSENGER_QueueMessages *messages);
++
++/**
++ * Clears the queue of messages.
++ *
++ * @param[in,out] messages Queue of messages
++ */
++void
++clear_queue_messages (struct GNUNET_MESSENGER_QueueMessages *messages);
++
++/**
++ * Adds a specific <i>message</i> to the end of the queue.
++ *
++ * @param[in,out] messages Queue of messages
++ * @param[in] sender Private sender key
++ * @param[in] message Message
++ */
++void
++enqueue_to_messages (struct GNUNET_MESSENGER_QueueMessages *messages,
++                     const struct GNUNET_CRYPTO_PrivateKey *sender,
++                     const struct GNUNET_MESSENGER_Message *message);
++
++/**
++ * Remove the message from the front of the queue and returns it.
++ *
++ * @param[in,out] messages Queue of messages
++ * @param[out] sender Private sender key
++ * @return Message from front or NULL
++ */
++struct GNUNET_MESSENGER_Message*
++dequeue_from_messages (struct GNUNET_MESSENGER_QueueMessages *messages,
++                       struct GNUNET_CRYPTO_PrivateKey *sender);
++
++#endif //GNUNET_MESSENGER_API_QUEUE_MESSAGES_H
diff --cc src/service/messenger/messenger_api_util.c
index 000000000,9d23e2262..c098ae3d9
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_util.c
+++ b/src/service/messenger/messenger_api_util.c
@@@ -1,0 -1,103 +1,127 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_util.c
+  * @brief messenger api: client implementation of GNUnet MESSENGER service
+  */
+ 
+ #include "platform.h"
+ #include "messenger_api_util.h"
+ 
+ static void
+ callback_close_channel (void *cls)
+ {
+   struct GNUNET_CADET_Channel *channel = cls;
+ 
+   if (channel)
+     GNUNET_CADET_channel_destroy (channel);
+ }
+ 
++
+ void
+ delayed_disconnect_channel (struct GNUNET_CADET_Channel *channel)
+ {
 -  GNUNET_assert(channel);
++  GNUNET_assert (channel);
+ 
+   GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_get_zero_ 
(),
+                                               
GNUNET_SCHEDULER_PRIORITY_URGENT,
+                                               callback_close_channel, 
channel);
+ }
+ 
++
+ int
+ generate_free_member_id (struct GNUNET_ShortHashCode *id,
+                          const struct GNUNET_CONTAINER_MultiShortmap *members)
+ {
 -  GNUNET_assert(id);
++  GNUNET_assert (id);
+ 
 -  size_t counter = 1 + (members ? GNUNET_CONTAINER_multishortmap_size 
(members) : 0);
++  size_t counter = 1 + (members ? GNUNET_CONTAINER_multishortmap_size (
++                          members) : 0);
+ 
+   do
+   {
 -    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, id, 
sizeof(struct GNUNET_ShortHashCode));
++    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, id, 
sizeof(struct
++                                                                         
GNUNET_ShortHashCode));
+ 
 -    if ((members) && (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains 
(members, id)))
++    if ((members) && (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
++                        members, id)))
+       counter--;
+     else
+       break;
+   }
+   while (counter > 0);
+ 
+   if (counter)
+     return GNUNET_YES;
+ 
+   return GNUNET_NO;
+ }
+ 
++
++const struct GNUNET_CRYPTO_PrivateKey*
++get_anonymous_private_key ()
++{
++  const struct GNUNET_IDENTITY_Ego *ego = GNUNET_IDENTITY_ego_get_anonymous 
();
++  return GNUNET_IDENTITY_ego_get_private_key (ego);
++}
++
++
+ const struct GNUNET_CRYPTO_PublicKey*
+ get_anonymous_public_key ()
+ {
+   static struct GNUNET_CRYPTO_PublicKey public_key;
 -  static struct GNUNET_IDENTITY_Ego* ego = NULL;
++  static struct GNUNET_IDENTITY_Ego *ego = NULL;
+ 
 -  if (!ego)
++  if (! ego)
+   {
 -    ego = GNUNET_IDENTITY_ego_get_anonymous();
 -    GNUNET_IDENTITY_ego_get_public_key(ego, &public_key);
++    ego = GNUNET_IDENTITY_ego_get_anonymous ();
++    GNUNET_IDENTITY_ego_get_public_key (ego, &public_key);
+   }
+ 
+   return &public_key;
+ }
+ 
++
+ void
 -convert_messenger_key_to_port(const struct GNUNET_HashCode *key,
 -                              struct GNUNET_HashCode *port)
++convert_messenger_key_to_port (const struct GNUNET_HashCode *key,
++                               struct GNUNET_HashCode *port)
+ {
+   static uint32_t version_value = 0;
+   static struct GNUNET_HashCode version;
+ 
 -  if (!version_value) {
++  if (! version_value)
++  {
+     version_value = (uint32_t) (GNUNET_MESSENGER_VERSION);
+     version_value = ((version_value >> 16) & 0xFFFF);
 -    version_value = GNUNET_htole32(version_value);
 -    GNUNET_CRYPTO_hash(&version_value, sizeof(version_value), &version);
++    version_value = GNUNET_htole32 (version_value);
++    GNUNET_CRYPTO_hash (&version_value, sizeof(version_value), &version);
+   }
+ 
 -  GNUNET_CRYPTO_hash_sum(key, &version, port);
++  GNUNET_CRYPTO_hash_sum (key, &version, port);
++}
++
++
++void
++convert_peer_identity_to_id (const struct GNUNET_PeerIdentity *identity,
++                             struct GNUNET_ShortHashCode *id)
++{
++  GNUNET_memcpy (id, identity, sizeof(struct GNUNET_ShortHashCode));
+ }
diff --cc src/service/messenger/messenger_api_util.h
index 000000000,bad001da3..a85a12686
mode 000000,100644..100644
--- a/src/service/messenger/messenger_api_util.h
+++ b/src/service/messenger/messenger_api_util.h
@@@ -1,0 -1,78 +1,98 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @author Tobias Frisch
+  * @file src/messenger/messenger_api_util.h
+  * @brief messenger api: client implementation of GNUnet MESSENGER service
+  */
+ 
+ #ifndef GNUNET_SERVICE_MESSENGER_UTIL_H
+ #define GNUNET_SERVICE_MESSENGER_UTIL_H
+ 
+ #include "platform.h"
+ #include "gnunet_cadet_service.h"
+ #include "gnunet_util_lib.h"
+ #include "gnunet_identity_service.h"
+ #include "gnunet_messenger_service.h"
+ 
+ /**
+  * Starts an urgent task to close a CADET channel asynchronously.
+  *
+  * @param[in,out] channel Channel
+  */
+ void
+ delayed_disconnect_channel (struct GNUNET_CADET_Channel *channel);
+ 
+ /**
+  * Tries to generate an unused member id and store it into the <i>id</i> 
parameter.
+  * A map containing all currently used member ids is used to check against.
+  *
+  * @param[out] id New member id
+  * @param[in] members Map of member ids
+  * @return #GNUNET_YES on success, #GNUNET_NO on failure
+  */
+ int
+ generate_free_member_id (struct GNUNET_ShortHashCode *id,
+                          const struct GNUNET_CONTAINER_MultiShortmap 
*members);
+ 
++/**
++ * Returns the private identity key of #GNUNET_IDENTITY_ego_get_anonymous() 
without
++ * recalculating it every time.
++ *
++ * @return anonymous private key
++ */
++const struct GNUNET_CRYPTO_PrivateKey*
++get_anonymous_private_key ();
++
+ /**
+  * Returns the public identity key of #GNUNET_IDENTITY_ego_get_anonymous() 
without
+  * recalculating it every time.
+  *
+  * @return anonymous public key
+  */
+ const struct GNUNET_CRYPTO_PublicKey*
+ get_anonymous_public_key ();
+ 
+ /**
+  * Converts a Messenger service key of a room to the specific port which
+  * gets used for the CADET channels.
+  *
+  * The port includes upper bits of the #GNUNET_MESSENGER_VERSION to
+  * reduce the chance of incompatible connections.
+  *
+  * @param[in] key Messenger service room key
+  * @param[out] port CADET service port
+  */
+ void
 -convert_messenger_key_to_port(const struct GNUNET_HashCode *key,
 -                              struct GNUNET_HashCode *port);
++convert_messenger_key_to_port (const struct GNUNET_HashCode *key,
++                               struct GNUNET_HashCode *port);
++
++/**
++ * Converts a peers identity to a short hash code which can be used
++ * as id to refer to a peer via sender id as attached in messages.
++ *
++ * @param[in] identity Peer identity
++ * @param[out] id Short peer id
++ */
++void
++convert_peer_identity_to_id (const struct GNUNET_PeerIdentity *identity,
++                             struct GNUNET_ShortHashCode *id);
+ 
+ #endif //GNUNET_SERVICE_MESSENGER_UTIL_H
diff --cc src/service/messenger/test_messenger.c
index 000000000,660e6473c..4d85e984f
mode 000000,100644..100644
--- a/src/service/messenger/test_messenger.c
+++ b/src/service/messenger/test_messenger.c
@@@ -1,0 -1,181 +1,217 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @file messenger/test_messenger.c
+  * @author Tobias Frisch
+  * @brief Test for the messenger service using cadet API.
+  */
+ #include "platform.h"
+ #include <stdio.h>
+ #include "gnunet_util_lib.h"
+ #include "gnunet_testing_lib.h"
+ #include "gnunet_messenger_service.h"
+ 
+ /**
+  * How long until we really give up on a particular testcase portion?
+  */
+ #define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, \
+                                                      60)
+ 
+ /**
+  * How long until we give up on any particular operation (and retry)?
+  */
+ #define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
5)
+ 
+ #define TESTER_NAME "tester"
+ 
+ static int status = 1;
+ 
+ static struct GNUNET_SCHEDULER_Task *die_task = NULL;
+ static struct GNUNET_SCHEDULER_Task *op_task = NULL;
++static struct GNUNET_SCHEDULER_Task *it_task = NULL;
+ 
+ struct GNUNET_MESSENGER_Handle *messenger = NULL;
+ 
++static struct GNUNET_CRYPTO_PrivateKey identity;
++
+ static void
+ end (void *cls)
+ {
+   die_task = NULL;
+ 
++  if (it_task)
++  {
++    GNUNET_SCHEDULER_cancel (it_task);
++    it_task = NULL;
++  }
++
+   if (op_task)
+   {
+     GNUNET_SCHEDULER_cancel (op_task);
+     op_task = NULL;
+   }
+ 
+   if (messenger)
+   {
+     GNUNET_MESSENGER_disconnect (messenger);
+     messenger = NULL;
+   }
+ 
+   status = 0;
+ }
+ 
++
+ static void
+ end_badly (void *cls)
+ {
+   fprintf (stderr, "Testcase failed (timeout).\n");
+ 
+   end (NULL);
+   status = 1;
+ }
+ 
++
+ static void
+ end_operation (void *cls)
+ {
+   op_task = NULL;
+ 
 -  fprintf (stderr, "Testcase failed (operation: '%s').\n", cls ? (const 
char*) cls : "unknown");
++  fprintf (stderr, "Testcase failed (operation: '%s').\n", cls ? (const
++                                                                  char*) cls :
++           "unknown");
+ 
+   if (die_task)
+     GNUNET_SCHEDULER_cancel (die_task);
+ 
+   end (NULL);
+   status = 1;
+ }
+ 
++
+ static int identity_counter = 0;
+ 
+ /**
+  * Function called when an identity is retrieved.
+  *
+  * @param cls Closure
+  * @param handle Handle of messenger service
+  */
+ static void
 -on_identity (void *cls,
 -             struct GNUNET_MESSENGER_Handle *handle)
++on_iteration (void *cls)
+ {
++  struct GNUNET_MESSENGER_Handle *handle = cls;
++  it_task = NULL;
++
+   if (op_task)
+   {
+     GNUNET_SCHEDULER_cancel (op_task);
+     op_task = NULL;
+   }
+ 
+   const char *name = GNUNET_MESSENGER_get_name (handle);
+ 
 -  if (0 != strcmp (name, TESTER_NAME))
++  if ((! name) || (0 != strcmp (name, TESTER_NAME)))
+   {
+     op_task = GNUNET_SCHEDULER_add_now (&end_operation, "name");
+     return;
+   }
+ 
 -  const struct GNUNET_CRYPTO_PublicKey *key = GNUNET_MESSENGER_get_key 
(handle);
++  const struct GNUNET_CRYPTO_PublicKey *key = GNUNET_MESSENGER_get_key (
++    handle);
+ 
 -  if (((!identity_counter) && (key)) || ((identity_counter) && (!key)))
++  struct GNUNET_CRYPTO_PublicKey pubkey;
++  GNUNET_CRYPTO_key_get_public (&identity, &pubkey);
++
++  if (((! identity_counter) && (key)) || ((identity_counter) && ((! key) ||
++                                                                 (0 !=
++                                                                  
GNUNET_memcmp (
++                                                                    key,
++                                                                    
&pubkey)))))
+   {
+     op_task = GNUNET_SCHEDULER_add_now (&end_operation, "key");
+     return;
+   }
+ 
+   if (identity_counter)
+   {
+     GNUNET_MESSENGER_disconnect (handle);
+ 
+     op_task = NULL;
+     messenger = NULL;
+ 
+     if (die_task)
+       GNUNET_SCHEDULER_cancel (die_task);
+ 
+     die_task = GNUNET_SCHEDULER_add_now (&end, NULL);
+     return;
+   }
+ 
 -  GNUNET_MESSENGER_update (messenger);
++  GNUNET_MESSENGER_set_key (handle, &identity);
+   identity_counter++;
++
++  it_task = GNUNET_SCHEDULER_add_now (&on_iteration, handle);
+ }
+ 
++
+ /**
+  * Main function for testcase.
+  *
+  * @param cls Closure
+  * @param cfg Configuration
+  * @param peer Peer for testing
+  */
+ static void
+ run (void *cls,
+      const struct GNUNET_CONFIGURATION_Handle *cfg,
+      struct GNUNET_TESTING_Peer *peer)
+ {
+   die_task = GNUNET_SCHEDULER_add_delayed (TOTAL_TIMEOUT, &end_badly, NULL);
+ 
+   identity_counter = 0;
+ 
 -  op_task = GNUNET_SCHEDULER_add_delayed (BASE_TIMEOUT, &end_operation, 
"connect");
 -  messenger = GNUNET_MESSENGER_connect (cfg, TESTER_NAME, &on_identity, NULL, 
NULL, NULL);
++  op_task = GNUNET_SCHEDULER_add_delayed (BASE_TIMEOUT, &end_operation,
++                                          "connect");
++  messenger = GNUNET_MESSENGER_connect (cfg, TESTER_NAME, NULL, NULL, NULL);
++
++  identity.type = htonl (GNUNET_PUBLIC_KEY_TYPE_ECDSA);
++  GNUNET_CRYPTO_ecdsa_key_create (&(identity.ecdsa_key));
++
++  if (messenger)
++    it_task = GNUNET_SCHEDULER_add_now (&on_iteration, messenger);
+ }
+ 
++
+ /**
+  * The main function.
+  *
+  * @param argc number of arguments from the command line
+  * @param argv command line arguments
+  * @return 0 ok, 1 on error
+  */
+ int
+ main (int argc,
+       char **argv)
+ {
 -  if (0 != GNUNET_TESTING_peer_run ("test-messenger", 
"test_messenger_api.conf", &run, NULL))
++  if (0 != GNUNET_TESTING_peer_run ("test-messenger", 
"test_messenger_api.conf",
++                                    &run, NULL))
+     return 1;
+ 
+   return status;
+ }
diff --cc src/service/messenger/test_messenger_anonymous.c
index 000000000,367d1c3b7..d3dadf2c5
mode 000000,100644..100644
--- a/src/service/messenger/test_messenger_anonymous.c
+++ b/src/service/messenger/test_messenger_anonymous.c
@@@ -1,0 -1,173 +1,190 @@@
+ /*
+    This file is part of GNUnet.
 -   Copyright (C) 2020--2021 GNUnet e.V.
++   Copyright (C) 2020--2023 GNUnet e.V.
+ 
+    GNUnet is free software: you can redistribute it and/or modify it
+    under the terms of the GNU Affero General Public License as published
+    by the Free Software Foundation, either version 3 of the License,
+    or (at your option) any later version.
+ 
+    GNUnet is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Affero General Public License for more details.
+ 
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ 
+    SPDX-License-Identifier: AGPL3.0-or-later
+  */
+ /**
+  * @file messenger/test_messenger_anonymous.c
+  * @author Tobias Frisch
+  * @brief Test for the messenger service using cadet API.
+  */
+ #include "platform.h"
+ #include <stdio.h>
+ #include "gnunet_util_lib.h"
+ #include "gnunet_testing_lib.h"
+ #include "gnunet_messenger_service.h"
+ 
+ /**
+  * How long until we really give up on a particular testcase portion?
+  */
+ #define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, \
+                                                      60)
+ 
+ /**
+  * How long until we give up on any particular operation (and retry)?
+  */
+ #define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
5)
+ 
+ static int status = 1;
+ 
+ static struct GNUNET_SCHEDULER_Task *die_task = NULL;
+ static struct GNUNET_SCHEDULER_Task *op_task = NULL;
++static struct GNUNET_SCHEDULER_Task *it_task = NULL;
+ 
+ struct GNUNET_MESSENGER_Handle *messenger = NULL;
+ 
+ static void
+ end (void *cls)
+ {
+   die_task = NULL;
+ 
++  if (it_task)
++  {
++    GNUNET_SCHEDULER_cancel (it_task);
++    it_task = NULL;
++  }
++
+   if (op_task)
+   {
+     GNUNET_SCHEDULER_cancel (op_task);
+     op_task = NULL;
+   }
+ 
+   if (messenger)
+   {
+     GNUNET_MESSENGER_disconnect (messenger);
+     messenger = NULL;
+   }
+ 
+   status = 0;
+ }
+ 
++
+ static void
+ end_badly (void *cls)
+ {
+   fprintf (stderr, "Testcase failed (timeout).\n");
+ 
+   end (NULL);
+   status = 1;
+ }
+ 
++
+ static void
+ end_operation (void *cls)
+ {
+   op_task = NULL;
+ 
 -  fprintf (stderr, "Testcase failed (operation: '%s').\n", cls ? (const 
char*) cls : "unknown");
++  fprintf (stderr, "Testcase failed (operation: '%s').\n", cls ? (const
++                                                                  char*) cls :
++           "unknown");
+ 
+   if (die_task)
+     GNUNET_SCHEDULER_cancel (die_task);
+ 
+   end (NULL);
+   status = 1;
+ }
+ 
++
+ /**
+  * Function called when an identity is retrieved.
+  *
+  * @param cls Closure
+  * @param handle Handle of messenger service
+  */
+ static void
 -on_identity (void *cls,
 -             struct GNUNET_MESSENGER_Handle *handle)
++on_iteration (void *cls)
+ {
++  struct GNUNET_MESSENGER_Handle *handle = cls;
++
++  it_task = NULL;
++
+   if (op_task)
+   {
+     GNUNET_SCHEDULER_cancel (op_task);
+     op_task = NULL;
+   }
+ 
+   const char *name = GNUNET_MESSENGER_get_name (handle);
+ 
+   if (NULL != name)
+   {
+     op_task = GNUNET_SCHEDULER_add_now (&end_operation, "name-anonymous");
+     return;
+   }
+ 
 -  if (GNUNET_SYSERR != GNUNET_MESSENGER_update (handle))
 -  {
 -    op_task = GNUNET_SCHEDULER_add_now (&end_operation, "update-fail");
 -    return;
 -  }
 -
 -  const struct GNUNET_CRYPTO_PublicKey *key = GNUNET_MESSENGER_get_key 
(handle);
++  const struct GNUNET_CRYPTO_PublicKey *key = GNUNET_MESSENGER_get_key (
++    handle);
+ 
+   if (key)
+   {
+     op_task = GNUNET_SCHEDULER_add_now (&end_operation, "key-anonymous");
+     return;
+   }
+ 
+   GNUNET_MESSENGER_disconnect (handle);
+ 
+   messenger = NULL;
+ 
+   if (die_task)
+     GNUNET_SCHEDULER_cancel (die_task);
+ 
+   die_task = GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+ 
++
+ /**
+  * Main function for testcase.
+  *
+  * @param cls Closure
+  * @param cfg Configuration
+  * @param peer Peer for testing
+  */
+ static void
+ run (void *cls,
+      const struct GNUNET_CONFIGURATION_Handle *cfg,
+      struct GNUNET_TESTING_Peer *peer)
+ {
+   die_task = GNUNET_SCHEDULER_add_delayed (TOTAL_TIMEOUT, &end_badly, NULL);
+ 
 -  op_task = GNUNET_SCHEDULER_add_delayed (BASE_TIMEOUT, &end_operation, 
"connect");
 -  messenger = GNUNET_MESSENGER_connect (cfg, NULL, &on_identity, NULL, NULL, 
NULL);
++  op_task = GNUNET_SCHEDULER_add_delayed (BASE_TIMEOUT, &end_operation,
++                                          "connect");
++  messenger = GNUNET_MESSENGER_connect (cfg, NULL, NULL, NULL, NULL);
++
++  if (messenger)
++    it_task = GNUNET_SCHEDULER_add_now (&on_iteration, messenger);
+ }
+ 
++
+ /**
+  * The main function.
+  *
+  * @param argc number of arguments from the command line
+  * @param argv command line arguments
+  * @return 0 ok, 1 on error
+  */
+ int
+ main (int argc,
+       char **argv)
+ {
 -  if (0 != GNUNET_TESTING_peer_run ("test-messenger", 
"test_messenger_api.conf", &run, NULL))
++  if (0 != GNUNET_TESTING_peer_run ("test-messenger", 
"test_messenger_api.conf",
++                                    &run, NULL))
+     return 1;
+ 
+   return status;
+ }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]