gnunet-go

GNUnet Bindings for Go
Log | Files | Refs | README | LICENSE

commit 22787606b45af3c36aebc4eb48c353f61aef9349
parent 7a6ae8f61ee7efde161db98462259ea9bbb23386
Author: Bernd Fix <brf@hoi-polloi.org>
Date:   Fri, 10 Jun 2022 09:48:44 +0200

RC1 for milestone 1 (NI Assure).

Diffstat:
MREADME.md | 14++++++++++++++
Dbuild.sh | 4----
Ddoc/raw/crypto.txt | 262-------------------------------------------------------------------------------
Ddoc/raw/protocols/core.txt | 38--------------------------------------
Ddoc/raw/protocols/hello.txt | 58----------------------------------------------------------
Ddoc/raw/transport.txt | 306-------------------------------------------------------------------------------
Ddoc/specification/.gitignore | 12------------
Ddoc/specification/chapters/messages.texi | 7-------
Ddoc/specification/chapters/messages/transport.texi | 47-----------------------------------------------
Ddoc/specification/chapters/overview.texi | 4----
Ddoc/specification/chapters/services.texi | 31-------------------------------
Ddoc/specification/chapters/services/core.texi | 63---------------------------------------------------------------
Ddoc/specification/chapters/services/services-01.dia | 0
Ddoc/specification/chapters/services/services-01.png | 0
Ddoc/specification/chapters/services/transport.texi | 25-------------------------
Ddoc/specification/fdl-1.3.texi | 505-------------------------------------------------------------------------------
Ddoc/specification/gpl-3.0.texi | 717-------------------------------------------------------------------------------
Ddoc/specification/techspec.texi | 87-------------------------------------------------------------------------------
Ddoc/specification/versioning.texi | 4----
Msrc/gnunet/build.sh | 1+
Msrc/gnunet/cmd/gnunet-service-dht-go/main.go | 20++++++++++++++------
Msrc/gnunet/cmd/gnunet-service-gns-go/main.go | 27++++++++++++++++++++-------
Msrc/gnunet/cmd/gnunet-service-revocation-go/main.go | 27++++++++++++++++++++-------
Msrc/gnunet/cmd/revoke-zonekey/main.go | 2+-
Msrc/gnunet/config/config.go | 2+-
Msrc/gnunet/config/config_test.go | 2+-
Msrc/gnunet/config/gnunet-config.json | 2+-
Msrc/gnunet/core/core.go | 164++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/gnunet/core/core_test.go | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/gnunet/core/event.go | 9++++++---
Asrc/gnunet/core/hello_test.go | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/core/peer_test.go | 2+-
Msrc/gnunet/crypto/gns.go | 2+-
Msrc/gnunet/crypto/gns_test.go | 2+-
Msrc/gnunet/crypto/hash.go | 2+-
Msrc/gnunet/crypto/key_exchange.go | 2+-
Msrc/gnunet/crypto/key_exchange_test.go | 2+-
Msrc/gnunet/crypto/keys_test.go | 5+++--
Msrc/gnunet/crypto/signature.go | 2+-
Asrc/gnunet/enums/blocktype_string.go | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/enums/dht.go | 26++++----------------------
Asrc/gnunet/enums/dht_block_type.go | 27+++++++++++++++++++++++++++
Asrc/gnunet/enums/generate.go | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/enums/gns.go | 291+++----------------------------------------------------------------------------
Asrc/gnunet/enums/gns_type.go | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gnunet/enums/gnstype_string.go | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gnunet/enums/gnunet-dht.rec | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gnunet/enums/gnunet-dht.tpl | 12++++++++++++
Asrc/gnunet/enums/gnunet-gns.rec | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gnunet/enums/gnunet-gns.tpl | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gnunet/enums/gnunet-signature.rec | 183+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gnunet/enums/gnunet-signature.tpl | 11+++++++++++
Msrc/gnunet/enums/signature.go | 37++++---------------------------------
Asrc/gnunet/enums/signature_purpose.go | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/gnunet/enums/sigpurpose_string.go | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/message/const.go | 2+-
Msrc/gnunet/message/factory.go | 4+++-
Msrc/gnunet/message/message.go | 2+-
Msrc/gnunet/message/msg_core.go | 6+++---
Msrc/gnunet/message/msg_dht.go | 2+-
Msrc/gnunet/message/msg_gns.go | 4++--
Msrc/gnunet/message/msg_hello.go | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Asrc/gnunet/message/msg_hello_dht.go | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/message/msg_namecache.go | 2+-
Msrc/gnunet/message/msg_revocation.go | 2+-
Msrc/gnunet/message/msg_transport.go | 2+-
Msrc/gnunet/message/types.go | 6+++++-
Dsrc/gnunet/rpc/server.go | 66------------------------------------------------------------------
Msrc/gnunet/service/client.go | 2+-
Msrc/gnunet/service/dht/blocks/hello.go | 107++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Dsrc/gnunet/service/dht/blocks/hello_test.go | 44--------------------------------------------
Msrc/gnunet/service/dht/module.go | 49++++++++++++++++++++++++-------------------------
Asrc/gnunet/service/dht/rpc.go | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/service/dht/service.go | 17++++++++++++-----
Msrc/gnunet/service/gns/block_handler.go | 54+++++++++++++++++++++++++++---------------------------
Msrc/gnunet/service/gns/box.go | 2+-
Msrc/gnunet/service/gns/dns.go | 12++++++------
Msrc/gnunet/service/gns/module.go | 17+++--------------
Asrc/gnunet/service/gns/rpc.go | 27+++++++++++++++++++++++++++
Msrc/gnunet/service/gns/service.go | 39++++++++++++++++++++++++---------------
Msrc/gnunet/service/module.go | 20++++++++++++++------
Msrc/gnunet/service/namecache/module.go | 2+-
Msrc/gnunet/service/revocation/module.go | 2+-
Msrc/gnunet/service/revocation/pow.go | 6+++---
Msrc/gnunet/service/revocation/pow_test.go | 2+-
Asrc/gnunet/service/revocation/rpc.go | 27+++++++++++++++++++++++++++
Msrc/gnunet/service/revocation/service.go | 18++++++++++++------
Asrc/gnunet/service/rpc.go | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/service/service.go | 29++---------------------------
Msrc/gnunet/service/store.go | 2+-
Asrc/gnunet/test/gnunet-dhtu/main.go | 218+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/transport/endpoint.go | 8++++++--
Asrc/gnunet/transport/responder.go | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet/transport/transport.go | 41++++++++++++++++++++++++++++++++++-------
Msrc/gnunet/util/address.go | 2+-
Msrc/gnunet/util/array.go | 14+++++++++++++-
Msrc/gnunet/util/base32.go | 2+-
Msrc/gnunet/util/base32_test.go | 2+-
Msrc/gnunet/util/database.go | 2+-
Msrc/gnunet/util/format.go | 2+-
Msrc/gnunet/util/fs.go | 2+-
Msrc/gnunet/util/id.go | 2+-
Msrc/gnunet/util/misc.go | 2+-
Msrc/gnunet/util/peer_id.go | 10+++++++++-
Msrc/gnunet/util/rnd.go | 2+-
Msrc/gnunet/util/time.go | 4++--
Dtest.sh | 4----
107 files changed, 2424 insertions(+), 2980 deletions(-)

diff --git a/README.md b/README.md @@ -30,6 +30,7 @@ Go v1.18+ is required to compile the code. git clone https://github.com/bfix/gnunet-go cd gnunet-go/src/gnunet go mod tidy +go generate ./... go install ./... go test ./... ``` @@ -57,6 +58,19 @@ below). The resulting programs are stored in `${GOPATH}/bin`. To run the unit tests, use `./test.sh`. +#### `./src/gnunet/enums` + +Changes in GANA definitions for block types, GNS record types and signature +purpose values can be imported by copying the recfiles (GNU recutils) from +GANA into this folder: + +* gnunet-dht.rec +* gnunet-gns.rec +* gnunet-signature.rec + +After updating the recfiles, you need to run `go generate ./...` to generate +the new source files. + ### `./src/gnunet/cmd` #### `gnunet-service-dht-test-go`: Implementation of the DHT core service (testbed). diff --git a/build.sh b/build.sh @@ -1,4 +0,0 @@ -#!/bin/bash - -cd src/gnunet/ -go install -v -gcflags "-N -l" ./... diff --git a/doc/raw/crypto.txt b/doc/raw/crypto.txt @@ -1,262 +0,0 @@ - -======================================================================== -0. Intro -======================================================================== - -GNUnet makes use of various cryptographic mechanisms (signing, hashing, -encrypting, ...) in various different flavors. This section will shortly -explain these mechanisms: - ------------------------------------------------------------------------- -0.1. Elliptic Curve Cryptography (ECC) ------------------------------------------------------------------------- - -Signatures in GNUnet are based on EdDSA [1],[2]. EdDSA is a secure and -fast ECC signature scheme based on the twisted Edwards curve Ed25519. The -private key is a 32 byte seed value (which is used to derive an integer -'d'); the public key is the point '[d]B' where 'B' is the base point of -Curve25519. - - Used for: - long-term signing key - (persistent, public key is the peer ID) - - short-term signing key - (transient, valid for ~12h) - -The key exchange scheme is based on ECDHE with Curve25519 key pairs. - - - - -Long-term signing key EdDSA -Short-term signing key ECDSA on Ed25519 -Key for key exchange ECDHE on Curve25519 -Session key(s) AES / Twofish - - - -======================================================================== -1. Initial setup -======================================================================== - ------------------------------------------------------------------------- -1.1. Long-term signing key ------------------------------------------------------------------------- - -A peer generates a long-term signing key pair for the EdDSA signature -algorithm with the Ed25519 curve from a random seed. For further details -see the Ed25519 paper [1] and RFC 8032 [2]. - ------------------------------------------------------------------------- -1.2. PeerIdentity ------------------------------------------------------------------------- - -The PeerIdentity is the public key of the long-term signing key of a -peer. A human-readable representation of the PeerIdentity is a custom -Base32 encoding of the public key (see A.1 for details) - -======================================================================== -2. Periodically -======================================================================== - ------------------------------------------------------------------------- -2.1. {REKEY_FREQUENCY: 12 hrs} Ephemeral key ------------------------------------------------------------------------- - -A Peer generates an ephemeral signing key pair for the EdDSA signature -algorithm with the Ed25519 curve from a random seed. It creates a -"CORE_EPHEMERAL_KEY" message (see "CORE protocol") and signs it with the -long-term signing key created in step 1.1 - -This ephemeral key will be used with the ECDHE key exchange algorithm to -establish session keys for symmetrical encryption between the peers. - -======================================================================== -3. On demand -======================================================================== - ------------------------------------------------------------------------- -2.1. {on start-up, expiration or change of TRANSPORT protocols} ------------------------------------------------------------------------- - -The peer constructs a new HELLO message for itself and puts it into the -DHT (see chapter "HELLO" protocol). A HELLO message contains the identity -of the peer and a list of available end-points where the peer accepts -connections from other peers. Each end-point defines an expiration date -(to handle cases where the globally-visible IP address of a peer changes -over time like for DSL clients). The HELLO in URI format looks like: - - gnunet://hello/<peerid>[+<expiration_time>+<proto>+<ip:port>](+) - -======================================================================== -4. Establishing a channel to a target peer -======================================================================== - ------------------------------------------------------------------------- -4.1. Lookup HELLO of target peer ------------------------------------------------------------------------- - -The peer looks up the HELLO for a target peer with a known peer identity -from either a local list of "known" peers with non-expired lifetime or -looks up the HELLO message of the target peer in the DHT (see chapter -"HELLO protocol"). It selects (one or more an end-points of the target -peer (see chapter "ATS") for a connection to the target. - ------------------------------------------------------------------------- -4.2. Connecting to target end-point ------------------------------------------------------------------------- - -The peer connects to the selected end-point(s) of the target peer thus -establishing a uni-directional (e.g. UDP) or bi-directional (e.g. TCP) -channel to the target. - -In case of a uni-directional channel the target will try to establish -a back-channel to the peer as soon as it knows how to do so (usually -after step 4.3.1). For simplification we assume that a bi-directional -message exchange between peer and target exists. - ------------------------------------------------------------------------- -4.3. HELLO protocol to negotiate session keys for transport ------------------------------------------------------------------------- - -The peer - -======================================================================== -[5] Message exchange -======================================================================== - -(1) Services queue messages for a target peer - - message is processed immediately (if requested by service) - - (smaller) messages are bundled (max 64k total) - => raw packet: - [msg_1][msg_2]...[msg_n] - -(2) raw packet is encrypted: - - AES-GCM (nonce, timestamp {obsolete in future version}) - - Twofish - => transport packet - -======================================================================== -[6] Transport -======================================================================== - -------------------------------------------------- -(1) TCP: -------------------------------------------------- - - - direct message exchange (bi-directional) - -------------------------------------------------- -(2) UDP: -------------------------------------------------- - - Each UDP packet has the following structure: - - peerid of sender (32 bytes) - { future extension: - - ephemeral key - - signature of payload (64 bytes) - - HMAC (32/64 bytes) - } - - payload (up to MTU-header size) - -======================================================================== -[A] Appendices -======================================================================== - ------------------------------------------------------------------------- -(1) Base32 conversion between binary data and string representation ------------------------------------------------------------------------- - -A binary array of size m is viewed as a consecutive stream of bits from -left to right. Bytes are ordered with ascending address, while bits (in -a byte) are ordered MSB to LSB. - -For encoding the stream is partitioned into 5-bit chunks; the last chunk -is right-padded with 0's if 8*m is not divisible by 5. Each chunk (value -between 0 and 31) is encoded into a character; the mapping for encoding -is the same as in [3]. - -For decoding each character is converted to a 5-bit chunk based on the -encoder mapping (with one addition: the character 'U' maps to the value -27). The chunks are concatenated to produce a bit stream to be stored -in the output array. - -======================================================================== -B. Crypto-related constants -======================================================================== - -------------------------------------------------- -B.1. Signature purpose -------------------------------------------------- - -+----------------------------------+-------+--------------------------------------------------------------------+ -| Name | Value | Comment | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_TEST | 0 | Only used in test cases! | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_TRANSPORT_PONG_OWN | 1 | Signature for confirming that this peer uses a particular address. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_TRANSPORT_DISCONNECT | 2 | Signature for confirming that this peer intends to disconnect. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_REVOCATION | 3 | Signature for confirming a key revocation. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_NAMESPACE_ADVERTISEMENT | 4 | Signature for a namespace/pseudonym advertisement. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_PEER_PLACEMENT | 5 | Signature by which a peer affirms that it is providing a certain | -| | | bit of content (used in LOCation URIs). | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_FS_KBLOCK | 6 | Obsolete, legacy value. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_FS_SBLOCK | 7 | Obsolete, legacy value. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_FS_NBLOCK | 8 | Obsolete, legacy value. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_FS_NBLOCK_KSIG | 9 | Obsolete, legacy value. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_RESOLVER_RESPONSE | 10 | Signature of an DNS_Advertisement | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_DNS_RECORD | 11 | | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_CHAT_MESSAGE | 12 | Signature of a chat message. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_CHAT_RECEIPT | 13 | Signature of confirmation receipt for a chat message. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_NSE_SEND | 14 | Signature of a network size estimate message. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_GNS_RECORD_SIGN | 15 | Signature of a gnunet naming system record block. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_ECC_KEY | 16 | Purpose is to set a session key. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG__FS_UBLOCK | 17 | UBlock Signature, done using DSS, not ECC | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_REGEX_ACCEPT | 18 | Accept state in regex DFA. Peer affirms that it offers the | -| | | matching service. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_MULTICAST_MESSAGE | 19 | Signature of a multicast message sent by the origin. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_CONVERSATION_RING | 20 | Signature of a conversation ring. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_SECRETSHARING_DKG1 | ? 22 | Signature for the first round of distributed key generation. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_SECRETSHARING_DKG2 | ? 23 | Signature for the second round of distributed key generation. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_SECRETSHARING_DECRYPTION | 23 | Signature for cooperative decryption. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_MULTICAST_REQUEST | 24 | Signature of a multicast request sent by a member. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_SENSOR_ANOMALY_REPORT | 25 | Signature for a sensor anomaly report message. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_GNUID_TOKEN | 26 | Signature for a GNUid Token. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_GNUID_TICKET | 27 | Signature for a GNUid Ticket. | -+----------------------------------+-------+--------------------------------------------------------------------+ -| SIG_CREDENTIAL | 28 | Signature for a GNUnet credential. | -+----------------------------------+-------+--------------------------------------------------------------------+ - -======================================================================== -[B] References -======================================================================== - -[1] https://tools.ietf.org/rfc/rfc8032.txt -[2] https://ed25519.cr.yp.to/ed25519-20110926.pdf -[3] https://www.crockford.com/wrmg/base32.html - diff --git a/doc/raw/protocols/core.txt b/doc/raw/protocols/core.txt @@ -1,38 +0,0 @@ - - - -======================================================================== -1. CORE Protocol -======================================================================== - -======================================================================== -A. Message Formats -======================================================================== - ------------------------------------------------------------------------- -A.1 CORE_EPHEMERAL_KEY message ------------------------------------------------------------------------- - -+-------------+------------------+------------------------------------------+ -+ Field | Size / type | Comment | -+-------------+------------------+------------------------------------------+ -| size | 2 / uint16 (nbo) | Total length of message (incl. size) | -+-------------+------------------+------------------------------------------+ -| type | 2 / uint16 (nbo) | Message type: CORE_EPHEMERAL_KEY (88) | -+-------------+------------------+------------------------------------------+ -| sender_stat | 4 / uint32 (nbo) | enum PeerStateMachine | -+-------------+------------------+------------------------------------------+ -| signature | 64 | EdDSA signature | -+-------------+------------------+------------------------------------------+ -| sign_length | 4 / uint32 (nbo) | Length of signed block (incl. this) | -+-------------+------------------+------------------------------------------+ -| purpose | 4 / uint32 (nbo) | Signature purpose (see chapter "CRYPTO") | -+-------------+------------------+------------------------------------------+ -| create_time | 8 / uint64 (nbo) | Time of key creation. | -+-------------+------------------+------------------------------------------+ -| expire_time | 8 / uint64 (nbo) | Time of key expiration. | -+-------------+------------------+------------------------------------------+ -| eph_key | 32 | Ephemeral EdDSA public key | -+-------------+------------------+------------------------------------------+ -| peerid | 32 | Peer identity (EdDSA public key) | -+-------------+------------------+------------------------------------------+ diff --git a/doc/raw/protocols/hello.txt b/doc/raw/protocols/hello.txt @@ -1,58 +0,0 @@ - - -======================================================================== -1. HELLO Protocol -======================================================================== - -The HELLO protocol (see chapter "HELLO Protocol" for details) is a plain- -text (unencrypted) message exchange to establish a secure (encrypted) -message exchange between the peers after a physical connection has been -established. - -4.3.1 The peer sends its HELLO message: This tells the target which - peer is connecting. The target retrieves the peer identity (thus - learning the long-term signature verification key (public EdDSA - key) and a list of available end-points for a possibly required - back-channel to the peer. If the target accepts the peer (not on - a black-list or filtered out) and the channel is uni-directional, - the target creates a back-channel to the peer. If the target - does not accept the peer and the channel is bi-directional, the - target resets the connection. - -(5) peers exchange (unencrypted) and validate ephemeral keys and derive - a shared secret (ECDHE) - -(6) the shared secret is used to derive (HKDF) two session keys for - AES-256 and Twofish - - -======================================================================== -A. Message Formats -======================================================================== - ------------------------------------------------------------------------- -A.1 HELLO ------------------------------------------------------------------------- - -+-------------+------------------+--------------------------------------+ -+ Field | Size / type | Comment | -+-------------+------------------+--------------------------------------+ -| size | 2 / uint16 (nbo) | Total length of message (incl. size) | -+-------------+------------------+--------------------------------------+ -| type | 2 / uint16 (nbo) | GNUnet message type = HELLO (17) | -+-------------+------------------+--------------------------------------+ -| friend_only | 4 / uint32 (nbo) | = 1: do not gossip this HELLO | -+-------------+------------------+--------------------------------------+ -| peerid | 32 | EdDSA public key (long-term) | -+-------------+------------------+--------------------------------------+ -| addresses | variable | List of variable length addresses | -+-+-----------+------------------+--------------------------------------+ - | transport | variable | Name of transport ('\0' terminated) | - +-----------+------------------+--------------------------------------+ - | addr_size | 2 / uint16 (nbo) | Length of address | - +-----------+------------------+--------------------------------------+ - | expire_on | 8 / uint64 (nbo) | UNIX timestamp | - +-----------+------------------+--------------------------------------+ - | address | adr_size | Address (transport-dependend) | - +-----------+------------------+--------------------------------------+ - diff --git a/doc/raw/transport.txt b/doc/raw/transport.txt @@ -1,306 +0,0 @@ - -######################################################################## -1. Establishing a GNUnet session between two peers -######################################################################## - -A session between two GNUnet peers enables the exchange of P2P messages -between them. A session is a wrapper around two uni-directional channels -(A -> B, B -> A) that in theory can even utilize two distinct transport -mechanisms (e.g. UDP and HTTPS). - -The most common (and reliable) transport mechanism is TCP/IP that has -the additional advantage of being bi-directional - it bundles channel -and back-channel into a single transport. The following sections will -describe how a TCP-based session between to peers A (initiator) and B -(target) is established. - -After negotiating the session and a shared session key, the exchange of -messages between A and B will be encrypted with forward secrecy (see -chapter "Crypto" for more details). - - -======================================================================== -1.1. Pre-Requisites -======================================================================== - -Each peer has a unique peer ID that is the public key of the long-term -EdDSA signing key (see chapter "Crypto" for details). It is represented -as a 32 byte binary. - -Each peer also has a list of end-points that can be used by other peers -to connect to it. An end-point specifies the transport protocol (e.g. -TCP) and an address (e.g. an IPv4 or IPv6 address and a port). The -format of an address is of course dependent on the transport protocol; -an HTTPS transport for example requires an URL address. - -We assume that the initiator A of a session knows how to connect to an -address on target B. The bootstrap is usually done by hard-coding a -single, reliable and available GNUnet peer identity and its addresses. -Every peer participating in the network will "learn" about more peers -and their addresses later in the process. - - -======================================================================== -1.2. GNUnet message format -======================================================================== - -The communication between two peers is based on GNUnet messages. An -individual GNUnet message cannot exceed the size of 64kB; it has at -least a size of 4 bytes (just a header with an empty payload). - -All GNUnet messages have a standard header of the following form: - -+--------+------------------+------------------------------------------+ -| Field | Size / type | Comment | -+--------+------------------+------------------------------------------+ -| size | 2 / uint16 (nbo) | Total length of message (incl. size) | -+--------+------------------+------------------------------------------+ -| type | 2 / uint16 (nbo) | GNUnet message type | -+--------+------------------+------------------------------------------+ - -The annotation "(nbo)" indicates "network-byte order"; integers of that -kind are stored in "big-endian" format (MSB first) in the message body. - -The field types used in messages are mostly self-explanatory and are used -in nearly all programming languages. The following field types need an -explanation: - - string a sequence of 8-bit characters delimited by '\0' - (C/C++ character string) - - time uint64 value of the number of microseconds since - midnight Jan 1st, 1970 (Unix epoch in usec) - - address uint8 array of variable length (with no terminator) - The internal structure of an address depends on the - transport protocol used (TCP and UDP addresses for - example are composed of a 4 (IPv4) or 16 (IPv6) uint8 - array followed by the port as uint16 (nbo)). - - -======================================================================== -1.3. Establishing a session between peers (TCP connection) -======================================================================== - -Peer A (initiator) establishes a TCP connection to an address of peer B. -After the TCP/IP connection is built, peer A starts the message exchange -to establish a GNUnet session with the other peer. - - ------------------------------------------------------------------------- -1.3.1. Exchange TRANSPORT_TCP_WELCOME messages ------------------------------------------------------------------------- - -Peer A sends a TRANSPORT_TCP_WELCOME message to peer B, so that peer B -can learn the peer identity of the initiating peer: - -+-----------------------------------------------------------------------+ -| TRANSPORT_TCP_WELCOME | -+---------+------------------+------------------------------------------+ -| Field | Size / type | Comment | -+---------+------------------+------------------------------------------+ -| size | 2 / uint16 (nbo) | Total length of message (incl. size) | -+---------+------------------+------------------------------------------+ -| type | 2 / uint16 (nbo) | TRANSPORT_TCP_WELCOME (61) | -+---------+------------------+------------------------------------------+ -| peer_id | 32 | Peer ID of sender (A) | -+---------+------------------+------------------------------------------+ - - -Peer B replies with a TRANSPORT_TCP_WELCOME message, so that peer A can -check it is talking to the correct target peer B (and terminate the TCP -connection if that is not the case). - -Peer B can also send a TRANSPORT_SESSION_QUOTA message to inform peer A -about a the maximum bandwidth it has assigned to this session. Only rogue -peers ignore this request: - -+-----------------------------------------------------------------------+ -| TRANSPORT_SESSION_QUOTA | -+---------+------------------+------------------------------------------+ -| Field | Size / type | Comment | -+---------+------------------+------------------------------------------+ -| size | 2 / uint16 (nbo) | Total length of message (incl. size) | -+---------+------------------+------------------------------------------+ -| quota | 4 / uint32 (nbo) | Assigned bandwith to session (B/s) | -+---------+------------------+------------------------------------------+ - - -Peer B can also send a TRANSPORT_SESSION_SYN message to - - -EXAMPLE: --------- - -A --> B 00:24:00:3d:d3:b3:ac:f3:85:0e:cc:df:82:dd:fe:45 - 03:08:71:8c:51:aa:e6:52:bf:b6:30:e5:17:13:79:dd - 01:bc:89:56 - - = TcpWelcomeMsg{'TESTSWW51V6DZ0PXZS2G623HHH8TNSJJQYV31S8Q2DWXT0DWH5B0'} - -B --> A 00:24:00:3d:92:dc:bf:39:40:2d:c6:3c:97:a6:81:e0 - fc:d8:7c:74:17:d3:a3:8c:52:fd:e0:49:bc:d0:1c:0a - 0b:8c:02:51 - - = TcpWelcomeMsg{'JBEBYEA05Q33S5X6G7GFSP3WEGBX78WCABYY0JDWT0E0M2WC098G'} - -B --> A 00:08:01:7b:ff:ff:ff:ff - - = SessionQuotaMsg{4.000GB/s} - - ------------------------------------------------------------------------- -1.3.2. Send HELLO message ------------------------------------------------------------------------- - - ------------------------------------------------------------------------- -1.3.2. Send HELLO message ------------------------------------------------------------------------- - -Peer A sends a HELLO message to peer B to announce its peer identity -and its list of available end-points (list of 0 or more HELLOADDR blocks): - -+----------------------------------------------------------------------------+ -| HELLO | -+-------------+-------------------+------------------------------------------+ -| Field | Size / type | Comment | -+-------------+-------------------+------------------------------------------+ -| size | 2 / uint16 (nbo) | Total length of message (incl. size) | -+-------------+-------------------+------------------------------------------+ -| type | 2 / uint16 (nbo) | HELLO (17) | -+-------------+-------------------+------------------------------------------+ -| friend_only | 32 / uint32 (nbo) | =1: don't gossip HELLO | -+-------------+-------------------+------------------------------------------+ -| peer_id | 32 | Peer ID of sender | -+-------------+-------------------+------------------------------------------+ -| addr_list | * / []HELLOADDR | List of HELLO addresses (can be empty) | -+-------------+-------------------+------------------------------------------+ - -The field 'friend_only' is either 0 (=NO) or 1 (=YES) and specifies if the -receiving peer may gossip this HELLO message to other peers (see section -"GOSSIP Protocol" for details). - -As mentioned earlier, Peer B could build a separate back-channel to peer -A for a GNUnet connection although that is not necessary for our TCP -connection which is bi-directional. In this case (TCP), the HELLO message -may contain no end-point specifications (address_list is empty): - -If the HELLO message contains HELLOADDR blocks, these have the following -format: - -+----------------------------------------------------------------------------+ -| HELLOADDR | -+-------------+-------------------+------------------------------------------+ -| Field | Size / type | Comment | -+-------------+-------------------+------------------------------------------+ -| transport | * / string | Name of transport | -+-------------+-------------------+------------------------------------------+ -| addr_size | 2 / uint16 (nbo) | Size of address entry | -+-------------+-------------------+------------------------------------------+ -| expire_on | 8 / time (nbo) | Expiration date | -+-------------+-------------------+------------------------------------------+ -| address | * / address | Address specification (addr_size bytes) | -+-------------+-------------------+------------------------------------------+ - -Peers should persistently store received HELLO messages (until the addresses -contained in it expire). - -EXAMPLE: --------- - -==> 00:3a:00:11:00:00:00:00:d3:b3:ac:f3:85:0e:cc:df - 82:dd:fe:45:03:08:71:8c:51:aa:e6:52:bf:b6:30:e5 - 17:13:79:dd:01:bc:89:56:74:63:70:00:00:04:00:05 - 70:c2:6b:b0:cc:92:ac:11:00:07 - - = HelloMsg{TESTSWW51V6DZ0PXZS2G623HHH8TNSJJQYV31S8Q2DWXT0DWH5B0, - 0,[Address{tcp:172.17.0.7,2018-07-12T00:26:56.000434Z}]} - - ------------------------------------------------------------------------- -1.3.2. PING/PONG handshake ------------------------------------------------------------------------- - -Peer A sends a TRANSPORT_PING message to Peer B: - -+----------------------------------------------------------------------------+ -| TRANSPORT_PING | -+-------------+-------------------+------------------------------------------+ -| Field | Size / type | Comment | -+-------------+-------------------+------------------------------------------+ -| size | 2 / uint16 (nbo) | Total length of message (incl. size) | -+-------------+-------------------+------------------------------------------+ -| type | 2 / uint16 (nbo) | TRANSPORT_PING (372) | -+-------------+-------------------+------------------------------------------+ -| challenge | 4 / uint32 | Challenge code (to ensure fresh reply) | -+-------------+-------------------+------------------------------------------+ -| target_id | 32 | Peer ID of target peer | -+-------------+-------------------+------------------------------------------+ -| addr | * / address | Address on target peer | -+-------------+-------------------+------------------------------------------+ - - -Example -==> 00:36:01:74:54:94:ab:a1:92:dc:bf:39:40:2d:c6:3c - 97:a6:81:e0:fc:d8:7c:74:17:d3:a3:8c:52:fd:e0:49 - bc:d0:1c:0a:0b:8c:02:51:74:63:70:00:00:00:00:00 - ac:11:00:05:08:26 - - = PingMsg{JBEBYEA05Q33S5X6G7GFSP3WEGBX78WCABYY0JDWT0E0M2WC098G, - Address{tcp:172.17.0.5:2086},2712376404} - - - -<== SessionQuotaMsg{4.000GB/s} - [0008017bffffffff] -<== SessionSyn{2018-07-11T12:26:56.000763Z} - [0010017700000000000570b85cc51ddb] -==> SessionSynAck{2018-07-11T12:26:56.000763Z} - [0010017800000000000570b85cc51ddb] -<== PongMsg{?,Address{tcp:172.17.0.5:2086},2712376404} - [006a01755494aba1b044e5b7249257eeb177079b431aff9d225f85e14b28b2a4f2f88ac2412d6425ab58bd7d13d48be43bc7482c23e94c94519c4701ca93af2f0c32631071397f050000002200000001000570b93358c20c0000000e7463700000000000ac1100050826] -*** PONG signature verified -<== SessionAck{} - [00040179] - - -======================================================================== -1.2. Peer B initiates a connection to Peer A -======================================================================== - -<== 00:24:00:3d:92:dc:bf:39:40:2d:c6:3c:97:a6:81:e0 - fc:d8:7c:74:17:d3:a3:8c:52:fd:e0:49:bc:d0:1c:0a - 0b:8c:02:51 - - = TcpWelcomeMsg{'JBEBYEA05Q33S5X6G7GFSP3WEGBX78WCABYY0JDWT0E0M2WC098G'} - -==> 00:24:00:3d:d3:b3:ac:f3:85:0e:cc:df:82:dd:fe:45 - 03:08:71:8c:51:aa:e6:52:bf:b6:30:e5:17:13:79:dd - 01:bc:89:56 - - = TcpWelcomeMsg{'TESTSWW51V6DZ0PXZS2G623HHH8TNSJJQYV31S8Q2DWXT0DWH5B0'} - -<== 00:28:00:11:00:00:00:00:92:dc:bf:39:40:2d:c6:3c - 97:a6:81:e0:fc:d8:7c:74:17:d3:a3:8c:52:fd:e0:49 - bc:d0:1c:0a:0b:8c:02:51 - - = HelloMsg{JBEBYEA05Q33S5X6G7GFSP3WEGBX78WCABYY0JDWT0E0M2WC098G,0,[]} - -<== PingMsg{TESTSWW51V6DZ0PXZS2G623HHH8TNSJJQYV31S8Q2DWXT0DWH5B0,Address{tcp:172.17.0.7:2086},279093666} - [00360174a2a1a210d3b3acf3850eccdf82ddfe450308718c51aae652bfb630e5171379dd01bc89567463700000000000ac1100070826] -==> PongMsg{OK,Address{tcp:172.17.0.7:2086},279093666} - [006a0175a2a1a210537ed664528db72e7903f6c34f8efdeb34597a77f68b1505901b3e1ce45c24337ae00e408dfcf94d5f7caa370241bfbd3bc12dcb0e0d0d9a60d3d662454fd40f0000002200000001000570c20d3fa97e0000000e7463700000000000ac1100070826] -<== SessionQuotaMsg{4.000GB/s} - [0008017bffffffff] -<== SessionSyn{2018-07-11T12:00:31.000255Z} - [0010017700000000000570b7fe554827] -==> SessionSynAck{2018-07-11T12:00:31.000255Z} - [0010017800000000000570b7fe554827] -<== SessionAck{} - [00040179] -*** CONNECTION etsablished with peer 'JBEBYEA05Q33S5X6G7GFSP3WEGBX78WCABYY0JDWT0E0M2WC098G' - - - - diff --git a/doc/specification/.gitignore b/doc/specification/.gitignore @@ -1,12 +0,0 @@ -*.fn -*.fns -*.ky -*.pg -*.tp -*.vr -*.aux -*.cp -*.cps -*.log -*.toc -*.pdf diff --git a/doc/specification/chapters/messages.texi b/doc/specification/chapters/messages.texi @@ -1,7 +0,0 @@ -@node Messages -@chapter Messages - -@c ********************************************************************* -@include chapters/messages/transport.texi -@c ********************************************************************* - diff --git a/doc/specification/chapters/messages/transport.texi b/doc/specification/chapters/messages/transport.texi @@ -1,47 +0,0 @@ -@node Transport -@section Transport - -@emph{Transport} in this chapter refers to the transport of GNUnet messages -as sent and received by the various subsystems of GNUnet (like DHT, NSE, FS, -GNS, ...) between peers in the P2P network. For the purpose of this chapter -such a message `M` is treated as a binary object of size `m` (in bytes). - -Every node (peer) in GNUnet is identified by the hash codes of its public key. - - -@table @samp - -@item StartMessage - -Message from the transport service to the library asking to check if both -processes agree about this peers identity. - -@example -+--------+--------+--------+--------+--------+--------+--------+--------+ -| msg_size | msg_type | options | -+--------+--------+--------+--------+--------+--------+--------+--------+ -| | -+ + -| | -+ peer_identity + -| | -+ + -| | -+--------+--------+--------+--------+--------+--------+--------+--------+ -@end example - -@itemize - @item @samp{msg_size} - uint16: size of the message = 40 bytes - - @item @samp{msg_type} - uint16: message type = GNUNET_MESSAGE_TYPE_TRANSPORT_START - - @item - - @item @samp{peer_identity} - Identity we think we have. If it does not match, the receiver should - print out an error message and disconnect. -@end itemize - -@end table diff --git a/doc/specification/chapters/overview.texi b/doc/specification/chapters/overview.texi @@ -1,4 +0,0 @@ -@node Overview -@chapter Overview - -t.b.d. diff --git a/doc/specification/chapters/services.texi b/doc/specification/chapters/services.texi @@ -1,31 +0,0 @@ -@node Services -@chapter Services - -A GNUnet instance running on one node is an assembly of services that exchange -messages (see Chapter "Messages" for details) -- among themselves and with -services running on other nodes. - -GNUnet services on a node usually utilize other, more basic GNUnet services -to provide their functionality. The following graph shows the dependencies -and message channels between the most basic GNUnet services: - -@float GNUnet services -@image{chapters/services/services-01,,7cm,,.png} -@caption{dependencies} -@end float - -@node Mandatory services for a GNUnet node -@section Mandatory services for a GNUnet node - -The services marked with a background color in the above figure comprise the -smallest set of services a node must provide to be useful for the network -- -even if it is only providing a simple DHT storage service. These mandatory -services are: - -@c ********************************************************************* -@include chapters/services/core.texi -@c ********************************************************************* - -@c ********************************************************************* -@include chapters/services/transport.texi -@c ********************************************************************* diff --git a/doc/specification/chapters/services/core.texi b/doc/specification/chapters/services/core.texi @@ -1,63 +0,0 @@ - -@subsection CORE - -One of the most important services in GNUnet is the CORE service managing -connections and handling encryption between peers. - -Every peer has a private (secret) key and an associated public key for the -Ed25519 signature scheme (see @url{https://gnunet.org/ed25519}); this keypair -is usually created if a GNUnet instance is started for the first time. The -keypair is unique, so the Ed25519 public key (32 octets in standard compact -format) serves as a GNUnet @dfn{peer identity}. - -A @dfn{connection} is a bi-directional channel suitable for message exchange -between two peers. The connection uses a specific transport method (e.g. -TCP/IP) available on both end-points. The TRANSPORT service is creating, -processing and dropping connections to other peers on behalf of CORE. - -The CORE service will try to maintain a certain number of open connections to -other peers; this number depends on the estimated size (number of participants) -of the network as determined by the NSE service (Network Size Estimation). If -@math{s} is the size of the network, than the number of concurrent connections -is @math{ n = \lceil log_2\;s \rceil}. - -To connect to the network, a peer needs to learn about the identities of other -peers on the network. This is done by providing a single (active) peer identity -(and its addresses) at start-up; in the course of exchanging messages with this -peer CORE will discover the identities of other nodes it can try connect to. -CORE will maintain a persistent database of node identities it has discovered -(and probably has been connected to). - -A node publishes its identity and addresses (initially and in case of address -changes) in the DHT, so other nodes can look it up and connect to it if -desired. In the same way CORE uses the DHT to lookup addresses of peers (based -on their identity) it want to establish a connection with. - -After a connection is established, the peers will start exchanging messages -over it. - -Out-bound GNUnet messages (originating from local GNUnet services including -CORE itself) are queued for further processing. CORE decides if and when a message is to be sent to -another peer. Based on the maximum size of the out-bound transport packet (MTU, depends -on the transport method used), it can either bundle smaller GNUnet messages -into a single transport packet, or create a sequence of fragments from a single -GNUnet message, in case the GNUnet message is larger than a transport -packet. If the GNUnet message(s) do not fill a transport packet completely, -the transport packet is padded with random data to its maximum size. A -transport packet is than encrypted with a session key negotiated between the -two peers during the creation of a connection (see section on "Packet -encryption") before leaving the peer. - -In-bound transport packets are first decrypted and than either split into -multiple GNUnet messages or defragmented (reassembled) in case of a large -GNUnet message. The received messages are either processed by CORE itself, are -forwarded to local GNUnet services or relayed to other peers. Messages that -cannot be handled (e.g. because a local service is temporarily unavailable) -are simply dropped. - -@subsubsection Cryptographic operations - -@subsubsection GNUnet Anonymization Protocol - -The protocol governing this process is the GNUnet Anonymization Protocol (GAP) -(see @url{https://gnunet.org/sites/default/files/aff.pdf,,paper}). diff --git a/doc/specification/chapters/services/services-01.dia b/doc/specification/chapters/services/services-01.dia Binary files differ. diff --git a/doc/specification/chapters/services/services-01.png b/doc/specification/chapters/services/services-01.png Binary files differ. diff --git a/doc/specification/chapters/services/transport.texi b/doc/specification/chapters/services/transport.texi @@ -1,25 +0,0 @@ - -@subsection TRANSPORT - -The TRANSPORT service handles all message exchanges between a local peer and -other peers on the network. It can -- depending on the computer hardware it -is running on -- support multiple transport methods between peers: TCP/IP, -UDP/IP, ICMP, HTTP, Bluetooth, WiFi and others. - -Each transport method has its unique way of specifying a peer address; TCP/IP -expects an IP address and a port number, while HTTP expects an URL. So a -single peer can have multiple addresses (one for each available transport -method). CORE links all these addresses to one peer identity. While a peer -address can (and often do) change over time, the peer identity is fixed. - -The TRANSPORT service establishes, maintains, processes and drops connections -with other peers on request of the CORE service. If a new connection to a peer -identity is requested, the ATS (Automatic Transport Selection) decides which -available transport method should be used. To improve performance and -reliability, multiple channels on different transport methods can be created -between two peers at the same time; the sender sends the next message on the -channel with the best throughput. - -Connection requests from other peers can be filtered by the TRANSPORT service -(e.g. by implementing a black-list of banned peers), all other requests are -forwarded to the CORE service for validation and approval. diff --git a/doc/specification/fdl-1.3.texi b/doc/specification/fdl-1.3.texi @@ -1,505 +0,0 @@ -@c The GNU Free Documentation License. -@center Version 1.3, 3 November 2008 - -@c This file is intended to be included within another document, -@c hence no sectioning command or @node. - -@display -Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. -@uref{http://fsf.org/} - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -functional and useful document @dfn{free} in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, -with or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible -for modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work, in any medium, that -contains a notice placed by the copyright holder saying it can be -distributed under the terms of this License. Such a notice grants a -world-wide, royalty-free license, unlimited in duration, to use that -work under the conditions stated herein. The ``Document'', below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as ``you''. You accept the license if you -copy, modify or distribute the work in a way requiring permission -under copyright law. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section -of the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall -subject (or to related matters) and contains nothing that could fall -directly within that overall subject. (Thus, if the Document is in -part a textbook of mathematics, a Secondary Section may not explain -any mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The ``Invariant Sections'' are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. If a -section does not fit the above definition of Secondary then it is not -allowed to be designated as Invariant. The Document may contain zero -Invariant Sections. If the Document does not identify any Invariant -Sections then there are none. - -The ``Cover Texts'' are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. A Front-Cover Text may -be at most 5 words, and a Back-Cover Text may be at most 25 words. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup, or absence of markup, has been arranged to thwart -or discourage subsequent modification by readers is not Transparent. -An image format is not Transparent if used for any substantial amount -of text. A copy that is not ``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -ASCII without markup, Texinfo input format, La@TeX{} input -format, SGML or XML using a publicly available -DTD, and standard-conforming simple HTML, -PostScript or PDF designed for human modification. Examples -of transparent image formats include PNG, XCF and -JPG. Opaque formats include proprietary formats that can be -read and edited only by proprietary word processors, SGML or -XML for which the DTD and/or processing tools are -not generally available, and the machine-generated HTML, -PostScript or PDF produced by some word processors for -output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, ``Title Page'' means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -The ``publisher'' means any person or entity that distributes copies -of the Document to the public. - -A section ``Entitled XYZ'' means a named subunit of the Document whose -title either is precisely XYZ or contains XYZ in parentheses following -text that translates XYZ in another language. (Here XYZ stands for a -specific section name mentioned below, such as ``Acknowledgements'', -``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' -of such a section when you modify the Document means that it remains a -section ``Entitled XYZ'' according to this definition. - -The Document may include Warranty Disclaimers next to the notice which -states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this -License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and has -no effect on the meaning of this License. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies (or copies in media that commonly have -printed covers) of the Document, numbering more than 100, and the -Document's license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a computer-network location from which the general network-using -public has access to download using public-standard network protocols -a complete Transparent copy of the Document, free of added material. -If you use the latter option, you must take reasonably prudent steps, -when you begin distribution of Opaque copies in quantity, to ensure -that this Transparent copy will remain thus accessible at the stated -location until at least one year after the last time you distribute an -Opaque copy (directly or through your agents or retailers) of that -edition to the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -@item -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has fewer than five), -unless they release you from this requirement. - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -@item -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document's license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section Entitled ``History'', Preserve its Title, and add -to it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section Entitled ``History'' in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -@item -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the ``History'' section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -@item -For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve -the Title of the section, and preserve in the section all the -substance and tone of each of the contributor acknowledgements and/or -dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -@item -Delete any section Entitled ``Endorsements''. Such a section -may not be included in the Modified Version. - -@item -Do not retitle any existing section to be Entitled ``Endorsements'' or -to conflict in title with any Invariant Section. - -@item -Preserve any Warranty Disclaimers. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section Entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice, and that you preserve all their Warranty Disclaimers. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections Entitled ``History'' -in the various original documents, forming one section Entitled -``History''; likewise combine any sections Entitled ``Acknowledgements'', -and any sections Entitled ``Dedications''. You must delete all -sections Entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, is called an ``aggregate'' if the copyright -resulting from the compilation is not used to limit the legal rights -of the compilation's users beyond what the individual works permit. -When the Document is included in an aggregate, this License does not -apply to the other works in the aggregate which are not themselves -derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document's Cover Texts may be placed on -covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic form. -Otherwise they must appear on printed covers that bracket the whole -aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between -the translation and the original version of this License or a notice -or disclaimer, the original version will prevail. - -If a section in the Document is Entitled ``Acknowledgements'', -``Dedications'', or ``History'', the requirement (section 4) to Preserve -its Title (section 1) will typically require changing the actual -title. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, or distribute it is void, and -will automatically terminate your rights under this License. - -However, if you cease all violation of this License, then your license -from a particular copyright holder is reinstated (a) provisionally, -unless and until the copyright holder explicitly and finally -terminates your license, and (b) permanently, if the copyright holder -fails to notify you of the violation by some reasonable means prior to -60 days after the cessation. - -Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, receipt of a copy of some or all of the same material does -not give you any rights to use it. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -@uref{http://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. If the Document -specifies that a proxy can decide which future versions of this -License can be used, that proxy's public statement of acceptance of a -version permanently authorizes you to choose that version for the -Document. - -@item -RELICENSING - -``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any -World Wide Web server that publishes copyrightable works and also -provides prominent facilities for anybody to edit those works. A -public wiki that anybody can edit is an example of such a server. A -``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the -site means any set of copyrightable works thus published on the MMC -site. - -``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 -license published by Creative Commons Corporation, a not-for-profit -corporation with a principal place of business in San Francisco, -California, as well as future copyleft versions of that license -published by that same organization. - -``Incorporate'' means to publish or republish a Document, in whole or -in part, as part of another Document. - -An MMC is ``eligible for relicensing'' if it is licensed under this -License, and if all works that were first published under this License -somewhere other than this MMC, and subsequently incorporated in whole -or in part into the MMC, (1) had no cover texts or invariant sections, -and (2) were thus incorporated prior to November 1, 2008. - -The operator of an MMC Site may republish an MMC contained in the site -under CC-BY-SA on the same site at any time before August 1, 2009, -provided the MMC is eligible for relicensing. - -@end enumerate - -@page -@heading ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@smallexample -@group - Copyright (C) @var{year} @var{your name}. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.3 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. A copy of the license is included in the section entitled ``GNU - Free Documentation License''. -@end group -@end smallexample - -If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the ``with@dots{}Texts.''@: line with this: - -@smallexample -@group - with the Invariant Sections being @var{list their titles}, with - the Front-Cover Texts being @var{list}, and with the Back-Cover Texts - being @var{list}. -@end group -@end smallexample - -If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. - -@c Local Variables: -@c ispell-local-pdict: "ispell-dict" -@c End: diff --git a/doc/specification/gpl-3.0.texi b/doc/specification/gpl-3.0.texi @@ -1,717 +0,0 @@ -@c The GNU General Public License. -@center Version 3, 29 June 2007 - -@c This file is intended to be included within another document, -@c hence no sectioning command or @node. - -@display -Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/} - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. -@end display - -@heading Preamble - -The GNU General Public License is a free, copyleft license for -software and other kinds of works. - -The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom -to share and change all versions of a program---to make sure it remains -free software for all its users. We, the Free Software Foundation, -use the GNU General Public License for most of our software; it -applies also to any other work released this way by its authors. You -can apply it to your programs, too. - -When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - -To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you -have certain responsibilities if you distribute copies of the -software, or if you modify it: responsibilities to respect the freedom -of others. - -For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, -receive or can get the source code. And you must show them these -terms so they know their rights. - -Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - -For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - -Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the -manufacturer can do so. This is fundamentally incompatible with the -aim of protecting users' freedom to change the software. The -systematic pattern of such abuse occurs in the area of products for -individuals to use, which is precisely where it is most unacceptable. -Therefore, we have designed this version of the GPL to prohibit the -practice for those products. If such problems arise substantially in -other domains, we stand ready to extend this provision to those -domains in future versions of the GPL, as needed to protect the -freedom of users. - -Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish -to avoid the special danger that patents applied to a free program -could make it effectively proprietary. To prevent this, the GPL -assures that patents cannot be used to render the program non-free. - -The precise terms and conditions for copying, distribution and -modification follow. - -@heading TERMS AND CONDITIONS - -@enumerate 0 -@item Definitions. - -``This License'' refers to version 3 of the GNU General Public License. - -``Copyright'' also means copyright-like laws that apply to other kinds -of works, such as semiconductor masks. - -``The Program'' refers to any copyrightable work licensed under this -License. Each licensee is addressed as ``you''. ``Licensees'' and -``recipients'' may be individuals or organizations. - -To ``modify'' a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of -an exact copy. The resulting work is called a ``modified version'' of -the earlier work or a work ``based on'' the earlier work. - -A ``covered work'' means either the unmodified Program or a work based -on the Program. - -To ``propagate'' a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - -To ``convey'' a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user -through a computer network, with no transfer of a copy, is not -conveying. - -An interactive user interface displays ``Appropriate Legal Notices'' to -the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - -@item Source Code. - -The ``source code'' for a work means the preferred form of the work for -making modifications to it. ``Object code'' means any non-source form -of a work. - -A ``Standard Interface'' means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - -The ``System Libraries'' of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -``Major Component'', in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - -The ``Corresponding Source'' for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - -The Corresponding Source need not include anything that users can -regenerate automatically from other parts of the Corresponding Source. - -The Corresponding Source for a work in source code form is that same -work. - -@item Basic Permissions. - -All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - -You may make, run and propagate covered works that you do not convey, -without conditions so long as your license otherwise remains in force. -You may convey covered works to others for the sole purpose of having -them make modifications exclusively for you, or provide you with -facilities for running those works, provided that you comply with the -terms of this License in conveying all material for which you do not -control copyright. Those thus making or running the covered works for -you must do so exclusively on your behalf, under your direction and -control, on terms that prohibit them from making any copies of your -copyrighted material outside their relationship with you. - -Conveying under any other circumstances is permitted solely under the -conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - -@item Protecting Users' Legal Rights From Anti-Circumvention Law. - -No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - -When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such -circumvention is effected by exercising rights under this License with -respect to the covered work, and you disclaim any intention to limit -operation or modification of the work as a means of enforcing, against -the work's users, your or third parties' legal rights to forbid -circumvention of technological measures. - -@item Conveying Verbatim Copies. - -You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - -You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - -@item Conveying Modified Source Versions. - -You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these -conditions: - -@enumerate a -@item -The work must carry prominent notices stating that you modified it, -and giving a relevant date. - -@item -The work must carry prominent notices stating that it is released -under this License and any conditions added under section 7. This -requirement modifies the requirement in section 4 to ``keep intact all -notices''. - -@item -You must license the entire work, as a whole, under this License to -anyone who comes into possession of a copy. This License will -therefore apply, along with any applicable section 7 additional terms, -to the whole of the work, and all its parts, regardless of how they -are packaged. This License gives no permission to license the work in -any other way, but it does not invalidate such permission if you have -separately received it. - -@item -If the work has interactive user interfaces, each must display -Appropriate Legal Notices; however, if the Program has interactive -interfaces that do not display Appropriate Legal Notices, your work -need not make them do so. -@end enumerate - -A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -``aggregate'' if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - -@item Conveying Non-Source Forms. - -You may convey a covered work in object code form under the terms of -sections 4 and 5, provided that you also convey the machine-readable -Corresponding Source under the terms of this License, in one of these -ways: - -@enumerate a -@item -Convey the object code in, or embodied in, a physical product -(including a physical distribution medium), accompanied by the -Corresponding Source fixed on a durable physical medium customarily -used for software interchange. - -@item -Convey the object code in, or embodied in, a physical product -(including a physical distribution medium), accompanied by a written -offer, valid for at least three years and valid for as long as you -offer spare parts or customer support for that product model, to give -anyone who possesses the object code either (1) a copy of the -Corresponding Source for all the software in the product that is -covered by this License, on a durable physical medium customarily used -for software interchange, for a price no more than your reasonable -cost of physically performing this conveying of source, or (2) access -to copy the Corresponding Source from a network server at no charge. - -@item -Convey individual copies of the object code with a copy of the written -offer to provide the Corresponding Source. This alternative is -allowed only occasionally and noncommercially, and only if you -received the object code with such an offer, in accord with subsection -6b. - -@item -Convey the object code by offering access from a designated place -(gratis or for a charge), and offer equivalent access to the -Corresponding Source in the same way through the same place at no -further charge. You need not require recipients to copy the -Corresponding Source along with the object code. If the place to copy -the object code is a network server, the Corresponding Source may be -on a different server (operated by you or a third party) that supports -equivalent copying facilities, provided you maintain clear directions -next to the object code saying where to find the Corresponding Source. -Regardless of what server hosts the Corresponding Source, you remain -obligated to ensure that it is available for as long as needed to -satisfy these requirements. - -@item -Convey the object code using peer-to-peer transmission, provided you -inform other peers where the object code and Corresponding Source of -the work are being offered to the general public at no charge under -subsection 6d. - -@end enumerate - -A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - -A ``User Product'' is either (1) a ``consumer product'', which means any -tangible personal property which is normally used for personal, -family, or household purposes, or (2) anything designed or sold for -incorporation into a dwelling. In determining whether a product is a -consumer product, doubtful cases shall be resolved in favor of -coverage. For a particular product received by a particular user, -``normally used'' refers to a typical or common use of that class of -product, regardless of the status of the particular user or of the way -in which the particular user actually uses, or expects or is expected -to use, the product. A product is a consumer product regardless of -whether the product has substantial commercial, industrial or -non-consumer uses, unless such uses represent the only significant -mode of use of the product. - -``Installation Information'' for a User Product means any methods, -procedures, authorization keys, or other information required to -install and execute modified versions of a covered work in that User -Product from a modified version of its Corresponding Source. The -information must suffice to ensure that the continued functioning of -the modified object code is in no case prevented or interfered with -solely because modification has been made. - -If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - -The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or -updates for a work that has been modified or installed by the -recipient, or for the User Product in which it has been modified or -installed. Access to a network may be denied when the modification -itself materially and adversely affects the operation of the network -or violates the rules and protocols for communication across the -network. - -Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - -@item Additional Terms. - -``Additional permissions'' are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - -Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders -of that material) supplement the terms of this License with terms: - -@enumerate a -@item -Disclaiming warranty or limiting liability differently from the terms -of sections 15 and 16 of this License; or - -@item -Requiring preservation of specified reasonable legal notices or author -attributions in that material or in the Appropriate Legal Notices -displayed by works containing it; or - -@item -Prohibiting misrepresentation of the origin of that material, or -requiring that modified versions of such material be marked in -reasonable ways as different from the original version; or - -@item -Limiting the use for publicity purposes of names of licensors or -authors of the material; or - -@item -Declining to grant rights under trademark law for use of some trade -names, trademarks, or service marks; or - -@item -Requiring indemnification of licensors and authors of that material by -anyone who conveys the material (or modified versions of it) with -contractual assumptions of liability to the recipient, for any -liability that these contractual assumptions directly impose on those -licensors and authors. -@end enumerate - -All other non-permissive additional terms are considered ``further -restrictions'' within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - -If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; the -above requirements apply either way. - -@item Termination. - -You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - -However, if you cease all violation of this License, then your license -from a particular copyright holder is reinstated (a) provisionally, -unless and until the copyright holder explicitly and finally -terminates your license, and (b) permanently, if the copyright holder -fails to notify you of the violation by some reasonable means prior to -60 days after the cessation. - -Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - -@item Acceptance Not Required for Having Copies. - -You are not required to accept this License in order to receive or run -a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - -@item Automatic Licensing of Downstream Recipients. - -Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - -An ``entity transaction'' is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - -@item Patents. - -A ``contributor'' is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's ``contributor version''. - -A contributor's ``essential patent claims'' are all patent claims owned -or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, ``control'' includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - -In the following three paragraphs, a ``patent license'' is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To ``grant'' such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - -If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. ``Knowingly relying'' means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - -A patent license is ``discriminatory'' if it does not include within the -scope of its coverage, prohibits the exercise of, or is conditioned on -the non-exercise of one or more of the rights that are specifically -granted under this License. You may not convey a covered work if you -are a party to an arrangement with a third party that is in the -business of distributing software, under which you make payment to the -third party based on the extent of your activity of conveying the -work, and under which the third party grants, to any of the parties -who would receive the covered work from you, a discriminatory patent -license (a) in connection with copies of the covered work conveyed by -you (or copies made from those copies), or (b) primarily for and in -connection with specific products or compilations that contain the -covered work, unless you entered into that arrangement, or that patent -license was granted, prior to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - -@item No Surrender of Others' Freedom. - -If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey -a covered work so as to satisfy simultaneously your obligations under -this License and any other pertinent obligations, then as a -consequence you may not convey it at all. For example, if you agree -to terms that obligate you to collect a royalty for further conveying -from those to whom you convey the Program, the only way you could -satisfy both those terms and this License would be to refrain entirely -from conveying the Program. - -@item Use with the GNU Affero General Public License. - -Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - -@item Revised Versions of this License. - -The Free Software Foundation may publish revised and/or new versions -of the GNU General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies that a certain numbered version of the GNU General Public -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that numbered version or -of any later version published by the Free Software Foundation. If -the Program does not specify a version number of the GNU General -Public License, you may choose any version ever published by the Free -Software Foundation. - -If the Program specifies that a proxy can decide which future versions -of the GNU General Public License can be used, that proxy's public -statement of acceptance of a version permanently authorizes you to -choose that version for the Program. - -Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - -@item Disclaimer of Warranty. - -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW@. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE@. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE PROGRAM IS WITH YOU@. SHOULD THE PROGRAM PROVE -DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR -CORRECTION. - -@item Limitation of Liability. - -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR -CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT -NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR -LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM -TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER -PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -@item Interpretation of Sections 15 and 16. - -If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - -@end enumerate - -@heading END OF TERMS AND CONDITIONS - -@heading How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - -To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the ``copyright'' line and a pointer to where the full notice is found. - -@smallexample -@var{one line to give the program's name and a brief idea of what it does.} -Copyright (C) @var{year} @var{name of author} - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or (at -your option) any later version. - -This program 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 -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see @url{http://www.gnu.org/licenses/}. -@end smallexample - -Also add information on how to contact you by electronic and paper mail. - -If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - -@smallexample -@var{program} Copyright (C) @var{year} @var{name of author} -This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}. -This is free software, and you are welcome to redistribute it -under certain conditions; type @samp{show c} for details. -@end smallexample - -The hypothetical commands @samp{show w} and @samp{show c} should show -the appropriate parts of the General Public License. Of course, your -program's commands might be different; for a GUI interface, you would -use an ``about box''. - -You should also get your employer (if you work as a programmer) or school, -if any, to sign a ``copyright disclaimer'' for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -@url{http://www.gnu.org/licenses/}. - -The GNU General Public License does not permit incorporating your -program into proprietary programs. If your program is a subroutine -library, you may consider it more useful to permit linking proprietary -applications with the library. If this is what you want to do, use -the GNU Lesser General Public License instead of this License. But -first, please read @url{http://www.gnu.org/philosophy/why-not-lgpl.html}. diff --git a/doc/specification/techspec.texi b/doc/specification/techspec.texi @@ -1,87 +0,0 @@ -\input texinfo -@c -*-texinfo-*- - -@c %**start of header -@setfilename techspec.info -@documentencoding UTF-8 -@settitle GNUnet Technical Specification -@exampleindent 2 -@c %**end of header - -@include versioning.texi - -@copying -Copyright @copyright{} 2001-2018 GNUnet e.V. - -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 or -any later version published by the Free Software Foundation; with no -Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A -copy of the license is included in the section entitled ``GNU Free -Documentation License''. - -A copy of the license is also available from the Free Software -Foundation Web site at @url{http://www.gnu.org/licenses/fdl.html}. - -Alternately, this document is also available under the General -Public License, version 3 or later, as published by the Free Software -Foundation. A copy of the license is included in the section entitled -``GNU General Public License''. - -A copy of the license is also available from the Free Software -Foundation Web site at @url{http://www.gnu.org/licenses/gpl.html}. -@end copying - -@titlepage -@title GNUnet Technical Specification -@subtitle Implementation-agnostic description of messages and processes in GNUnet -@author The GNUnet Developers - -@page -@vskip 0pt plus 1filll -Edition @value{EDITION} @* -@value{UPDATED} @* - -@insertcopying -@end titlepage - -@summarycontents -@contents - -@node Top - -@menu -* Overview:: Overview of GNUnet -* Services:: Services provided by GNUnet -* Messages:: GNUnet message formats -* GNU Free Documentation License:: The license of this manual -* GNU General Public License:: The license of this manual -* References:: References to external resources -* Index:: Index to the document -@end menu - -@c ********************************************************************* -@include chapters/overview.texi -@c ********************************************************************* - -@c ********************************************************************* -@include chapters/services.texi -@c ********************************************************************* - -@c ********************************************************************* -@include chapters/messages.texi -@c ********************************************************************* - -@c ********************************************************************* -@node GNU Free Documentation License -@appendix GNU Free Documentation License -@cindex license, GNU Free Documentation License -@include fdl-1.3.texi - -@c ********************************************************************* -@node GNU General Public License -@appendix GNU General Public License -@cindex license, GNU General Public License -@include gpl-3.0.texi - -@bye diff --git a/doc/specification/versioning.texi b/doc/specification/versioning.texi @@ -1,4 +0,0 @@ -@set UPDATED 13 June 2018 -@set UPDATED-MONTH June 2018 -@set EDITION 0.11.0 -@set VERSION 0.11.0 diff --git a/src/gnunet/build.sh b/src/gnunet/build.sh @@ -1,3 +1,4 @@ #!/bin/bash +go generate ./... go install -v -gcflags "-N -l" ./... diff --git a/src/gnunet/cmd/gnunet-service-dht-go/main.go b/src/gnunet/cmd/gnunet-service-dht-go/main.go @@ -21,6 +21,7 @@ package main import ( "context" "flag" + "net/rpc" "os" "os/signal" "strings" @@ -29,7 +30,6 @@ import ( "gnunet/config" "gnunet/core" - "gnunet/rpc" "gnunet/service" "gnunet/service/dht" @@ -91,14 +91,18 @@ func main() { defer c.Shutdown() // start a new DHT service - dht := dht.NewService(ctx, c) - srv := service.NewSocketHandler("dht", dht) + var dhtSrv service.Service + if dhtSrv, err = dht.NewService(ctx, c); err != nil { + logger.Printf(logger.ERROR, "[dht] failed to create DHT service: %s\n", err.Error()) + return + } + srv := service.NewSocketHandler("dht", dhtSrv) if err = srv.Start(ctx, socket, params); err != nil { logger.Printf(logger.ERROR, "[dht] Failed to start DHT service: '%s'", err.Error()) return } - // start JSON-RPC server on request + // handle command-line arguments for RPC if len(rpcEndp) > 0 { parts := strings.Split(rpcEndp, ":") if parts[0] != "tcp" { @@ -106,11 +110,15 @@ func main() { return } config.Cfg.RPC.Endpoint = parts[1] - if err = rpc.Start(ctx); err != nil { + } + // start JSON-RPC server on request + if ep := config.Cfg.RPC.Endpoint; len(ep) > 0 { + var rpc *rpc.Server + if rpc, err = service.StartRPC(ctx, ep); err != nil { logger.Printf(logger.ERROR, "[dht] RPC failed to start: %s", err.Error()) return } - rpc.Register(dht) + dhtSrv.InitRPC(rpc) } // handle OS signals diff --git a/src/gnunet/cmd/gnunet-service-gns-go/main.go b/src/gnunet/cmd/gnunet-service-gns-go/main.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -21,6 +21,7 @@ package main import ( "context" "flag" + "net/rpc" "os" "os/signal" "strings" @@ -28,7 +29,7 @@ import ( "time" "gnunet/config" - "gnunet/rpc" + "gnunet/core" "gnunet/service" "gnunet/service/gns" @@ -80,16 +81,24 @@ func main() { params = config.Cfg.GNS.Service.Params } - // start a new GNS service + // instantiate core service ctx, cancel := context.WithCancel(context.Background()) - gns := gns.NewService() + var c *core.Core + if c, err = core.NewCore(ctx, config.Cfg.Local); err != nil { + logger.Printf(logger.ERROR, "[gns] core failed: %s\n", err.Error()) + return + } + defer c.Shutdown() + + // start a new GNS service + gns := gns.NewService(ctx, c) srv := service.NewSocketHandler("gns", gns) if err = srv.Start(ctx, socket, params); err != nil { logger.Printf(logger.ERROR, "[gns] Error: '%s'", err.Error()) return } - // start JSON-RPC server on request + // handle command-line arguments for RPC if len(rpcEndp) > 0 { parts := strings.Split(rpcEndp, ":") if parts[0] != "tcp" { @@ -97,11 +106,15 @@ func main() { return } config.Cfg.RPC.Endpoint = parts[1] - if err = rpc.Start(ctx); err != nil { + } + // start JSON-RPC server on request + if ep := config.Cfg.RPC.Endpoint; len(ep) > 0 { + var rpc *rpc.Server + if rpc, err = service.StartRPC(ctx, ep); err != nil { logger.Printf(logger.ERROR, "[gns] RPC failed to start: %s", err.Error()) return } - rpc.Register(gns) + gns.InitRPC(rpc) } // handle OS signals diff --git a/src/gnunet/cmd/gnunet-service-revocation-go/main.go b/src/gnunet/cmd/gnunet-service-revocation-go/main.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -21,6 +21,7 @@ package main import ( "context" "flag" + "net/rpc" "os" "os/signal" "strings" @@ -28,7 +29,7 @@ import ( "time" "gnunet/config" - "gnunet/rpc" + "gnunet/core" "gnunet/service" "gnunet/service/revocation" @@ -80,16 +81,24 @@ func main() { params = config.Cfg.GNS.Service.Params } - // start a new REVOCATION service + // instantiate core service ctx, cancel := context.WithCancel(context.Background()) - rvc := revocation.NewService() + var c *core.Core + if c, err = core.NewCore(ctx, config.Cfg.Local); err != nil { + logger.Printf(logger.ERROR, "[gns] core failed: %s\n", err.Error()) + return + } + defer c.Shutdown() + + // start a new REVOCATION service + rvc := revocation.NewService(ctx, c) srv := service.NewSocketHandler("revocation", rvc) if err = srv.Start(ctx, socket, params); err != nil { logger.Printf(logger.ERROR, "[revocation] Error: '%s'\n", err.Error()) return } - // start JSON-RPC server on request + // handle command-line arguments for RPC if len(rpcEndp) > 0 { parts := strings.Split(rpcEndp, ":") if parts[0] != "tcp" { @@ -97,11 +106,15 @@ func main() { return } config.Cfg.RPC.Endpoint = parts[1] - if err = rpc.Start(ctx); err != nil { + } + // start JSON-RPC server on request + if ep := config.Cfg.RPC.Endpoint; len(ep) > 0 { + var rpc *rpc.Server + if rpc, err = service.StartRPC(ctx, ep); err != nil { logger.Printf(logger.ERROR, "[revocation] RPC failed to start: %s", err.Error()) return } - rpc.Register(rvc) + rvc.InitRPC(rpc) } // handle OS signals diff --git a/src/gnunet/cmd/revoke-zonekey/main.go b/src/gnunet/cmd/revoke-zonekey/main.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/config/config.go b/src/gnunet/config/config.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/config/config_test.go b/src/gnunet/config/config_test.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/config/gnunet-config.json b/src/gnunet/config/gnunet-config.json @@ -1,7 +1,7 @@ { "bootstrap": { "nodes": [ - "gnunet://hello/7KTBJ90340HF1Q2GB0A57E2XJER4FDHX8HP5GHEB9125VPWPD27G/BNMDFN6HJCPWSPNBSEC06MC1K8QN1Z2DHRQSRXDTFR7FTBD4JHNBJ2RJAAEZ31FWG1Q3PMN3PXGZQ3Q7NTNEKQZFA7TE2Y46FM8E20R/1653499308?r5n%2Bip%2Budp%3A127.0.0.1%3A7654" + "gnunet://hello/7KTBJ90340HF1Q2GB0A57E2XJER4FDHX8HP5GHEB9125VPWPD27G/BNMDFN6HJCPWSPNBSEC06MC1K8QN1Z2DHRQSRXDTFR7FTBD4JHNBJ2RJAAEZ31FWG1Q3PMN3PXGZQ3Q7NTNEKQZFA7TE2Y46FM8E20R/1653499308?r5n+ip+udp=127.0.0.1%3A7654" ] }, "local": { diff --git a/src/gnunet/core/core.go b/src/gnunet/core/core.go @@ -29,6 +29,8 @@ import ( "net" "strings" "time" + + "github.com/bfix/gospel/logger" ) //---------------------------------------------------------------------- @@ -146,49 +148,68 @@ func NewCore(ctx context.Context, node *config.NodeConfig) (c *Core, err error) } } // run message pump - go func() { - // wait for incoming messages - for { - select { - // get (next) message from transport - case tm := <-c.incoming: - var ev *Event - - // inspect message for peer state events - switch msg := tm.Msg.(type) { - case *message.HelloMsg: - // keep peer addresses - for _, addr := range msg.Addresses { - a := &util.Address{ - Netw: addr.Transport, - Address: addr.Address, - Expires: addr.ExpireOn, - } - c.Learn(ctx, msg.PeerID, a) - } - // generate EV_CONNECT event - ev = &Event{ - ID: EV_CONNECT, - Peer: tm.Peer, - Msg: msg, - } - c.dispatch(ev) + go c.pump(ctx) + return +} + +// message pump for core +func (c *Core) pump(ctx context.Context) { + // wait for incoming messages + for { + select { + // get (next) message from transport + case tm := <-c.incoming: + var ev *Event + + // inspect message for peer state events + switch msg := tm.Msg.(type) { + case *message.HelloDHTMsg: + logger.Println(logger.INFO, "[core] Received HELLO message: "+msg.String()) + // verify integrity of message + if ok, err := msg.Verify(tm.Peer); !ok || err != nil { + logger.Println(logger.WARN, "[core] Received invalid DHT_P2P_HELLO message") + break + } + // keep peer addresses + aList, err := msg.Addresses() + if err != nil { + logger.Println(logger.WARN, "[core] Failed to parse addresses from DHT_P2P_HELLO message") + break } - // generate EV_MESSAGE event + for _, addr := range aList { + c.Learn(ctx, tm.Peer, addr.Wrap()) + } + // generate EV_CONNECT event ev = &Event{ - ID: EV_MESSAGE, + ID: EV_CONNECT, Peer: tm.Peer, - Msg: tm.Msg, + Msg: msg, } c.dispatch(ev) - - // wait for termination - case <-ctx.Done(): - return } + // set default responder (core) if no custom responder + // is defined by the receiving endpoint. + resp := tm.Resp + if resp == nil { + resp = &transport.TransportResponder{ + Peer: tm.Peer, + SendFcn: c.Send, + } + } + // generate EV_MESSAGE event + ev = &Event{ + ID: EV_MESSAGE, + Peer: tm.Peer, + Msg: tm.Msg, + Resp: tm.Resp, + } + c.dispatch(ev) + + // wait for termination + case <-ctx.Done(): + return } - }() - return + } } // Shutdown all core-related processes. @@ -202,32 +223,24 @@ func (c *Core) Shutdown() { // Send is a function that allows the local peer to send a protocol // message to a remote peer. func (c *Core) Send(ctx context.Context, peer *util.PeerID, msg message.Message) error { + // get peer label (id or "@") + label := "@" + if peer != nil { + label = peer.String() + } // TODO: select best endpoint protocol for transport; now fixed to IP+UDP netw := "ip+udp" - addrs := c.peers.Get(peer.String(), netw) + addrs := c.peers.Get(label, netw) if len(addrs) == 0 { return ErrCoreNoEndpAddr } // TODO: select best address; curently selects first addr := addrs[0] + return c.send(ctx, addr, msg) +} - // select best endpoint for transport - var ep transport.Endpoint - for _, epCfg := range c.endpoints { - if epCfg.addr.Network() == netw { - if ep == nil { - ep = epCfg.ep - } - // TODO: compare endpoints, select better one: - // if ep.Better(epCfg.ep) { - // ep = epCfg.ep - // } - } - } - // check we have an endpoint to send on - if ep == nil { - return ErrCoreNoEndpAddr - } +// send message directly to address +func (c *Core) send(ctx context.Context, addr *util.Address, msg message.Message) error { // assemble transport message tm := transport.NewTransportMessage(c.PeerID(), msg) // send on transport @@ -236,26 +249,33 @@ func (c *Core) Send(ctx context.Context, peer *util.PeerID, msg message.Message) // Learn a (new) address for peer func (c *Core) Learn(ctx context.Context, peer *util.PeerID, addr *util.Address) (err error) { + // assemble our own HELLO message: + addrList := make([]*util.Address, 0) + for _, epRef := range c.endpoints { + addrList = append(addrList, epRef.addr) + } + node := c.local + var hello *blocks.HelloBlock + hello, err = node.HelloData(time.Hour, addrList) + if err != nil { + return + } + msg := message.NewHelloDHTMsg() + var aList []*message.HelloAddress + msg.NumAddr = uint16(len(hello.Addresses())) + for _, a := range hello.Addresses() { + ha := message.NewHelloAddress(a) + aList = append(aList, ha) + } + msg.SetAddresses(aList) + + // if no peer is given, we send HELLO directly to address + if peer == nil { + return c.send(ctx, addr, msg) + } + // add peer address to address list if c.peers.Add(peer.String(), addr) == 1 { // we added a previously unknown peer: send a HELLO - - // collect endpoint addresses - addrList := make([]*util.Address, 0) - for _, epRef := range c.endpoints { - addrList = append(addrList, epRef.addr) - } - // new peer id: send HELLO message to newly added peer - node := c.local - var hello *blocks.HelloBlock - hello, err = node.HelloData(time.Hour, addrList) - if err != nil { - return - } - msg := message.NewHelloMsg(node.GetID()) - for _, a := range hello.Addresses() { - ha := message.NewHelloAddress(a) - msg.AddAddress(ha) - } err = c.Send(ctx, peer, msg) } return diff --git a/src/gnunet/core/core_test.go b/src/gnunet/core/core_test.go @@ -19,10 +19,13 @@ package core import ( + "bytes" "context" "encoding/hex" "gnunet/config" + "gnunet/transport" "gnunet/util" + "log" "testing" "time" ) @@ -165,6 +168,64 @@ func TestCoreUPNP(t *testing.T) { } //---------------------------------------------------------------------- +// Test Go node with DHTU GNUnet nodes +//---------------------------------------------------------------------- + +var testDHTU = false + +func TestDHTU(t *testing.T) { + // skip test on demand + if !testDHTU { + return + } + // convert arguments + var ( + rId *util.PeerID + rAddr *util.Address + err error + ) + if rAddr, err = util.ParseAddress("ip+udp://172.17.0.4:10000"); err != nil { + t.Fatal(err) + } + // configuration data + var ( + peerCfg = &config.NodeConfig{ + Name: "p1", + PrivateSeed: "iYK1wSi5XtCP774eNFk1LYXqKlOPEpwKBw+2/bMkE24=", + Endpoints: []*config.EndpointConfig{ + { + ID: "p1", + Network: "ip+udp", + Address: "172.17.0.1", + Port: 2086, + TTL: 86400, + }, + }, + } + ) + // setup execution context + ctx, cancel := context.WithCancel(context.Background()) + defer func() { + cancel() + time.Sleep(time.Second) + }() + + // create and run node + node, err := NewTestNode(t, ctx, peerCfg) + if err != nil { + log.Fatal(err) + } + defer node.Shutdown() + + // learn bootstrap address (triggers HELLO) + node.Learn(ctx, rId, rAddr) + + // run forever + var ch chan struct{} + <-ch +} + +//---------------------------------------------------------------------- // create and run a node with given spec //---------------------------------------------------------------------- @@ -181,7 +242,11 @@ func (n *TestNode) Shutdown() { } func (n *TestNode) Learn(ctx context.Context, peer *util.PeerID, addr *util.Address) { - n.t.Logf("[%d] Learning %s for %s", n.id, addr.StringAll(), peer.String()) + label := "@" + if peer != nil { + label = peer.String() + } + n.t.Logf("[%d] Learning %s for %s", n.id, addr.StringAll(), label) if err := n.core.Learn(ctx, peer, addr); err != nil { n.t.Log("Learn: " + err.Error()) } @@ -199,11 +264,6 @@ func NewTestNode(t *testing.T, ctx context.Context, cfg *config.NodeConfig) (nod return } node.peer = node.core.Peer() - - // create peer object - if node.peer, err = NewLocalPeer(cfg); err != nil { - return - } t.Logf("[%d] Node %s starting", node.id, node.peer.GetID()) t.Logf("[%d] --> %s", node.id, hex.EncodeToString(node.peer.GetID().Key)) @@ -240,6 +300,12 @@ func NewTestNode(t *testing.T, ctx context.Context, cfg *config.NodeConfig) (nod case EV_MESSAGE: t.Logf("[%d] <<< Msg from %s of type %d", node.id, ev.Peer, ev.Msg.Header().MsgType) t.Logf("[%d] <<< --> %s", node.id, ev.Msg.String()) + wrt := new(bytes.Buffer) + if err := transport.WriteMessageDirect(wrt, ev.Msg); err == nil { + t.Logf("[%d] <<< %s", node.id, hex.EncodeToString(wrt.Bytes())) + } else { + t.Logf("[%d] <<< Error %s", node.id, err.Error()) + } } // handle termination signal diff --git a/src/gnunet/core/event.go b/src/gnunet/core/event.go @@ -20,6 +20,7 @@ package core import ( "gnunet/message" + "gnunet/transport" "gnunet/util" ) @@ -83,9 +84,11 @@ func (f *EventFilter) CheckMsgType(mt uint16) bool { // Event sent to listeners type Event struct { - ID int // event type - Peer *util.PeerID // remote peer - Msg message.Message // GNUnet message (can be nil) + ID int // event type + Peer *util.PeerID // remote peer + Msg message.Message // GNUnet message (can be nil) + Resp transport.Responder // reply handler (can be nil) + Label string // event label (can be empty) } //---------------------------------------------------------------------- diff --git a/src/gnunet/core/hello_test.go b/src/gnunet/core/hello_test.go @@ -0,0 +1,107 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019-2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +package core + +import ( + "fmt" + "gnunet/config" + "gnunet/service/dht/blocks" + "gnunet/util" + "testing" + "time" +) + +var ( + peerCfg = &config.NodeConfig{ + Name: "p1", + PrivateSeed: "iYK1wSi5XtCP774eNFk1LYXqKlOPEpwKBw+2/bMkE24=", + Endpoints: []*config.EndpointConfig{ + { + ID: "p1", + Network: "ip+udp", + Address: "172.17.0.1", + Port: 2086, + TTL: 86400, + }, + }, + } + + helloURL = []string{ + "gnunet://hello" + + "/RBVQWST48N9YDVHYM7KYR1YDBZN7X4KG1SJJZHGHGX5HFHX5P010" + + "/Y4YEXZBBKS1HFGGHZW5QWQTX20QJ5BBEQZB8PNA85VCASRR60P741X28E8HS6P20HQED43RAQFADJTVREFQ37W1YQFN29TCC2AT4R2R" + + "/1654964519" + + "?ip+udp=127.0.0.1%3A10000" + + "&ip+udp=192.168.178.50%3A10000" + + "&ip+udp=%5B%3A%3A1%5D%3A10000" + + "&ip+udp=%5B2001%3A1620%3Afe9%3A0%3A7285%3Ac2ff%3Afe62%3Ab4c9%5D%3A10000" + + "&ip+udp=%5Bfe80%3A%3A7285%3Ac2ff%3Afe62%3Ab4c9%5D%3A10000", + "gnunet://hello" + + "/6SR91X40JHTTSKTEY04KC920MDJBVDDNJ9Y2KPVY1RJK40KC1SVG" + + "/7H3BX1XDYXKXDR20X1GPCYY1CT68GGH1CC9FSDBW4MZ4H5GFB3K7PMJZTEWK3NVVJ0FXBBG6QFBWFM233F5YTQZGZ8JV5MEPNBWP800" + + "/1654953178" + + "?ip+udp=127.0.0.1%3A10000" + + "&ip+udp=172.17.0.4%3A10000" + + "&ip+udp=%5B%3A%3Affff%3A172.17.0.4%5D%3A10000", + } +) + +func TestHelloURLDirect(t *testing.T) { + for _, hu := range helloURL { + if _, err := blocks.ParseHelloURL(hu, false); err != nil { + t.Fatal(err) + } + } +} + +func TestHelloURL(t *testing.T) { + + // prepare peer and HELLO data + peer, err := NewLocalPeer(peerCfg) + if err != nil { + t.Fatal(err) + } + as := fmt.Sprintf("%s://%s:%d", + peerCfg.Endpoints[0].Network, + peerCfg.Endpoints[0].Address, + peerCfg.Endpoints[0].Port, + ) + listen, err := util.ParseAddress(as) + if err != nil { + t.Fatal(err) + } + aList := []*util.Address{listen} + hd, err := peer.HelloData(time.Hour, aList) + if err != nil { + t.Fatal(err) + } + + // convert to and from HELLO URL + url1 := hd.URL() + hd2, err := blocks.ParseHelloURL(url1, true) + if err != nil { + t.Fatal(err) + } + url2 := hd2.URL() + if url1 != url2 { + t.Log(">>> " + url1) + t.Log("<<< " + url2) + t.Fatal("urls don't match") + } +} diff --git a/src/gnunet/core/peer_test.go b/src/gnunet/core/peer_test.go @@ -65,7 +65,7 @@ func TestPeerHello(t *testing.T) { // convert to URL and back u := h.URL() t.Log(u) - h2, err := blocks.ParseHelloURL(u) + h2, err := blocks.ParseHelloURL(u, true) if err != nil { t.Fatal(err) } diff --git a/src/gnunet/crypto/gns.go b/src/gnunet/crypto/gns.go @@ -148,7 +148,7 @@ var ( ZONE_EDKEY = uint32(enums.GNS_TYPE_EDKEY) // register available zone types for BlockHandler - ZoneTypes = []int{ + ZoneTypes = []enums.GNSType{ enums.GNS_TYPE_PKEY, enums.GNS_TYPE_EDKEY, } diff --git a/src/gnunet/crypto/gns_test.go b/src/gnunet/crypto/gns_test.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/crypto/hash.go b/src/gnunet/crypto/hash.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/crypto/key_exchange.go b/src/gnunet/crypto/key_exchange.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/crypto/key_exchange_test.go b/src/gnunet/crypto/key_exchange_test.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/crypto/keys_test.go b/src/gnunet/crypto/keys_test.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -23,9 +23,10 @@ import ( "encoding/hex" "testing" + "gnunet/util" + "github.com/bfix/gospel/crypto/ed25519" "github.com/bfix/gospel/math" - "gnunet/util" ) var ( diff --git a/src/gnunet/crypto/signature.go b/src/gnunet/crypto/signature.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/enums/blocktype_string.go b/src/gnunet/enums/blocktype_string.go @@ -0,0 +1,54 @@ +// Code generated by "stringer -type=BlockType dht_block_type.go"; DO NOT EDIT. + +package enums + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[BLOCK_TYPE_ANY-0] + _ = x[BLOCK_TYPE_FS_DBLOCK-1] + _ = x[BLOCK_TYPE_FS_IBLOCK-2] + _ = x[BLOCK_TYPE_FS_ONDEMAND-6] + _ = x[BLOCK_TYPE_DHT_HELLO-7] + _ = x[BLOCK_TYPE_TEST-8] + _ = x[BLOCK_TYPE_FS_UBLOCK-9] + _ = x[BLOCK_TYPE_DNS-10] + _ = x[BLOCK_TYPE_GNS_NAMERECORD-11] + _ = x[BLOCK_TYPE_REVOCATION-12] + _ = x[BLOCK_TYPE_DHT_URL_HELLO-13] + _ = x[BLOCK_TYPE_REGEX-22] + _ = x[BLOCK_TYPE_REGEX_ACCEPT-23] + _ = x[BLOCK_TYPE_SET_TEST-24] + _ = x[BLOCK_TYPE_CONSENSUS_ELEMENT-25] + _ = x[BLOCK_TYPE_SETI_TEST-26] +} + +const ( + _BlockType_name_0 = "BLOCK_TYPE_ANYBLOCK_TYPE_FS_DBLOCKBLOCK_TYPE_FS_IBLOCK" + _BlockType_name_1 = "BLOCK_TYPE_FS_ONDEMANDBLOCK_TYPE_DHT_HELLOBLOCK_TYPE_TESTBLOCK_TYPE_FS_UBLOCKBLOCK_TYPE_DNSBLOCK_TYPE_GNS_NAMERECORDBLOCK_TYPE_REVOCATIONBLOCK_TYPE_DHT_URL_HELLO" + _BlockType_name_2 = "BLOCK_TYPE_REGEXBLOCK_TYPE_REGEX_ACCEPTBLOCK_TYPE_SET_TESTBLOCK_TYPE_CONSENSUS_ELEMENTBLOCK_TYPE_SETI_TEST" +) + +var ( + _BlockType_index_0 = [...]uint8{0, 14, 34, 54} + _BlockType_index_1 = [...]uint8{0, 22, 42, 57, 77, 91, 116, 137, 161} + _BlockType_index_2 = [...]uint8{0, 16, 39, 58, 86, 106} +) + +func (i BlockType) String() string { + switch { + case 0 <= i && i <= 2: + return _BlockType_name_0[_BlockType_index_0[i]:_BlockType_index_0[i+1]] + case 6 <= i && i <= 13: + i -= 6 + return _BlockType_name_1[_BlockType_index_1[i]:_BlockType_index_1[i+1]] + case 22 <= i && i <= 26: + i -= 22 + return _BlockType_name_2[_BlockType_index_2[i]:_BlockType_index_2[i+1]] + default: + return "BlockType(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/src/gnunet/enums/dht.go b/src/gnunet/enums/dht.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -19,7 +19,7 @@ package enums // DHT flags and settings -var ( +const ( DHT_RO_NONE = 0 // Default. Do nothing special. DHT_RO_DEMULTIPLEX_EVERYWHERE = 1 // Each peer along the way should look at 'enc' DHT_RO_RECORD_ROUTE = 2 // keep track of the route that the message took in the P2P network. @@ -30,24 +30,6 @@ var ( DHT_GNS_REPLICATION_LEVEL = 10 ) -// DHT block types -var ( - BLOCK_TYPE_ANY = 0 // Any type of block, used as a wildcard when searching. - BLOCK_TYPE_FS_DBLOCK = 1 // Data block (leaf) in the CHK tree. - BLOCK_TYPE_FS_IBLOCK = 2 // Inner block in the CHK tree. - BLOCK_TYPE_FS_KBLOCK = 3 // Legacy type, no longer in use. - BLOCK_TYPE_FS_SBLOCK = 4 // Legacy type, no longer in use. - BLOCK_TYPE_FS_NBLOCK = 5 // Legacy type, no longer in use. - BLOCK_TYPE_FS_ONDEMAND = 6 // Type of a block representing a block to be encoded on demand from disk. - BLOCK_TYPE_DHT_HELLO = 7 // Type of a block that contains a HELLO for a peer - BLOCK_TYPE_TEST = 8 // Block for testing. - BLOCK_TYPE_FS_UBLOCK = 9 // Type of a block representing any type of search result (universal). - BLOCK_TYPE_DNS = 10 // Block for storing DNS exit service advertisements. - BLOCK_TYPE_GNS_NAMERECORD = 11 // Block for storing record data - BLOCK_TYPE_REVOCATION = 12 // Block type for a revocation message by which a key is revoked. +//go:generate go run generate.go gnunet-dht.rec gnunet-dht.tpl dht_block_type.go - BLOCK_TYPE_REGEX = 22 // Block to store a cadet regex state - BLOCK_TYPE_REGEX_ACCEPT = 23 // Block to store a cadet regex accepting state - BLOCK_TYPE_SET_TEST = 24 // Block for testing set/consensus. - BLOCK_TYPE_CONSENSUS_ELEMENT = 25 // Block type for consensus elements. -) +//go:generate stringer -type=BlockType dht_block_type.go diff --git a/src/gnunet/enums/dht_block_type.go b/src/gnunet/enums/dht_block_type.go @@ -0,0 +1,27 @@ +// Code generated by enum generator; DO NOT EDIT. + +package enums + +type BlockType int + +// DHT block types +const ( +BLOCK_TYPE_ANY BlockType = 0 // Identifier for any block. +BLOCK_TYPE_FS_DBLOCK BlockType = 1 // Data block (leaf) in the CHK tree. +BLOCK_TYPE_FS_IBLOCK BlockType = 2 // Inner block in the CHK tree. +BLOCK_TYPE_FS_ONDEMAND BlockType = 6 // Type of a block representing a block to be encoded on demand from disk. Should never appear on the network directly. +BLOCK_TYPE_DHT_HELLO BlockType = 7 // Type of a block that contains a HELLO for a peer. +BLOCK_TYPE_TEST BlockType = 8 // Block for testing. +BLOCK_TYPE_FS_UBLOCK BlockType = 9 // Type of a block representing any type of search result (universal). +BLOCK_TYPE_DNS BlockType = 10 // Block for storing DNS exit service advertisements. +BLOCK_TYPE_GNS_NAMERECORD BlockType = 11 // Block for storing GNS record data. +BLOCK_TYPE_REVOCATION BlockType = 12 // Block type for a revocation message by which a key is revoked. +BLOCK_TYPE_DHT_URL_HELLO BlockType = 13 // Type of a block that contains a DHT-NG HELLO for a peer. +BLOCK_TYPE_REGEX BlockType = 22 // Block to store a cadet regex state +BLOCK_TYPE_REGEX_ACCEPT BlockType = 23 // Block to store a cadet regex accepting state +BLOCK_TYPE_SET_TEST BlockType = 24 // Block for testing set/consensus. If first byte of the block is non-zero, the block is considered invalid. +BLOCK_TYPE_CONSENSUS_ELEMENT BlockType = 25 // Block type for consensus elements. Contains either special marker elements or a nested block. +BLOCK_TYPE_SETI_TEST BlockType = 26 // Block for testing set intersection. If first byte of the block is non-zero, the block is considered invalid. + +) + diff --git a/src/gnunet/enums/generate.go b/src/gnunet/enums/generate.go @@ -0,0 +1,134 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019-2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +//go:build ignore + +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "log" + "os" + "strings" + "text/template" +) + +// Record in the GANA registry (for a given type) +type Record struct { + Number string + Name string + Comment string + References string +} + +// String returns a readable record string +func (rec *Record) String() string { + return fmt.Sprintf("[%s:%s]\n", rec.Number, rec.Name) +} + +// go:generate generator to read recfiles and fill templates (not exactly +// build on recutils but on recfiles). +func main() { + // handle command-line arguments + flag.Parse() + args := flag.Args() + if len(args) != 3 { + log.Fatal("not enough arguments") + } + + // read template + tpl, err := template.ParseFiles(args[1]) + if err != nil { + log.Fatal(err) + } + + // parse recfile + in, err := os.Open(args[0]) + if err != nil { + log.Fatal(err) + } + defer in.Close() + + rdr := bufio.NewReader(in) + state := 0 + var recs []*Record + var rec *Record + for { + // read next line from recfile + buf, _, err := rdr.ReadLine() + if err != nil { + if err == io.EOF { + break + } + } + line := strings.TrimSpace(string(buf)) + log.Printf("[%d] %s\n", state, line) + + // perform state machine: + switch state { + + // wait for record to start + case 0: + if len(line) == 0 || strings.Index("%#", string(line[0])) != -1 { + continue + } + // new record starts here + rec = new(Record) + state = 1 + fallthrough + + // read record data + case 1: + if len(line) == 0 { + // record done; add to list + log.Println("Record: " + rec.String()) + recs = append(recs, rec) + rec = nil + state = 0 + continue + } + // set attribute + kv := strings.SplitN(line, ":", 2) + switch kv[0] { + case "Number": + rec.Number = strings.TrimSpace(kv[1]) + case "Name": + rec.Name = strings.TrimSpace(kv[1]) + case "Comment": + rec.Comment = strings.TrimSpace(kv[1]) + case "References": + rec.References = strings.TrimSpace(kv[1]) + } + } + } + + // open output file + out, err := os.Create(args[2]) + if err != nil { + log.Fatal(err) + } + defer out.Close() + + // Exeute template on data + if err := tpl.Execute(out, recs); err != nil { + log.Fatal(err) + } +} diff --git a/src/gnunet/enums/gns.go b/src/gnunet/enums/gns.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -18,296 +18,21 @@ package enums -// GNS constants -var ( - GNS_MAX_BLOCK_SIZE = (63 * 1024) // Maximum size of a value that can be stored in a GNS block. - +const ( // GNS record flags GNS_FLAG_PRIVATE = 2 // Record is not shared on the DHT GNS_FLAG_SUPPL = 4 // Supplemental records (e.g. NICK) in a block GNS_FLAG_EXPREL = 8 // Expire time in record is in relative time. GNS_FLAG_SHADOW = 16 // Record is ignored if non-expired records of same type exist in block - // GNS record types - GNS_TYPE_ANY = 0 // Record type indicating any record/'*' - GNS_TYPE_DNS_A = 1 // [RFC1035] IPv4 Address record - GNS_TYPE_DNS_NS = 2 // [RFC1035] Name Server record - GNS_TYPE_DNS_CNAME = 5 // [RFC1035] Canonical Name record - GNS_TYPE_DNS_SOA = 6 // [RFC2308] Start Of [a zone of] Authority - GNS_TYPE_DNS_PTR = 12 // [RFC1035] Pointer record - GNS_TYPE_DNS_MX = 15 // [RFC7505] Mail eXchange record - GNS_TYPE_DNS_TXT = 16 // [RFC1035] Text record - GNS_TYPE_DNS_RP = 17 // [RFC1183] Responsible Person - GNS_TYPE_DNS_AFSDB = 18 // [RFC1183] AFS Database Record - GNS_TYPE_DNS_SIG = 24 // [RFC2535] Signature - GNS_TYPE_DNS_KEY = 25 // [RFC2930] Key record - GNS_TYPE_DNS_AAAA = 28 // [RFC3596] IPv6 Address record - GNS_TYPE_DNS_LOC = 29 // [RFC1876] Location record - GNS_TYPE_DNS_SRV = 33 // [RFC2782] Service locator - GNS_TYPE_DNS_NAPTR = 35 // [RFC3403] Naming Authority Pointer - GNS_TYPE_DNS_KX = 36 // [RFC2230] Key eXchanger record - GNS_TYPE_DNS_CERT = 37 // [RFC4398] Certificate record - GNS_TYPE_DNS_DNAME = 39 // [RFC2672] Delegation Name - GNS_TYPE_DNS_APL = 42 // [RFC3123] Address Prefix List - GNS_TYPE_DNS_DS = 43 // [RFC4034] Delegation Signer - GNS_TYPE_DNS_SSHFP = 44 // [RFC4255] SSH public key Fingerprint - GNS_TYPE_DNS_IPSECKEY = 45 // [RFC4025] IPsec Key - GNS_TYPE_DNS_RRSIG = 46 // [RFC4034] DNSSEC Signature - GNS_TYPE_DNS_NSEC = 47 // [RFC4034] Next-Secure record - GNS_TYPE_DNS_DNSKEY = 48 // [RFC4034] DNS Key record - GNS_TYPE_DNS_DHCID = 49 // [RFC4701] DHCP Identifier - GNS_TYPE_DNS_NSEC3 = 50 // [RFC5155] NSEC record version 3 or NSEC hashed - GNS_TYPE_DNS_NSEC3PARAM = 51 // [RFC5155] NSEC3 Parameters - GNS_TYPE_DNS_TLSA = 52 // [RFC6698] TLSA certificate association - GNS_TYPE_DNS_HIP = 55 // [RFC5205] Host Identity Protocol - GNS_TYPE_DNS_CDS = 59 // [RFC7344] Child DS - GNS_TYPE_DNS_CDNSKEY = 60 // [RFC7344] Child DNSKEY - GNS_TYPE_DNS_TKEY = 249 // [RFC2930] Secret Key - GNS_TYPE_DNS_TSIG = 250 // [RFC2845] Transaction Signature - GNS_TYPE_DNS_URI = 256 // [RFC7553] Uniform Resource Identifier - GNS_TYPE_DNS_CAA = 257 // [RFC6844] Certification Authority Authorization - GNS_TYPE_DNS_TA = 32768 // [–] DNSSEC Trust Authorities - GNS_TYPE_DNS_DLV = 32769 // [RFC4431] DNSSEC Lookaside Validation record - GNS_TYPE_PKEY = 65536 // Record type for GNS zone transfer ("PKEY"). - GNS_TYPE_NICK = 65537 // Record type for GNS nick names ("NICK"). - GNS_TYPE_LEHO = 65538 // Record type for GNS legacy hostnames ("LEHO"). - GNS_TYPE_VPN = 65539 // Record type for VPN resolution - GNS_TYPE_GNS2DNS = 65540 // Record type for delegation to DNS. - GNS_TYPE_BOX = 65541 // Record type for a boxed record (see TLSA/SRV handling in GNS). - GNS_TYPE_PLACE = 65542 // Record type for a social place. - GNS_TYPE_PHONE = 65543 // Record type for a phone (of CONVERSATION). - GNS_TYPE_RECLAIM_ATTR = 65544 // Record type for identity attributes (of RECLAIM). - GNS_TYPE_RECLAIM_TICKET = 65545 // Record type for local ticket references - GNS_TYPE_CREDENTIAL = 65547 // Record type for credential - GNS_TYPE_POLICY = 65548 // Record type for policies - GNS_TYPE_ATTRIBUTE = 65549 // Record type for reverse lookups - GNS_TYPE_RECLAIM_ATTR_REF = 65550 // Record type for reclaim records - GNS_TYPE_RECLAIM_MASTER = 65551 // Record type for RECLAIM master - GNS_TYPE_RECLAIM_OIDC_CLIENT = 65552 // Record type for reclaim OIDC clients - GNS_TYPE_RECLAIM_OIDC_REDIRECT = 65553 // Record type for reclaim OIDC redirect URIs - GNS_TYPE_EDKEY = 65556 // Record type for GNS zone transfer ("EDKEY"). - - GNS_TYPE = map[int]string{ - GNS_TYPE_ANY: "GNS_TYPE_ANY", - GNS_TYPE_DNS_A: "GNS_TYPE_DNS_A", - GNS_TYPE_DNS_NS: "GNS_TYPE_DNS_NS ", - GNS_TYPE_DNS_NS: "GNS_TYPE_DNS_NS", - GNS_TYPE_DNS_NS: "GNS_TYPE_DNS_NS", - GNS_TYPE_DNS_CNAME: "GNS_TYPE_DNS_CNAME ", - GNS_TYPE_DNS_NS: "GNS_TYPE_DNS_NS", - GNS_TYPE_DNS_CNAME: "GNS_TYPE_DNS_CNAME", - GNS_TYPE_DNS_CNAME: "GNS_TYPE_DNS_CNAME", - GNS_TYPE_DNS_SOA: "GNS_TYPE_DNS_SOA ", - GNS_TYPE_DNS_CNAME: "GNS_TYPE_DNS_CNAME", - GNS_TYPE_DNS_SOA: "GNS_TYPE_DNS_SOA", - GNS_TYPE_DNS_SOA: "GNS_TYPE_DNS_SOA", - GNS_TYPE_DNS_PTR: "GNS_TYPE_DNS_PTR ", - GNS_TYPE_DNS_SOA: "GNS_TYPE_DNS_SOA", - GNS_TYPE_DNS_PTR: "GNS_TYPE_DNS_PTR", - GNS_TYPE_DNS_PTR: "GNS_TYPE_DNS_PTR", - GNS_TYPE_DNS_MX: "GNS_TYPE_DNS_MX ", - GNS_TYPE_DNS_PTR: "GNS_TYPE_DNS_PTR", - GNS_TYPE_DNS_MX: "GNS_TYPE_DNS_MX", - GNS_TYPE_DNS_MX: "GNS_TYPE_DNS_MX", - GNS_TYPE_DNS_TXT: "GNS_TYPE_DNS_TXT ", - GNS_TYPE_DNS_MX: "GNS_TYPE_DNS_MX", - GNS_TYPE_DNS_TXT: "GNS_TYPE_DNS_TXT", - GNS_TYPE_DNS_TXT: "GNS_TYPE_DNS_TXT", - GNS_TYPE_DNS_RP: "GNS_TYPE_DNS_RP ", - GNS_TYPE_DNS_TXT: "GNS_TYPE_DNS_TXT", - GNS_TYPE_DNS_RP: "GNS_TYPE_DNS_RP", - GNS_TYPE_DNS_RP: "GNS_TYPE_DNS_RP", - GNS_TYPE_DNS_AFSDB: "GNS_TYPE_DNS_AFSDB ", - GNS_TYPE_DNS_RP: "GNS_TYPE_DNS_RP", - GNS_TYPE_DNS_AFSDB: "GNS_TYPE_DNS_AFSDB", - GNS_TYPE_DNS_AFSDB: "GNS_TYPE_DNS_AFSDB", - GNS_TYPE_DNS_SIG: "GNS_TYPE_DNS_SIG ", - GNS_TYPE_DNS_AFSDB: "GNS_TYPE_DNS_AFSDB", - GNS_TYPE_DNS_SIG: "GNS_TYPE_DNS_SIG", - GNS_TYPE_DNS_SIG: "GNS_TYPE_DNS_SIG", - GNS_TYPE_DNS_KEY: "GNS_TYPE_DNS_KEY ", - GNS_TYPE_DNS_SIG: "GNS_TYPE_DNS_SIG", - GNS_TYPE_DNS_KEY: "GNS_TYPE_DNS_KEY", - GNS_TYPE_DNS_KEY: "GNS_TYPE_DNS_KEY", - GNS_TYPE_DNS_AAAA: "GNS_TYPE_DNS_AAAA ", - GNS_TYPE_DNS_KEY: "GNS_TYPE_DNS_KEY", - GNS_TYPE_DNS_AAAA: "GNS_TYPE_DNS_AAAA", - GNS_TYPE_DNS_AAAA: "GNS_TYPE_DNS_AAAA", - GNS_TYPE_DNS_LOC: "GNS_TYPE_DNS_LOC ", - GNS_TYPE_DNS_AAAA: "GNS_TYPE_DNS_AAAA", - GNS_TYPE_DNS_LOC: "GNS_TYPE_DNS_LOC", - GNS_TYPE_DNS_LOC: "GNS_TYPE_DNS_LOC", - GNS_TYPE_DNS_SRV: "GNS_TYPE_DNS_SRV ", - GNS_TYPE_DNS_LOC: "GNS_TYPE_DNS_LOC", - GNS_TYPE_DNS_SRV: "GNS_TYPE_DNS_SRV", - GNS_TYPE_DNS_SRV: "GNS_TYPE_DNS_SRV", - GNS_TYPE_DNS_NAPTR: "GNS_TYPE_DNS_NAPTR ", - GNS_TYPE_DNS_SRV: "GNS_TYPE_DNS_SRV", - GNS_TYPE_DNS_NAPTR: "GNS_TYPE_DNS_NAPTR", - GNS_TYPE_DNS_NAPTR: "GNS_TYPE_DNS_NAPTR", - GNS_TYPE_DNS_KX: "GNS_TYPE_DNS_KX ", - GNS_TYPE_DNS_NAPTR: "GNS_TYPE_DNS_NAPTR", - GNS_TYPE_DNS_KX: "GNS_TYPE_DNS_KX", - GNS_TYPE_DNS_KX: "GNS_TYPE_DNS_KX", - GNS_TYPE_DNS_CERT: "GNS_TYPE_DNS_CERT ", - GNS_TYPE_DNS_KX: "GNS_TYPE_DNS_KX", - GNS_TYPE_DNS_CERT: "GNS_TYPE_DNS_CERT", - GNS_TYPE_DNS_CERT: "GNS_TYPE_DNS_CERT", - GNS_TYPE_DNS_DNAME: "GNS_TYPE_DNS_DNAME ", - GNS_TYPE_DNS_CERT: "GNS_TYPE_DNS_CERT", - GNS_TYPE_DNS_DNAME: "GNS_TYPE_DNS_DNAME", - GNS_TYPE_DNS_DNAME: "GNS_TYPE_DNS_DNAME", - GNS_TYPE_DNS_APL: "GNS_TYPE_DNS_APL ", - GNS_TYPE_DNS_DNAME: "GNS_TYPE_DNS_DNAME", - GNS_TYPE_DNS_APL: "GNS_TYPE_DNS_APL", - GNS_TYPE_DNS_APL: "GNS_TYPE_DNS_APL", - GNS_TYPE_DNS_DS: "GNS_TYPE_DNS_DS ", - GNS_TYPE_DNS_APL: "GNS_TYPE_DNS_APL", - GNS_TYPE_DNS_DS: "GNS_TYPE_DNS_DS", - GNS_TYPE_DNS_DS: "GNS_TYPE_DNS_DS", - GNS_TYPE_DNS_SSHFP: "GNS_TYPE_DNS_SSHFP ", - GNS_TYPE_DNS_DS: "GNS_TYPE_DNS_DS", - GNS_TYPE_DNS_SSHFP: "GNS_TYPE_DNS_SSHFP", - GNS_TYPE_DNS_SSHFP: "GNS_TYPE_DNS_SSHFP", - GNS_TYPE_DNS_IPSECKEY: "GNS_TYPE_DNS_IPSECKEY ", - GNS_TYPE_DNS_SSHFP: "GNS_TYPE_DNS_SSHFP", - GNS_TYPE_DNS_IPSECKEY: "GNS_TYPE_DNS_IPSECKEY", - GNS_TYPE_DNS_IPSECKEY: "GNS_TYPE_DNS_IPSECKEY", - GNS_TYPE_DNS_RRSIG: "GNS_TYPE_DNS_RRSIG ", - GNS_TYPE_DNS_IPSECKEY: "GNS_TYPE_DNS_IPSECKEY", - GNS_TYPE_DNS_RRSIG: "GNS_TYPE_DNS_RRSIG", - GNS_TYPE_DNS_RRSIG: "GNS_TYPE_DNS_RRSIG", - GNS_TYPE_DNS_NSEC: "GNS_TYPE_DNS_NSEC ", - GNS_TYPE_DNS_RRSIG: "GNS_TYPE_DNS_RRSIG", - GNS_TYPE_DNS_NSEC: "GNS_TYPE_DNS_NSEC", - GNS_TYPE_DNS_NSEC: "GNS_TYPE_DNS_NSEC", - GNS_TYPE_DNS_DNSKEY: "GNS_TYPE_DNS_DNSKEY ", - GNS_TYPE_DNS_NSEC: "GNS_TYPE_DNS_NSEC", - GNS_TYPE_DNS_DNSKEY: "GNS_TYPE_DNS_DNSKEY", - GNS_TYPE_DNS_DNSKEY: "GNS_TYPE_DNS_DNSKEY", - GNS_TYPE_DNS_DHCID: "GNS_TYPE_DNS_DHCID ", - GNS_TYPE_DNS_DNSKEY: "GNS_TYPE_DNS_DNSKEY", - GNS_TYPE_DNS_DHCID: "GNS_TYPE_DNS_DHCID", - GNS_TYPE_DNS_DHCID: "GNS_TYPE_DNS_DHCID", - GNS_TYPE_DNS_NSEC3: "GNS_TYPE_DNS_NSEC3 ", - GNS_TYPE_DNS_DHCID: "GNS_TYPE_DNS_DHCID", - GNS_TYPE_DNS_NSEC3: "GNS_TYPE_DNS_NSEC3", - GNS_TYPE_DNS_NSEC3: "GNS_TYPE_DNS_NSEC3", - GNS_TYPE_DNS_NSEC3PARAM: "GNS_TYPE_DNS_NSEC3PARAM ", - GNS_TYPE_DNS_NSEC3: "GNS_TYPE_DNS_NSEC3", - GNS_TYPE_DNS_NSEC3PARAM: "GNS_TYPE_DNS_NSEC3PARAM", - GNS_TYPE_DNS_NSEC3PARAM: "GNS_TYPE_DNS_NSEC3PARAM", - GNS_TYPE_DNS_TLSA: "GNS_TYPE_DNS_TLSA ", - GNS_TYPE_DNS_NSEC3PARAM: "GNS_TYPE_DNS_NSEC3PARAM", - GNS_TYPE_DNS_TLSA: "GNS_TYPE_DNS_TLSA", - GNS_TYPE_DNS_TLSA: "GNS_TYPE_DNS_TLSA", - GNS_TYPE_DNS_HIP: "GNS_TYPE_DNS_HIP ", - GNS_TYPE_DNS_TLSA: "GNS_TYPE_DNS_TLSA", - GNS_TYPE_DNS_HIP: "GNS_TYPE_DNS_HIP", - GNS_TYPE_DNS_HIP: "GNS_TYPE_DNS_HIP", - GNS_TYPE_DNS_CDS: "GNS_TYPE_DNS_CDS ", - GNS_TYPE_DNS_HIP: "GNS_TYPE_DNS_HIP", - GNS_TYPE_DNS_CDS: "GNS_TYPE_DNS_CDS", - GNS_TYPE_DNS_CDS: "GNS_TYPE_DNS_CDS", - GNS_TYPE_DNS_CDNSKEY: "GNS_TYPE_DNS_CDNSKEY ", - GNS_TYPE_DNS_CDS: "GNS_TYPE_DNS_CDS", - GNS_TYPE_DNS_CDNSKEY: "GNS_TYPE_DNS_CDNSKEY", - GNS_TYPE_DNS_CDNSKEY: "GNS_TYPE_DNS_CDNSKEY", - GNS_TYPE_DNS_TKEY: "GNS_TYPE_DNS_TKEY ", - GNS_TYPE_DNS_CDNSKEY: "GNS_TYPE_DNS_CDNSKEY", - GNS_TYPE_DNS_TKEY: "GNS_TYPE_DNS_TKEY", - GNS_TYPE_DNS_TKEY: "GNS_TYPE_DNS_TKEY", - GNS_TYPE_DNS_TSIG: "GNS_TYPE_DNS_TSIG ", - GNS_TYPE_DNS_TKEY: "GNS_TYPE_DNS_TKEY", - GNS_TYPE_DNS_TSIG: "GNS_TYPE_DNS_TSIG", - GNS_TYPE_DNS_TSIG: "GNS_TYPE_DNS_TSIG", - GNS_TYPE_DNS_URI: "GNS_TYPE_DNS_URI ", - GNS_TYPE_DNS_TSIG: "GNS_TYPE_DNS_TSIG", - GNS_TYPE_DNS_URI: "GNS_TYPE_DNS_URI", - GNS_TYPE_DNS_URI: "GNS_TYPE_DNS_URI", - GNS_TYPE_DNS_CAA: "GNS_TYPE_DNS_CAA ", - GNS_TYPE_DNS_URI: "GNS_TYPE_DNS_URI", - GNS_TYPE_DNS_CAA: "GNS_TYPE_DNS_CAA", - GNS_TYPE_DNS_CAA: "GNS_TYPE_DNS_CAA", - GNS_TYPE_DNS_TA: "GNS_TYPE_DNS_TA ", - GNS_TYPE_DNS_CAA: "GNS_TYPE_DNS_CAA", - GNS_TYPE_DNS_TA: "GNS_TYPE_DNS_TA", - GNS_TYPE_DNS_TA: "GNS_TYPE_DNS_TA", - GNS_TYPE_DNS_DLV: "GNS_TYPE_DNS_DLV ", - GNS_TYPE_DNS_TA: "GNS_TYPE_DNS_TA", - GNS_TYPE_DNS_DLV: "GNS_TYPE_DNS_DLV", - GNS_TYPE_DNS_DLV: "GNS_TYPE_DNS_DLV", - GNS_TYPE_PKEY: "GNS_TYPE_PKEY ", - GNS_TYPE_DNS_DLV: "GNS_TYPE_DNS_DLV", - GNS_TYPE_PKEY: "GNS_TYPE_PKEY", - GNS_TYPE_PKEY: "GNS_TYPE_PKEY", - GNS_TYPE_NICK: "GNS_TYPE_NICK ", - GNS_TYPE_PKEY: "GNS_TYPE_PKEY", - GNS_TYPE_NICK: "GNS_TYPE_NICK", - GNS_TYPE_NICK: "GNS_TYPE_NICK", - GNS_TYPE_LEHO: "GNS_TYPE_LEHO ", - GNS_TYPE_NICK: "GNS_TYPE_NICK", - GNS_TYPE_LEHO: "GNS_TYPE_LEHO", - GNS_TYPE_LEHO: "GNS_TYPE_LEHO", - GNS_TYPE_VPN: "GNS_TYPE_VPN ", - GNS_TYPE_LEHO: "GNS_TYPE_LEHO", - GNS_TYPE_VPN: "GNS_TYPE_VPN", - GNS_TYPE_VPN: "GNS_TYPE_VPN", - GNS_TYPE_GNS2DNS: "GNS_TYPE_GNS2DNS ", - GNS_TYPE_VPN: "GNS_TYPE_VPN", - GNS_TYPE_GNS2DNS: "GNS_TYPE_GNS2DNS", - GNS_TYPE_GNS2DNS: "GNS_TYPE_GNS2DNS", - GNS_TYPE_BOX: "GNS_TYPE_BOX ", - GNS_TYPE_GNS2DNS: "GNS_TYPE_GNS2DNS", - GNS_TYPE_BOX: "GNS_TYPE_BOX", - GNS_TYPE_BOX: "GNS_TYPE_BOX", - GNS_TYPE_PLACE: "GNS_TYPE_PLACE ", - GNS_TYPE_BOX: "GNS_TYPE_BOX", - GNS_TYPE_PLACE: "GNS_TYPE_PLACE", - GNS_TYPE_PLACE: "GNS_TYPE_PLACE", - GNS_TYPE_PHONE: "GNS_TYPE_PHONE ", - GNS_TYPE_PLACE: "GNS_TYPE_PLACE", - GNS_TYPE_PHONE: "GNS_TYPE_PHONE", - GNS_TYPE_PHONE: "GNS_TYPE_PHONE", - GNS_TYPE_RECLAIM_ATTR: "GNS_TYPE_RECLAIM_ATTR ", - GNS_TYPE_PHONE: "GNS_TYPE_PHONE", - GNS_TYPE_RECLAIM_ATTR: "GNS_TYPE_RECLAIM_ATTR", - GNS_TYPE_RECLAIM_ATTR: "GNS_TYPE_RECLAIM_ATTR", - GNS_TYPE_RECLAIM_TICKET: "GNS_TYPE_RECLAIM_TICKET ", - GNS_TYPE_RECLAIM_ATTR: "GNS_TYPE_RECLAIM_ATTR", - GNS_TYPE_RECLAIM_TICKET: "GNS_TYPE_RECLAIM_TICKET", - GNS_TYPE_RECLAIM_TICKET: "GNS_TYPE_RECLAIM_TICKET", - GNS_TYPE_CREDENTIAL: "GNS_TYPE_CREDENTIAL ", - GNS_TYPE_RECLAIM_TICKET: "GNS_TYPE_RECLAIM_TICKET", - GNS_TYPE_CREDENTIAL: "GNS_TYPE_CREDENTIAL", - GNS_TYPE_CREDENTIAL: "GNS_TYPE_CREDENTIAL", - GNS_TYPE_POLICY: "GNS_TYPE_POLICY ", - GNS_TYPE_CREDENTIAL: "GNS_TYPE_CREDENTIAL", - GNS_TYPE_POLICY: "GNS_TYPE_POLICY", - GNS_TYPE_POLICY: "GNS_TYPE_POLICY", - GNS_TYPE_ATTRIBUTE: "GNS_TYPE_ATTRIBUTE ", - GNS_TYPE_POLICY: "GNS_TYPE_POLICY", - GNS_TYPE_ATTRIBUTE: "GNS_TYPE_ATTRIBUTE", - GNS_TYPE_ATTRIBUTE: "GNS_TYPE_ATTRIBUTE", - GNS_TYPE_RECLAIM_ATTR_REF: "GNS_TYPE_RECLAIM_ATTR_REF ", - GNS_TYPE_ATTRIBUTE: "GNS_TYPE_ATTRIBUTE", - GNS_TYPE_RECLAIM_ATTR_REF: "GNS_TYPE_RECLAIM_ATTR_REF", - GNS_TYPE_RECLAIM_ATTR_REF: "GNS_TYPE_RECLAIM_ATTR_REF", - GNS_TYPE_RECLAIM_MASTER: "GNS_TYPE_RECLAIM_MASTER ", - GNS_TYPE_RECLAIM_ATTR_REF: "GNS_TYPE_RECLAIM_ATTR_REF", - GNS_TYPE_RECLAIM_MASTER: "GNS_TYPE_RECLAIM_MASTER", - GNS_TYPE_RECLAIM_MASTER: "GNS_TYPE_RECLAIM_MASTER", - GNS_TYPE_RECLAIM_OIDC_CLIENT: "GNS_TYPE_RECLAIM_OIDC_CLIENT ", - GNS_TYPE_RECLAIM_MASTER: "GNS_TYPE_RECLAIM_MASTER", - GNS_TYPE_RECLAIM_OIDC_CLIENT: "GNS_TYPE_RECLAIM_OIDC_CLIENT", - GNS_TYPE_RECLAIM_OIDC_CLIENT: "GNS_TYPE_RECLAIM_OIDC_CLIENT", - GNS_TYPE_RECLAIM_OIDC_REDIRECT: "GNS_TYPE_RECLAIM_OIDC_REDIRECT ", - GNS_TYPE_RECLAIM_OIDC_CLIENT: "GNS_TYPE_RECLAIM_OIDC_CLIENT", - GNS_TYPE_RECLAIM_OIDC_REDIRECT: "GNS_TYPE_RECLAIM_OIDC_REDIRECT", - } - // GNS_LocalOptions GNS_LO_DEFAULT = 0 // Defaults, look in cache, then in DHT. GNS_LO_NO_DHT = 1 // Never look in the DHT, keep request to local cache. GNS_LO_LOCAL_MASTER = 2 // For the rightmost label, only look in the cache. + + GNS_MAX_BLOCK_SIZE = (63 * 1024) // Maximum size of a value that can be stored in a GNS block. ) + +//go:generate go run generate.go gnunet-gns.rec gnunet-gns.tpl gns_type.go + +//go:generate stringer -type=GNSType gns_type.go diff --git a/src/gnunet/enums/gns_type.go b/src/gnunet/enums/gns_type.go @@ -0,0 +1,72 @@ +// Code generated by enum generator; DO NOT EDIT. + +package enums + +type GNSType int + +// GNS constants +const ( + // GNS record types + GNS_TYPE_ANY GNSType = 0 // Record type indicating any record/'*' + GNS_TYPE_DNS_A GNSType = 1 // [RFC1035] IPv4 Address record + GNS_TYPE_DNS_NS GNSType = 2 // [RFC1035] Name Server record + GNS_TYPE_DNS_CNAME GNSType = 5 // [RFC1035] Canonical Name record + GNS_TYPE_DNS_SOA GNSType = 6 // [RFC2308] Start Of [a zone of] Authority + GNS_TYPE_DNS_PTR GNSType = 12 // [RFC1035] Pointer record + GNS_TYPE_DNS_MX GNSType = 15 // [RFC7505] Mail eXchange record + GNS_TYPE_DNS_TXT GNSType = 16 // [RFC1035] Text record + GNS_TYPE_DNS_RP GNSType = 17 // [RFC1183] Responsible Person + GNS_TYPE_DNS_AFSDB GNSType = 18 // [RFC1183] AFS Database Record + GNS_TYPE_DNS_SIG GNSType = 24 // [RFC2535] Signature + GNS_TYPE_DNS_KEY GNSType = 25 // [RFC2930] Key record + GNS_TYPE_DNS_AAAA GNSType = 28 // [RFC3596] IPv6 Address record + GNS_TYPE_DNS_LOC GNSType = 29 // [RFC1876] Location record + GNS_TYPE_DNS_SRV GNSType = 33 // [RFC2782] Service locator + GNS_TYPE_DNS_NAPTR GNSType = 35 // [RFC3403] Naming Authority Pointer + GNS_TYPE_DNS_KX GNSType = 36 // [RFC2230] Key eXchanger record + GNS_TYPE_DNS_CERT GNSType = 37 // [RFC4398] Certificate record + GNS_TYPE_DNS_DNAME GNSType = 39 // [RFC2672] Delegation Name + GNS_TYPE_DNS_APL GNSType = 42 // [RFC3123] Address Prefix List + GNS_TYPE_DNS_DS GNSType = 43 // [RFC4034] Delegation Signer + GNS_TYPE_DNS_SSHFP GNSType = 44 // [RFC4255] SSH public key Fingerprint + GNS_TYPE_DNS_IPSECKEY GNSType = 45 // [RFC4025] IPsec Key + GNS_TYPE_DNS_RRSIG GNSType = 46 // [RFC4034] DNSSEC Signature + GNS_TYPE_DNS_NSEC GNSType = 47 // [RFC4034] Next-Secure record + GNS_TYPE_DNS_DNSKEY GNSType = 48 // [RFC4034] DNS Key record + GNS_TYPE_DNS_DHCID GNSType = 49 // [RFC4701] DHCP Identifier + GNS_TYPE_DNS_NSEC3 GNSType = 50 // [RFC5155] NSEC record version 3 or NSEC hashed + GNS_TYPE_DNS_NSEC3PARAM GNSType = 51 // [RFC5155] NSEC3 Parameters + GNS_TYPE_DNS_TLSA GNSType = 52 // [RFC6698] TLSA certificate association + GNS_TYPE_DNS_HIP GNSType = 55 // [RFC5205] Host Identity Protocol + GNS_TYPE_DNS_CDS GNSType = 59 // [RFC7344] Child DS + GNS_TYPE_DNS_CDNSKEY GNSType = 60 // [RFC7344] Child DNSKEY + GNS_TYPE_DNS_TKEY GNSType = 249 // [RFC2930] Secret Key + GNS_TYPE_DNS_TSIG GNSType = 250 // [RFC2845] Transaction Signature + GNS_TYPE_DNS_URI GNSType = 256 // [RFC7553] Uniform Resource Identifier + GNS_TYPE_DNS_CAA GNSType = 257 // [RFC6844] Certification Authority Authorization + GNS_TYPE_DNS_TA GNSType = 32768 // [–] DNSSEC Trust Authorities + GNS_TYPE_DNS_DLV GNSType = 32769 // [RFC4431] DNSSEC Lookaside Validation record +GNS_TYPE_PKEY GNSType = 65536 // GNS zone transfer +GNS_TYPE_NICK GNSType = 65537 // GNS nick names +GNS_TYPE_LEHO GNSType = 65538 // legacy hostnames +GNS_TYPE_VPN GNSType = 65539 // VPN resolution +GNS_TYPE_GNS2DNS GNSType = 65540 // Delegation to DNS +GNS_TYPE_BOX GNSType = 65541 // Boxed records (see TLSA/SRV handling in GNS) +GNS_TYPE_PLACE GNSType = 65542 // social place for SecuShare +GNS_TYPE_PHONE GNSType = 65543 // Endpoint for conversation +GNS_TYPE_RECLAIM_ATTRIBUTE GNSType = 65544 // identity attribute +GNS_TYPE_RECLAIM_TICKET GNSType = 65545 // local ticket reference +GNS_TYPE_DELEGATE GNSType = 65548 // For ABD policies +GNS_TYPE_ATTRIBUTE GNSType = 65549 // For ABD reverse lookups +GNS_TYPE_RECLAIM_ATTRIBUTE_REF GNSType = 65550 // for reclaim records +GNS_TYPE_REDIRECT GNSType = 65551 // Resolver redirects +GNS_TYPE_RECLAIM_OIDC_CLIENT GNSType = 65552 // For reclaim OIDC client names. +GNS_TYPE_RECLAIM_OIDC_REDIRECT GNSType = 65553 // Used reclaimID OIDC client redirect URIs. +GNS_TYPE_RECLAIM_CREDENTIAL GNSType = 65554 // Record type for an attribute attestation (e.g. JWT). +GNS_TYPE_RECLAIM_PRESENTATION GNSType = 65555 // Record type for a presentation of a credential. +GNS_TYPE_EDKEY GNSType = 65556 // Record type for EDKEY zone delegations. +GNS_TYPE_ERIS_READ_CAPABILITY GNSType = 65557 // Encoding for Robust Immutable Storage (ERIS) binary read capability +GNS_TYPE_MESSENGER_ROOM_ENTRY GNSType = 65558 // Record type to share an entry of a messenger room +GNS_TYPE_TOMBSTONE GNSType = 65559 // Record type to indicate a previously delete record (PRIVATE only) + +) diff --git a/src/gnunet/enums/gnstype_string.go b/src/gnunet/enums/gnstype_string.go @@ -0,0 +1,145 @@ +// Code generated by "stringer -type=GNSType gns_type.go"; DO NOT EDIT. + +package enums + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[GNS_TYPE_ANY-0] + _ = x[GNS_TYPE_DNS_A-1] + _ = x[GNS_TYPE_DNS_NS-2] + _ = x[GNS_TYPE_DNS_CNAME-5] + _ = x[GNS_TYPE_DNS_SOA-6] + _ = x[GNS_TYPE_DNS_PTR-12] + _ = x[GNS_TYPE_DNS_MX-15] + _ = x[GNS_TYPE_DNS_TXT-16] + _ = x[GNS_TYPE_DNS_RP-17] + _ = x[GNS_TYPE_DNS_AFSDB-18] + _ = x[GNS_TYPE_DNS_SIG-24] + _ = x[GNS_TYPE_DNS_KEY-25] + _ = x[GNS_TYPE_DNS_AAAA-28] + _ = x[GNS_TYPE_DNS_LOC-29] + _ = x[GNS_TYPE_DNS_SRV-33] + _ = x[GNS_TYPE_DNS_NAPTR-35] + _ = x[GNS_TYPE_DNS_KX-36] + _ = x[GNS_TYPE_DNS_CERT-37] + _ = x[GNS_TYPE_DNS_DNAME-39] + _ = x[GNS_TYPE_DNS_APL-42] + _ = x[GNS_TYPE_DNS_DS-43] + _ = x[GNS_TYPE_DNS_SSHFP-44] + _ = x[GNS_TYPE_DNS_IPSECKEY-45] + _ = x[GNS_TYPE_DNS_RRSIG-46] + _ = x[GNS_TYPE_DNS_NSEC-47] + _ = x[GNS_TYPE_DNS_DNSKEY-48] + _ = x[GNS_TYPE_DNS_DHCID-49] + _ = x[GNS_TYPE_DNS_NSEC3-50] + _ = x[GNS_TYPE_DNS_NSEC3PARAM-51] + _ = x[GNS_TYPE_DNS_TLSA-52] + _ = x[GNS_TYPE_DNS_HIP-55] + _ = x[GNS_TYPE_DNS_CDS-59] + _ = x[GNS_TYPE_DNS_CDNSKEY-60] + _ = x[GNS_TYPE_DNS_TKEY-249] + _ = x[GNS_TYPE_DNS_TSIG-250] + _ = x[GNS_TYPE_DNS_URI-256] + _ = x[GNS_TYPE_DNS_CAA-257] + _ = x[GNS_TYPE_DNS_TA-32768] + _ = x[GNS_TYPE_DNS_DLV-32769] + _ = x[GNS_TYPE_PKEY-65536] + _ = x[GNS_TYPE_NICK-65537] + _ = x[GNS_TYPE_LEHO-65538] + _ = x[GNS_TYPE_VPN-65539] + _ = x[GNS_TYPE_GNS2DNS-65540] + _ = x[GNS_TYPE_BOX-65541] + _ = x[GNS_TYPE_PLACE-65542] + _ = x[GNS_TYPE_PHONE-65543] + _ = x[GNS_TYPE_RECLAIM_ATTRIBUTE-65544] + _ = x[GNS_TYPE_RECLAIM_TICKET-65545] + _ = x[GNS_TYPE_DELEGATE-65548] + _ = x[GNS_TYPE_ATTRIBUTE-65549] + _ = x[GNS_TYPE_RECLAIM_ATTRIBUTE_REF-65550] + _ = x[GNS_TYPE_REDIRECT-65551] + _ = x[GNS_TYPE_RECLAIM_OIDC_CLIENT-65552] + _ = x[GNS_TYPE_RECLAIM_OIDC_REDIRECT-65553] + _ = x[GNS_TYPE_RECLAIM_CREDENTIAL-65554] + _ = x[GNS_TYPE_RECLAIM_PRESENTATION-65555] + _ = x[GNS_TYPE_EDKEY-65556] + _ = x[GNS_TYPE_ERIS_READ_CAPABILITY-65557] + _ = x[GNS_TYPE_MESSENGER_ROOM_ENTRY-65558] + _ = x[GNS_TYPE_TOMBSTONE-65559] +} + +const _GNSType_name = "GNS_TYPE_ANYGNS_TYPE_DNS_AGNS_TYPE_DNS_NSGNS_TYPE_DNS_CNAMEGNS_TYPE_DNS_SOAGNS_TYPE_DNS_PTRGNS_TYPE_DNS_MXGNS_TYPE_DNS_TXTGNS_TYPE_DNS_RPGNS_TYPE_DNS_AFSDBGNS_TYPE_DNS_SIGGNS_TYPE_DNS_KEYGNS_TYPE_DNS_AAAAGNS_TYPE_DNS_LOCGNS_TYPE_DNS_SRVGNS_TYPE_DNS_NAPTRGNS_TYPE_DNS_KXGNS_TYPE_DNS_CERTGNS_TYPE_DNS_DNAMEGNS_TYPE_DNS_APLGNS_TYPE_DNS_DSGNS_TYPE_DNS_SSHFPGNS_TYPE_DNS_IPSECKEYGNS_TYPE_DNS_RRSIGGNS_TYPE_DNS_NSECGNS_TYPE_DNS_DNSKEYGNS_TYPE_DNS_DHCIDGNS_TYPE_DNS_NSEC3GNS_TYPE_DNS_NSEC3PARAMGNS_TYPE_DNS_TLSAGNS_TYPE_DNS_HIPGNS_TYPE_DNS_CDSGNS_TYPE_DNS_CDNSKEYGNS_TYPE_DNS_TKEYGNS_TYPE_DNS_TSIGGNS_TYPE_DNS_URIGNS_TYPE_DNS_CAAGNS_TYPE_DNS_TAGNS_TYPE_DNS_DLVGNS_TYPE_PKEYGNS_TYPE_NICKGNS_TYPE_LEHOGNS_TYPE_VPNGNS_TYPE_GNS2DNSGNS_TYPE_BOXGNS_TYPE_PLACEGNS_TYPE_PHONEGNS_TYPE_RECLAIM_ATTRIBUTEGNS_TYPE_RECLAIM_TICKETGNS_TYPE_DELEGATEGNS_TYPE_ATTRIBUTEGNS_TYPE_RECLAIM_ATTRIBUTE_REFGNS_TYPE_REDIRECTGNS_TYPE_RECLAIM_OIDC_CLIENTGNS_TYPE_RECLAIM_OIDC_REDIRECTGNS_TYPE_RECLAIM_CREDENTIALGNS_TYPE_RECLAIM_PRESENTATIONGNS_TYPE_EDKEYGNS_TYPE_ERIS_READ_CAPABILITYGNS_TYPE_MESSENGER_ROOM_ENTRYGNS_TYPE_TOMBSTONE" + +var _GNSType_map = map[GNSType]string{ + 0: _GNSType_name[0:12], + 1: _GNSType_name[12:26], + 2: _GNSType_name[26:41], + 5: _GNSType_name[41:59], + 6: _GNSType_name[59:75], + 12: _GNSType_name[75:91], + 15: _GNSType_name[91:106], + 16: _GNSType_name[106:122], + 17: _GNSType_name[122:137], + 18: _GNSType_name[137:155], + 24: _GNSType_name[155:171], + 25: _GNSType_name[171:187], + 28: _GNSType_name[187:204], + 29: _GNSType_name[204:220], + 33: _GNSType_name[220:236], + 35: _GNSType_name[236:254], + 36: _GNSType_name[254:269], + 37: _GNSType_name[269:286], + 39: _GNSType_name[286:304], + 42: _GNSType_name[304:320], + 43: _GNSType_name[320:335], + 44: _GNSType_name[335:353], + 45: _GNSType_name[353:374], + 46: _GNSType_name[374:392], + 47: _GNSType_name[392:409], + 48: _GNSType_name[409:428], + 49: _GNSType_name[428:446], + 50: _GNSType_name[446:464], + 51: _GNSType_name[464:487], + 52: _GNSType_name[487:504], + 55: _GNSType_name[504:520], + 59: _GNSType_name[520:536], + 60: _GNSType_name[536:556], + 249: _GNSType_name[556:573], + 250: _GNSType_name[573:590], + 256: _GNSType_name[590:606], + 257: _GNSType_name[606:622], + 32768: _GNSType_name[622:637], + 32769: _GNSType_name[637:653], + 65536: _GNSType_name[653:666], + 65537: _GNSType_name[666:679], + 65538: _GNSType_name[679:692], + 65539: _GNSType_name[692:704], + 65540: _GNSType_name[704:720], + 65541: _GNSType_name[720:732], + 65542: _GNSType_name[732:746], + 65543: _GNSType_name[746:760], + 65544: _GNSType_name[760:786], + 65545: _GNSType_name[786:809], + 65548: _GNSType_name[809:826], + 65549: _GNSType_name[826:844], + 65550: _GNSType_name[844:874], + 65551: _GNSType_name[874:891], + 65552: _GNSType_name[891:919], + 65553: _GNSType_name[919:949], + 65554: _GNSType_name[949:976], + 65555: _GNSType_name[976:1005], + 65556: _GNSType_name[1005:1019], + 65557: _GNSType_name[1019:1048], + 65558: _GNSType_name[1048:1077], + 65559: _GNSType_name[1077:1095], +} + +func (i GNSType) String() string { + if str, ok := _GNSType_map[i]; ok { + return str + } + return "GNSType(" + strconv.FormatInt(int64(i), 10) + ")" +} diff --git a/src/gnunet/enums/gnunet-dht.rec b/src/gnunet/enums/gnunet-dht.rec @@ -0,0 +1,102 @@ +# -*- mode: rec -*- +# +# Registry for GNU Name System record types +# + +%rec: BlockType +%key: Number +%type: Number int +%mandatory: Number +%typedef: Name_t regexp /^[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-]*$/ +%type: Name Name_t +%unique: Name +%mandatory: Name +%mandatory: Comment +%allowed: Contact +%allowed: References +%sort: Number Name Contact References + +Number: 0 +Name: ANY +Comment: Identifier for any block. +References: None + +Number: 1 +Name: FS_DBLOCK +Comment: Data block (leaf) in the CHK tree. +References: None + +Number: 2 +Name: FS_IBLOCK +Comment: Inner block in the CHK tree. +References: None + +Number: 6 +Name: FS_ONDEMAND +Comment: Type of a block representing a block to be encoded on demand from disk. Should never appear on the network directly. +References: None + +Number: 7 +Name: DHT_HELLO +Comment: Type of a block that contains a HELLO for a peer. +References: None + +Number: 8 +Name: TEST +Comment: Block for testing. +References: None + +Number: 9 +Name: FS_UBLOCK +Comment: Type of a block representing any type of search result (universal). +References: None + +Number: 10 +Name: DNS +Comment: Block for storing DNS exit service advertisements. +References: None + +Number: 11 +Name: GNS_NAMERECORD +Comment: Block for storing GNS record data. +References: None + +Number: 12 +Name: REVOCATION +Comment: Block type for a revocation message by which a key is revoked. +References: None + +Number: 13 +Name: DHT_URL_HELLO +Comment: Type of a block that contains a DHT-NG HELLO for a peer. +References: None + +Number: 22 +Name: REGEX +Comment: Block to store a cadet regex state +References: None + +Number: 23 +Name: REGEX_ACCEPT +Comment: Block to store a cadet regex accepting state +References: None + +Number: 24 +Name: SET_TEST +Comment: Block for testing set/consensus. If first byte of the block is non-zero, the block is considered invalid. +References: None + +Number: 25 +Name: CONSENSUS_ELEMENT +Comment: Block type for consensus elements. Contains either special marker elements or a nested block. +References: None + +Number: 26 +Name: SETI_TEST +Comment: Block for testing set intersection. If first byte of the block is non-zero, the block is considered invalid. +References: None + +Number: 27 +Name: SETU_TEST +Comment: Block for testing set union. If first byte of the block is non-zero, the block is considered invalid. +References: None diff --git a/src/gnunet/enums/gnunet-dht.tpl b/src/gnunet/enums/gnunet-dht.tpl @@ -0,0 +1,12 @@ +// Code generated by enum generator; DO NOT EDIT. + +package enums + +type BlockType int + +// DHT block types +const ( +{{ range $i, $kv := . }}BLOCK_TYPE_{{.Name}} BlockType = {{.Number}} // {{.Comment}} +{{ end }} +) + diff --git a/src/gnunet/enums/gnunet-gns.rec b/src/gnunet/enums/gnunet-gns.rec @@ -0,0 +1,132 @@ +# -*- mode: rec -*- +# +# Registry for GNU Name System record types +# + +%rec: RecordType +%key: Number +%type: Number int +%mandatory: Number +%typedef: Name_t regexp /^[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-]*$/ +%type: Name Name_t +%unique: Name +%mandatory: Name +%mandatory: Comment +%allowed: Contact +%allowed: References +%sort: Number Name Contact References + +Number: 65536 +Name: PKEY +Comment: GNS zone transfer +References: LSD0001 + +Number: 65537 +Name: NICK +Comment: GNS nick names +References: LSD0001 + +Number: 65538 +Name: LEHO +Comment: legacy hostnames +References: LSD0001 + +Number: 65539 +Name: VPN +Comment: VPN resolution +References: LSD0001 + +Number: 65540 +Name: GNS2DNS +Comment: Delegation to DNS +References: LSD0001 + +Number: 65541 +Name: BOX +Comment: Boxed records (see TLSA/SRV handling in GNS) +References: LSD0001 + +Number: 65542 +Name: PLACE +Comment: social place for SecuShare +Contact: lynx@gnunet.org + +Number: 65543 +Name: PHONE +Comment: Endpoint for conversation +Contact: grothoff@gnunet.org + +Number: 65544 +Name: RECLAIM_ATTRIBUTE +Comment: identity attribute +Contact: schanzen@gnunet.org + +Number: 65545 +Name: RECLAIM_TICKET +Comment: local ticket reference +Contact: schanzen@gnunet.org + +Number: 65548 +Name: DELEGATE +Comment: For ABD policies +Contact: schanzen@gnunet.org + +Number: 65549 +Name: ATTRIBUTE +Comment: For ABD reverse lookups +Contact: schanzen@gnunet.org + +Number: 65550 +Name: RECLAIM_ATTRIBUTE_REF +Comment: for reclaim records +Contact: schanzen@gnunet.org + +Number: 65551 +Name: REDIRECT +Comment: Resolver redirects +Contact: LSD0001 + +Number: 65552 +Name: RECLAIM_OIDC_CLIENT +Comment: For reclaim OIDC client names. +Contact: schanzen@gnunet.org + +Number: 65553 +Name: RECLAIM_OIDC_REDIRECT +Comment: Used reclaimID OIDC client redirect URIs. +Contact: schanzen@gnunet.org + + +Number: 65554 +Name: RECLAIM_CREDENTIAL +Comment: Record type for an attribute attestation (e.g. JWT). +Contact: schanzen@gnunet.org + +Number: 65555 +Name: RECLAIM_PRESENTATION +Comment: Record type for a presentation of a credential. +Contact: schanzen@gnunet.org + +Number: 65556 +Name: EDKEY +Comment: Record type for EDKEY zone delegations. + +Number: 65557 +Name: ERIS_READ_CAPABILITY +Comment: Encoding for Robust Immutable Storage (ERIS) binary read capability +References: http://purl.org/eris + +Number: 65558 +Name: MESSENGER_ROOM_ENTRY +Comment: Record type to share an entry of a messenger room +Contact: thejackimonster@gmail.com + +Number: 65559 +Name: TOMBSTONE +Comment: Record type to indicate a previously delete record (PRIVATE only) +Contact: gnunet-developers@gnunet.org + +Number: 65560 +Name: MESSENGER_ROOM_DETAILS +Comment: Record type to store details about a messenger room +Contact: thejackimonster@gmail.com diff --git a/src/gnunet/enums/gnunet-gns.tpl b/src/gnunet/enums/gnunet-gns.tpl @@ -0,0 +1,51 @@ +// Code generated by enum generator; DO NOT EDIT. + +package enums + +type GNSType int + +// GNS constants +const ( + // GNS record types + GNS_TYPE_ANY GNSType = 0 // Record type indicating any record/'*' + GNS_TYPE_DNS_A GNSType = 1 // [RFC1035] IPv4 Address record + GNS_TYPE_DNS_NS GNSType = 2 // [RFC1035] Name Server record + GNS_TYPE_DNS_CNAME GNSType = 5 // [RFC1035] Canonical Name record + GNS_TYPE_DNS_SOA GNSType = 6 // [RFC2308] Start Of [a zone of] Authority + GNS_TYPE_DNS_PTR GNSType = 12 // [RFC1035] Pointer record + GNS_TYPE_DNS_MX GNSType = 15 // [RFC7505] Mail eXchange record + GNS_TYPE_DNS_TXT GNSType = 16 // [RFC1035] Text record + GNS_TYPE_DNS_RP GNSType = 17 // [RFC1183] Responsible Person + GNS_TYPE_DNS_AFSDB GNSType = 18 // [RFC1183] AFS Database Record + GNS_TYPE_DNS_SIG GNSType = 24 // [RFC2535] Signature + GNS_TYPE_DNS_KEY GNSType = 25 // [RFC2930] Key record + GNS_TYPE_DNS_AAAA GNSType = 28 // [RFC3596] IPv6 Address record + GNS_TYPE_DNS_LOC GNSType = 29 // [RFC1876] Location record + GNS_TYPE_DNS_SRV GNSType = 33 // [RFC2782] Service locator + GNS_TYPE_DNS_NAPTR GNSType = 35 // [RFC3403] Naming Authority Pointer + GNS_TYPE_DNS_KX GNSType = 36 // [RFC2230] Key eXchanger record + GNS_TYPE_DNS_CERT GNSType = 37 // [RFC4398] Certificate record + GNS_TYPE_DNS_DNAME GNSType = 39 // [RFC2672] Delegation Name + GNS_TYPE_DNS_APL GNSType = 42 // [RFC3123] Address Prefix List + GNS_TYPE_DNS_DS GNSType = 43 // [RFC4034] Delegation Signer + GNS_TYPE_DNS_SSHFP GNSType = 44 // [RFC4255] SSH public key Fingerprint + GNS_TYPE_DNS_IPSECKEY GNSType = 45 // [RFC4025] IPsec Key + GNS_TYPE_DNS_RRSIG GNSType = 46 // [RFC4034] DNSSEC Signature + GNS_TYPE_DNS_NSEC GNSType = 47 // [RFC4034] Next-Secure record + GNS_TYPE_DNS_DNSKEY GNSType = 48 // [RFC4034] DNS Key record + GNS_TYPE_DNS_DHCID GNSType = 49 // [RFC4701] DHCP Identifier + GNS_TYPE_DNS_NSEC3 GNSType = 50 // [RFC5155] NSEC record version 3 or NSEC hashed + GNS_TYPE_DNS_NSEC3PARAM GNSType = 51 // [RFC5155] NSEC3 Parameters + GNS_TYPE_DNS_TLSA GNSType = 52 // [RFC6698] TLSA certificate association + GNS_TYPE_DNS_HIP GNSType = 55 // [RFC5205] Host Identity Protocol + GNS_TYPE_DNS_CDS GNSType = 59 // [RFC7344] Child DS + GNS_TYPE_DNS_CDNSKEY GNSType = 60 // [RFC7344] Child DNSKEY + GNS_TYPE_DNS_TKEY GNSType = 249 // [RFC2930] Secret Key + GNS_TYPE_DNS_TSIG GNSType = 250 // [RFC2845] Transaction Signature + GNS_TYPE_DNS_URI GNSType = 256 // [RFC7553] Uniform Resource Identifier + GNS_TYPE_DNS_CAA GNSType = 257 // [RFC6844] Certification Authority Authorization + GNS_TYPE_DNS_TA GNSType = 32768 // [–] DNSSEC Trust Authorities + GNS_TYPE_DNS_DLV GNSType = 32769 // [RFC4431] DNSSEC Lookaside Validation record +{{ range $i, $kv := . }}GNS_TYPE_{{.Name}} GNSType = {{.Number}} // {{.Comment}} +{{ end }} +) diff --git a/src/gnunet/enums/gnunet-signature.rec b/src/gnunet/enums/gnunet-signature.rec @@ -0,0 +1,183 @@ +# -*- mode: rec -*- +# +# Registry for GNUnet Signature purposes +# + +%rec: SignaturePurpose +%key: Number +%type: Number int +%mandatory: Number +%typedef: Name_t regexp /^[ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_][ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*$/ +%type: Name Name_t +%unique: Name +%mandatory: Name +%mandatory: Comment +%allowed: Subsystem +%sort: Number Name + + +Number: 0 +Name: TEST +Comment: Test signature, not valid for anything other than writing a test. (Note that the signature verification code will accept this value). +Subsystem: GNUnet + +Number: 1 +Name: TRANSPORT_PONG_OWN +Comment: Signature for confirming that this peer uses a particular address. +Subsystem: GNUnet-TRANSPORT + +Number: 2 +Name: TRANSPORT_DISCONNECT +Comment: Signature for confirming that this peer intends to disconnect. +Subsystem: GNUnet-TRANSPORT + +Number: 3 +Name: REVOCATION +Comment: Signature for confirming a key revocation. +Subsystem: GNUnet-Revocation + +Number: 4 +Name: NAMESPACE_ADVERTISEMENT +Comment: Signature for a namespace/pseudonym advertisement (by the namespace owner). +Subsystem: GNUnet-FS + +Number: 5 +Name: PEER_PLACEMENT +Comment: Signature by which a peer affirms that it is providing a certain bit of content for use in LOCation URIs. +Subsystem: GNUnet-FS + +Number: 6 +Name: DHT_HOP +Comment: Signature by which a peer affirms that it forwarded a message in the DHT. +Subsystem: GNUnet-DHT + +Number: 7 +Name: HELLO +Comment: Signature by which a peer affirms its address. +Subsystem: GNUnet-HELLO + + +Number: 11 +Name: DNS_RECORD +Comment: Signature on a GNUNET_DNS_Advertisement. +Subsystem: GNUnet-DNS+Exit + +Number: 12 +Name: CHAT_MESSAGE +Comment: Signature of a chat message. +Subsystem: GNUnet-MESSENGER + +Number: 13 +Name: CHAT_RECEIPT +Comment: Signature of confirmation receipt for a chat message. +Subsystem: GNUnet-MESSENGER + +Number: 14 +Name: NSE_SEND +Comment: Signature of a network size estimate message. +Subsystem: GNUnet-NSE + +Number: 15 +Name: GNS_RECORD_SIGN +Comment: Signature of a gnunet naming system record block +Subsystem: GNUnet-GNSRECORD + +Number: 16 +Name: SET_ECC_KEY +Comment: Purpose is to set a session key. +Subsystem: GNUnet-CORE + +Number: 17 +Name: FS_UBLOCK +Comment: UBlock Signature, done using DSS, not ECC +Subsystem: GNUnet-FS + +Number: 18 +Name: REGEX_ACCEPT +Comment: Accept state in regex DFA. Peer affirms that it offers the matching service. +Subsystem: GNUnet-REGEX + +Number: 20 +Name: CONVERSATION_RING +Comment: Signature of a conversation ring. +Subsystem: GNUnet-CONVERSATION + +Number: 21 +Name: SECRETSHARING_DKG1 +Comment: Signature for the first round of distributed key generation. +Subsystem: GNUnet-SECRETSHARING + +Number: 22 +Name: SECRETSHARING_DKG2 +Comment: Signature for the second round of distributed key generation. +Subsystem: GNUnet-SECRETSHARING + +Number: 23 +Name: SECRETSHARING_DECRYPTION +Comment: Signature for the cooperative decryption. +Subsystem: GNUnet-SECRETSHARING + +Number: 27 +Name: RECLAIM_CODE_SIGN +Comment: Signature for a GNUid Ticket +Subsystem: Reclaim + +Number: 28 +Name: DELEGATE +Comment: Signature for a GNUnet credential +Subsystem: Reclaim + +Number: 29 +Name: TRANSPORT_ADDRESS +Comment: Signature by a peer affirming that this is one of its addresses for the given time period. +Subsystem: GNUnet-TRANSPORT + +Number: 30 +Name: TRANSPORT_EPHEMERAL +Comment: Signature by a peer affirming that the given ephemeral key is currently in use by that peer's transport service. +Subsystem: GNUnet-TRANSPORT + +Number: 31 +Name: COMMUNICATOR_TCP_HANDSHAKE +Comment: Signature used by TCP communicator handshake. +Subsystem: GNUnet-TRANSPORT-TCP + +Number: 32 +Name: COMMUNICATOR_TCP_REKEY +Comment: Signature used by TCP communicator rekey. +Subsystem: GNUnet-TRANSPORT-TCP + +Number: 33 +Name: COMMUNICATOR_UDP_HANDSHAKE +Comment: Signature used by UDP communicator handshake. +Subsystem: GNUnet-TRANSPORT-UDP + +Number: 34 +Name: COMMUNICATOR_UDP_BROADCAST +Comment: Signature used by UDP broadcasts. +Subsystem: GNUnet-TRANSPORT-UDP + +Number: 35 +Name: TRANSPORT_CHALLENGE +Comment: Signature by a peer affirming that it received a challenge (and stating how long it expects the address on which the challenge was received to remain valid). +Subsystem: GNUnet-TRANSPORT + +Number: 36 +Name: TRANSPORT_DV_HOP +Comment: Signature by a peer affirming that it is on a DV path. +Subsystem: GNUnet-TRANSPORT + +Number: 37 +Name: TRANSPORT_DV_INITIATOR +Comment: Signature by a peer affirming that it originated the DV path. +Subsystem: GNUnet-TRANSPORT + +Number: 38 +Name: CADET_CONNECTION_INITIATOR +Comment: Signature by a peer that like to create a connection. +Subsystem: GNUnet-CADET + +Number: 39 +Name: COMMUNICATOR_TCP_HANDSHAKE_ACK +Comment: Signature by a peer sending back the nonce received at initial handshake. +Subsystem: GNUnet-TRANSPORT-TCP diff --git a/src/gnunet/enums/gnunet-signature.tpl b/src/gnunet/enums/gnunet-signature.tpl @@ -0,0 +1,11 @@ +// Code generated by enum generator; DO NOT EDIT. + +package enums + +type SigPurpose int + +// Signature purpose values +const ( +{{ range $i, $kv := . }}SIG_{{.Name}} SigPurpose = {{.Number}} // {{.Comment}} +{{ end }} +) diff --git a/src/gnunet/enums/signature.go b/src/gnunet/enums/signature.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -18,35 +18,6 @@ package enums -// Signature purpose constants -const ( - SIG_TEST = iota // Only used in test cases! - SIG_TRANSPORT_PONG_OWN // Confirming a particular address. - SIG_TRANSPORT_DISCONNECT // Confirming intent to disconnect. - SIG_REVOCATION // Confirming a key revocation. - SIG_NAMESPACE_ADVERTISEMENT // Namespace/pseudonym advertisement. - SIG_PEER_PLACEMENT // Affirm certain content (LOCation URIs). - SIG_FS_KBLOCK // Obsolete, legacy value. - SIG_FS_SBLOCK // Obsolete, legacy value. - SIG_FS_NBLOCK // Obsolete, legacy value. - SIG_FS_NBLOCK_KSIG // Obsolete, legacy value. - SIG_RESOLVER_RESPONSE // DNS_Advertisement - SIG_DNS_RECORD // - SIG_CHAT_MESSAGE // Chat message. - SIG_CHAT_RECEIPT // Confirmation receipt for chat message. - SIG_NSE_SEND // Network size estimate message. - SIG_GNS_RECORD_SIGN // GNS record block. - SIG_ECC_KEY // Set a session key. - SIG_FS_UBLOCK // UBlock Signature, done using DSS, not ECC. - SIG_REGEX_ACCEPT // Accept state (affirm matching service). - SIG_MULTICAST_MESSAGE // Multicast message sent by origin. - SIG_CONVERSATION_RING // Conversation ring. - SIG_SECRETSHARING_DKG1 // First round of distributed key generation. - SIG_SECRETSHARING_DKG2 // Second round of distributed key generation. - SIG_SECRETSHARING_DECRYPTION // Cooperative decryption. - SIG_MULTICAST_REQUEST // Multicast request sent by member. - SIG_SENSOR_ANOMALY_REPORT // Sensor anomaly report message. - SIG_GNUID_TOKEN // GNUid Token. - SIG_GNUID_TICKET // GNUid Ticket. - SIG_CREDENTIAL // GNUnet credential. -) +//go:generate go run generate.go gnunet-signature.rec gnunet-signature.tpl signature_purpose.go + +//go:generate stringer -type=SigPurpose signature_purpose.go diff --git a/src/gnunet/enums/signature_purpose.go b/src/gnunet/enums/signature_purpose.go @@ -0,0 +1,42 @@ +// Code generated by enum generator; DO NOT EDIT. + +package enums + +type SigPurpose int + +// Signature purpose values +const ( +SIG_TEST SigPurpose = 0 // Test signature, not valid for anything other than writing a test. (Note that the signature verification code will accept this value). +SIG_TRANSPORT_PONG_OWN SigPurpose = 1 // Signature for confirming that this peer uses a particular address. +SIG_TRANSPORT_DISCONNECT SigPurpose = 2 // Signature for confirming that this peer intends to disconnect. +SIG_REVOCATION SigPurpose = 3 // Signature for confirming a key revocation. +SIG_NAMESPACE_ADVERTISEMENT SigPurpose = 4 // Signature for a namespace/pseudonym advertisement (by the namespace owner). +SIG_PEER_PLACEMENT SigPurpose = 5 // Signature by which a peer affirms that it is providing a certain bit of content for use in LOCation URIs. +SIG_DHT_HOP SigPurpose = 6 // Signature by which a peer affirms that it forwarded a message in the DHT. +SIG_HELLO SigPurpose = 7 // Signature by which a peer affirms its address. +SIG_DNS_RECORD SigPurpose = 11 // Signature on a GNUNET_DNS_Advertisement. +SIG_CHAT_MESSAGE SigPurpose = 12 // Signature of a chat message. +SIG_CHAT_RECEIPT SigPurpose = 13 // Signature of confirmation receipt for a chat message. +SIG_NSE_SEND SigPurpose = 14 // Signature of a network size estimate message. +SIG_GNS_RECORD_SIGN SigPurpose = 15 // Signature of a gnunet naming system record block +SIG_SET_ECC_KEY SigPurpose = 16 // Purpose is to set a session key. +SIG_FS_UBLOCK SigPurpose = 17 // UBlock Signature, done using DSS, not ECC +SIG_REGEX_ACCEPT SigPurpose = 18 // Accept state in regex DFA. Peer affirms that it offers the matching service. +SIG_CONVERSATION_RING SigPurpose = 20 // Signature of a conversation ring. +SIG_SECRETSHARING_DKG1 SigPurpose = 21 // Signature for the first round of distributed key generation. +SIG_SECRETSHARING_DKG2 SigPurpose = 22 // Signature for the second round of distributed key generation. +SIG_SECRETSHARING_DECRYPTION SigPurpose = 23 // Signature for the cooperative decryption. +SIG_RECLAIM_CODE_SIGN SigPurpose = 27 // Signature for a GNUid Ticket +SIG_DELEGATE SigPurpose = 28 // Signature for a GNUnet credential +SIG_TRANSPORT_ADDRESS SigPurpose = 29 // Signature by a peer affirming that this is one of its addresses for the given time period. +SIG_TRANSPORT_EPHEMERAL SigPurpose = 30 // Signature by a peer affirming that the given ephemeral key is currently in use by that peer's transport service. +SIG_COMMUNICATOR_TCP_HANDSHAKE SigPurpose = 31 // Signature used by TCP communicator handshake. +SIG_COMMUNICATOR_TCP_REKEY SigPurpose = 32 // Signature used by TCP communicator rekey. +SIG_COMMUNICATOR_UDP_HANDSHAKE SigPurpose = 33 // Signature used by UDP communicator handshake. +SIG_COMMUNICATOR_UDP_BROADCAST SigPurpose = 34 // Signature used by UDP broadcasts. +SIG_TRANSPORT_CHALLENGE SigPurpose = 35 // Signature by a peer affirming that it received a challenge (and stating how long it expects the address on which the challenge was received to remain valid). +SIG_TRANSPORT_DV_HOP SigPurpose = 36 // Signature by a peer affirming that it is on a DV path. +SIG_TRANSPORT_DV_INITIATOR SigPurpose = 37 // Signature by a peer affirming that it originated the DV path. +SIG_CADET_CONNECTION_INITIATOR SigPurpose = 38 // Signature by a peer that like to create a connection. + +) diff --git a/src/gnunet/enums/sigpurpose_string.go b/src/gnunet/enums/sigpurpose_string.go @@ -0,0 +1,75 @@ +// Code generated by "stringer -type=SigPurpose signature_purpose.go"; DO NOT EDIT. + +package enums + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[SIG_TEST-0] + _ = x[SIG_TRANSPORT_PONG_OWN-1] + _ = x[SIG_TRANSPORT_DISCONNECT-2] + _ = x[SIG_REVOCATION-3] + _ = x[SIG_NAMESPACE_ADVERTISEMENT-4] + _ = x[SIG_PEER_PLACEMENT-5] + _ = x[SIG_DHT_HOP-6] + _ = x[SIG_HELLO-7] + _ = x[SIG_DNS_RECORD-11] + _ = x[SIG_CHAT_MESSAGE-12] + _ = x[SIG_CHAT_RECEIPT-13] + _ = x[SIG_NSE_SEND-14] + _ = x[SIG_GNS_RECORD_SIGN-15] + _ = x[SIG_SET_ECC_KEY-16] + _ = x[SIG_FS_UBLOCK-17] + _ = x[SIG_REGEX_ACCEPT-18] + _ = x[SIG_CONVERSATION_RING-20] + _ = x[SIG_SECRETSHARING_DKG1-21] + _ = x[SIG_SECRETSHARING_DKG2-22] + _ = x[SIG_SECRETSHARING_DECRYPTION-23] + _ = x[SIG_RECLAIM_CODE_SIGN-27] + _ = x[SIG_DELEGATE-28] + _ = x[SIG_TRANSPORT_ADDRESS-29] + _ = x[SIG_TRANSPORT_EPHEMERAL-30] + _ = x[SIG_COMMUNICATOR_TCP_HANDSHAKE-31] + _ = x[SIG_COMMUNICATOR_TCP_REKEY-32] + _ = x[SIG_COMMUNICATOR_UDP_HANDSHAKE-33] + _ = x[SIG_COMMUNICATOR_UDP_BROADCAST-34] + _ = x[SIG_TRANSPORT_CHALLENGE-35] + _ = x[SIG_TRANSPORT_DV_HOP-36] + _ = x[SIG_TRANSPORT_DV_INITIATOR-37] + _ = x[SIG_CADET_CONNECTION_INITIATOR-38] +} + +const ( + _SigPurpose_name_0 = "SIG_TESTSIG_TRANSPORT_PONG_OWNSIG_TRANSPORT_DISCONNECTSIG_REVOCATIONSIG_NAMESPACE_ADVERTISEMENTSIG_PEER_PLACEMENTSIG_DHT_HOPSIG_HELLO" + _SigPurpose_name_1 = "SIG_DNS_RECORDSIG_CHAT_MESSAGESIG_CHAT_RECEIPTSIG_NSE_SENDSIG_GNS_RECORD_SIGNSIG_SET_ECC_KEYSIG_FS_UBLOCKSIG_REGEX_ACCEPT" + _SigPurpose_name_2 = "SIG_CONVERSATION_RINGSIG_SECRETSHARING_DKG1SIG_SECRETSHARING_DKG2SIG_SECRETSHARING_DECRYPTION" + _SigPurpose_name_3 = "SIG_RECLAIM_CODE_SIGNSIG_DELEGATESIG_TRANSPORT_ADDRESSSIG_TRANSPORT_EPHEMERALSIG_COMMUNICATOR_TCP_HANDSHAKESIG_COMMUNICATOR_TCP_REKEYSIG_COMMUNICATOR_UDP_HANDSHAKESIG_COMMUNICATOR_UDP_BROADCASTSIG_TRANSPORT_CHALLENGESIG_TRANSPORT_DV_HOPSIG_TRANSPORT_DV_INITIATORSIG_CADET_CONNECTION_INITIATOR" +) + +var ( + _SigPurpose_index_0 = [...]uint8{0, 8, 30, 54, 68, 95, 113, 124, 133} + _SigPurpose_index_1 = [...]uint8{0, 14, 30, 46, 58, 77, 92, 105, 121} + _SigPurpose_index_2 = [...]uint8{0, 21, 43, 65, 93} + _SigPurpose_index_3 = [...]uint16{0, 21, 33, 54, 77, 107, 133, 163, 193, 216, 236, 262, 292} +) + +func (i SigPurpose) String() string { + switch { + case 0 <= i && i <= 7: + return _SigPurpose_name_0[_SigPurpose_index_0[i]:_SigPurpose_index_0[i+1]] + case 11 <= i && i <= 18: + i -= 11 + return _SigPurpose_name_1[_SigPurpose_index_1[i]:_SigPurpose_index_1[i+1]] + case 20 <= i && i <= 23: + i -= 20 + return _SigPurpose_name_2[_SigPurpose_index_2[i]:_SigPurpose_index_2[i+1]] + case 27 <= i && i <= 38: + i -= 27 + return _SigPurpose_name_3[_SigPurpose_index_3[i]:_SigPurpose_index_3[i+1]] + default: + return "SigPurpose(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/src/gnunet/message/const.go b/src/gnunet/message/const.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/message/factory.go b/src/gnunet/message/factory.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -66,6 +66,8 @@ func NewEmptyMessage(msgType uint16) (Message, error) { return NewDHTClientResultMsg(nil), nil case DHT_CLIENT_GET_RESULTS_KNOWN: return NewDHTClientGetResultsKnownMsg(nil), nil + case DHT_P2P_HELLO: + return NewHelloDHTMsg(), nil //------------------------------------------------------------------ // GNS diff --git a/src/gnunet/message/message.go b/src/gnunet/message/message.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/message/msg_core.go b/src/gnunet/message/msg_core.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -60,7 +60,7 @@ func NewEphemeralKeyMsg() *EphemeralKeyMsg { SignedBlock: &EphKeyBlock{ Purpose: &crypto.SignaturePurpose{ Size: 88, - Purpose: enums.SIG_ECC_KEY, + Purpose: uint32(enums.SIG_SET_ECC_KEY), }, CreateTime: util.AbsoluteTimeNow(), ExpireTime: util.NewRelativeTime(12 * time.Hour), @@ -86,7 +86,7 @@ func (m *EphemeralKeyMsg) Header() *Header { // Public extracts the public key of an announcing peer. func (m *EphemeralKeyMsg) Public() *ed25519.PublicKey { - return ed25519.NewPublicKeyFromBytes(m.SignedBlock.PeerID.Key) + return m.SignedBlock.PeerID.PublicKey() } // Verify the integrity of the message data using the public key of the diff --git a/src/gnunet/message/msg_dht.go b/src/gnunet/message/msg_dht.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/message/msg_gns.go b/src/gnunet/message/msg_gns.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -154,7 +154,7 @@ type ResourceRecord struct { // String returns a human-readable representation of the message. func (r *ResourceRecord) String() string { return fmt.Sprintf("GNSResourceRecord{type=%s,expire=%s,flags=%d,size=%d}", - enums.GNS_TYPE[int(r.Type)], r.Expires, r.Flags, r.Size) + enums.GNSType(r.Type).String(), r.Expires, r.Flags, r.Size) } // LookupResultMsg is a response message for a GNS name lookup request diff --git a/src/gnunet/message/msg_hello.go b/src/gnunet/message/msg_hello.go @@ -19,82 +19,163 @@ package message import ( + "bytes" + "encoding/binary" "fmt" "gnunet/util" + "io" ) //---------------------------------------------------------------------- -// HELLO -// -// A HELLO message is used to exchange information about transports with -// other peers. This struct is always followed by the actual network -// addresses which have the format: -// -// 1) transport-name (0-terminated) -// 2) address-length (uint16_t, network byte order) -// 3) address expiration -// 4) address (address-length bytes) -//---------------------------------------------------------------------- -// HelloAddress represents a (generic) peer address with expiration date +// HelloAddress represents a (generic) peer address with expiration date: type HelloAddress struct { - Transport string // Name of transport - AddrSize uint16 `order:"big"` // Size of address entry - ExpireOn util.AbsoluteTime // Expiry date - Address []byte `size:"AddrSize"` // Address specification + transport string // Name of transport + addrSize uint16 // Size of address entry + expires util.AbsoluteTime // Expiry date + address []byte // Address specification } // NewHelloAddress create a new HELLO address from the given address func NewHelloAddress(a *util.Address) *HelloAddress { addr := &HelloAddress{ - Transport: a.Netw, - AddrSize: uint16(len(a.Address)), - ExpireOn: a.Expires, - Address: make([]byte, len(a.Address)), + transport: a.Netw, + addrSize: uint16(len(a.Address)), + expires: a.Expires, + address: make([]byte, len(a.Address)), } - copy(addr.Address, a.Address) + copy(addr.address, a.Address) return addr } +// ParseHelloAddress from reader +func ParseHelloAddr(rdr io.Reader) (a *HelloAddress, err error) { + // parse \0-terminated transport + var ( + transport []byte + buf = make([]byte, 1) + ) + for { + if _, err = rdr.Read(buf); err != nil { + return + } + if buf[0] == 0 { + break + } + transport = append(transport, buf[0]) + } + // parse address size + var asize uint16 + if err = binary.Read(rdr, binary.BigEndian, &asize); err != nil { + return + } + // parse expiration time + var exp uint64 + if err = binary.Read(rdr, binary.BigEndian, &exp); err != nil { + return + } + // get address data + adata := make([]byte, asize) + if _, err = rdr.Read(adata); err != nil { + return + } + // assemble HELLO address + a = &HelloAddress{ + transport: string(transport), + addrSize: asize, + expires: util.AbsoluteTime{Val: exp}, + address: adata, + } + return +} + +// Wrap a HelloAddress into a uitl.Address +func (a *HelloAddress) Wrap() (addr *util.Address) { + addr = util.NewAddress(a.transport, string(a.address)) + addr.Expires = a.expires + return +} + // String returns a human-readable representation of the message. func (a *HelloAddress) String() string { return fmt.Sprintf("Address{%s,expire=%s}", - util.URI(a.Transport, a.Address), a.ExpireOn) + util.URI(a.transport, a.address), a.expires) +} + +// Bytes returns the binary representation of a HelloAddress +func (a *HelloAddress) Bytes() []byte { + buf := new(bytes.Buffer) + buf.Write([]byte(a.transport)) + buf.WriteByte(0) + binary.Write(buf, binary.BigEndian, a.addrSize) + binary.Write(buf, binary.BigEndian, a.expires.Val) + buf.Write(a.address) + return buf.Bytes() } +//---------------------------------------------------------------------- +// HELLO +// +// A HELLO message is used to exchange information about transports with +// other peers. This struct is always followed by the actual network +// addresses of type "HelloAddress" +//---------------------------------------------------------------------- + // HelloMsg is a message send by peers to announce their presence type HelloMsg struct { - MsgSize uint16 `order:"big"` // total size of message - MsgType uint16 `order:"big"` // HELLO (17) - FriendOnly uint32 `order:"big"` // =1: do not gossip this HELLO - PeerID *util.PeerID // EdDSA public key (long-term) - Addresses []*HelloAddress `size:"*"` // List of end-point addressess + MsgSize uint16 `order:"big"` // total size of message + MsgType uint16 `order:"big"` // HELLO (17) + FriendsOnly uint32 `order:"big"` // Do not gossip this HELLO message + Peer *util.PeerID `` // peer identifier for addresses + AddrList []byte `size:"*"` // List of end-point addresses (HelloAddress) } // NewHelloMsg creates a new HELLO msg for a given peer. -func NewHelloMsg(peerid *util.PeerID) *HelloMsg { - if peerid == nil { - peerid = util.NewPeerID(nil) +func NewHelloMsg(peer *util.PeerID) *HelloMsg { + // allocate peer id if none is specified + if peer == nil { + peer = util.NewPeerID(nil) } + // return empty HelloMessage return &HelloMsg{ - MsgSize: 40, - MsgType: HELLO, - FriendOnly: 0, - PeerID: peerid, - Addresses: make([]*HelloAddress, 0), + MsgSize: 40, // size without 'AddrList' + MsgType: HELLO, // HELLO (17) + FriendsOnly: 0, // not used here + Peer: peer, // associated peer + AddrList: make([]byte, 0), // list of addresses + } +} + +// Addresses returns the list of HelloAddress +func (m *HelloMsg) Addresses() (list []*HelloAddress, err error) { + rdr := bytes.NewReader(m.AddrList) + var addr *HelloAddress + for { + // parse address from stream + if addr, err = ParseHelloAddr(rdr); err != nil { + // end of stream: no more addresses + if err == io.EOF { + err = nil + } + return + } + list = append(list, addr) } } // String returns a human-readable representation of the message. func (m *HelloMsg) String() string { - return fmt.Sprintf("HelloMsg{peer=%s,friendsonly=%d,addr=%v}", - m.PeerID, m.FriendOnly, m.Addresses) + return fmt.Sprintf("HelloMsg{%s: addrs=%d}", m.Peer, len(m.AddrList)) } -// AddAddress adds a new address to the HELLO message. -func (m *HelloMsg) AddAddress(a *HelloAddress) { - m.Addresses = append(m.Addresses, a) - m.MsgSize += uint16(len(a.Transport)) + a.AddrSize + 11 +// SetAddresses adds addresses to the HELLO message. +func (m *HelloMsg) SetAddresses(list []*HelloAddress) { + wrt := new(bytes.Buffer) + for _, addr := range list { + n, _ := wrt.Write(addr.Bytes()) + m.MsgSize += uint16(n) + } + m.AddrList = wrt.Bytes() } // Header returns the message header in a separate instance. diff --git a/src/gnunet/message/msg_hello_dht.go b/src/gnunet/message/msg_hello_dht.go @@ -0,0 +1,146 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019-2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +package message + +import ( + "bytes" + "crypto/sha512" + "encoding/binary" + "fmt" + "gnunet/enums" + "gnunet/util" + "io" + "time" + + "github.com/bfix/gospel/crypto/ed25519" + "github.com/bfix/gospel/logger" +) + +//---------------------------------------------------------------------- +// HELLO-DHT +// +// A HELLO message is used to exchange information about transports with +// other DHT nodes. This struct is always followed by the actual network +// addresses of type "HelloAddress" +//---------------------------------------------------------------------- + +// HelloDHTMsg is a message send by peers to announce their presence +type HelloDHTMsg struct { + MsgSize uint16 `order:"big"` // total size of message + MsgType uint16 `order:"big"` // DHT_P2P_HELLO (157) + Reserved uint16 `order:"big"` // Reserved for further use + NumAddr uint16 `order:"big"` // Number of addresses in list + Signature []byte `size:"64"` // Signature + Expires util.AbsoluteTime `` // expiration time + AddrList []byte `size:"*"` // List of end-point addresses (HelloAddress) +} + +// NewHelloMsgDHT creates an empty DHT_P2P_HELLO message. +func NewHelloDHTMsg() *HelloDHTMsg { + // return empty HelloMessage + exp := time.Now().Add(HelloAddressExpiration) + return &HelloDHTMsg{ + MsgSize: 80, // size without 'AddrList' + MsgType: DHT_P2P_HELLO, // DHT_P2P_HELLO (157) + Reserved: 0, // not used here + NumAddr: 0, // start with empty address list + Signature: make([]byte, 64), // signature + Expires: util.NewAbsoluteTime(exp), // default expiration + AddrList: make([]byte, 0), // list of addresses + } +} + +// Addresses returns the list of HelloAddress +func (m *HelloDHTMsg) Addresses() (list []*HelloAddress, err error) { + rdr := bytes.NewReader(m.AddrList) + var addr *HelloAddress + num := 0 + for { + // parse address from stream + if addr, err = ParseHelloAddr(rdr); err != nil { + // end of stream: no more addresses + if err == io.EOF { + err = nil + } + // check numbers + if num != int(m.NumAddr) { + logger.Printf(logger.WARN, "[HelloDHTMsg] Number of addresses doesn't match (got %d, expected %d)", num, m.NumAddr) + } + return + } + list = append(list, addr) + num++ + } +} + +// String returns a human-readable representation of the message. +func (m *HelloDHTMsg) String() string { + return fmt.Sprintf("HelloDHTMsg{expire:%s,addrs=%d}", m.Expires, m.NumAddr) +} + +// SetAddresses adds addresses to the HELLO message. +func (m *HelloDHTMsg) SetAddresses(list []*HelloAddress) { + // write addresses as blob and track earliest expiration + exp := util.AbsoluteTimeNever() + wrt := new(bytes.Buffer) + for _, addr := range list { + // check if address expires before current expire + if _, after := exp.Diff(addr.expires); !after { + exp = addr.expires + } + n, _ := wrt.Write(addr.Bytes()) + m.MsgSize += uint16(n) + m.NumAddr++ + } + m.AddrList = wrt.Bytes() + m.Expires = exp +} + +// Header returns the message header in a separate instance. +func (m *HelloDHTMsg) Header() *Header { + return &Header{m.MsgSize, m.MsgType} +} + +// Verify the message signature +func (m *HelloDHTMsg) Verify(peer *util.PeerID) (bool, error) { + // assemble signed data and public key + sd := m.signedData() + pub := peer.PublicKey() + sig, err := ed25519.NewEdSignatureFromBytes(m.Signature) + if err != nil { + return false, err + } + return pub.EdVerify(sd, sig) +} + +// signedData assembles a data block for sign and verify operations. +func (m *HelloDHTMsg) signedData() []byte { + // hash address block + hAddr := sha512.Sum512(m.AddrList) + var size uint32 = 80 + purpose := uint32(enums.SIG_HELLO) + + // assemble signed data + buf := new(bytes.Buffer) + binary.Write(buf, binary.BigEndian, size) + binary.Write(buf, binary.BigEndian, purpose) + binary.Write(buf, binary.BigEndian, m.Expires.Epoch()*1000000) + buf.Write(hAddr[:]) + return buf.Bytes() +} diff --git a/src/gnunet/message/msg_namecache.go b/src/gnunet/message/msg_namecache.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/message/msg_revocation.go b/src/gnunet/message/msg_revocation.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/message/msg_transport.go b/src/gnunet/message/msg_transport.go @@ -145,7 +145,7 @@ func NewSignedAddress(a *util.Address) *SignedAddress { addr := &SignedAddress{ Purpose: &crypto.SignaturePurpose{ Size: uint32(alen + 20), - Purpose: enums.SIG_TRANSPORT_PONG_OWN, + Purpose: uint32(enums.SIG_TRANSPORT_PONG_OWN), }, ExpireOn: util.AbsoluteTimeNow().Add(12 * time.Hour), AddrSize: uint32(alen), diff --git a/src/gnunet/message/types.go b/src/gnunet/message/types.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -193,6 +193,10 @@ const ( DHT_MONITOR_START = 153 // Request information about transiting messages DHT_MONITOR_STOP = 154 // Stop information about transiting messages DHT_CLIENT_GET_RESULTS_KNOWN = 156 // Certain results are already known to the client, filter those. + DHT_P2P_HELLO = 157 // HELLO advertising a neighbours addresses. + DHT_CORE = 158 // Encapsulation of DHT messages in CORE service. + DHT_CLIENT_HELLO_URL = 159 // HELLO URL send between client and service (in either direction). + DHT_CLIENT_HELLO_GET = 161 // Client requests DHT service's HELLO URL. //------------------------------------------------------------------ // HOSTLIST message types diff --git a/src/gnunet/rpc/server.go b/src/gnunet/rpc/server.go @@ -1,66 +0,0 @@ -// This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< -// -// gnunet-go 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-go 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 - -package rpc - -import ( - "context" - "gnunet/config" - "gnunet/service" - "net/http" - "time" - - "github.com/bfix/gospel/logger" - "github.com/gorilla/mux" -) - -// Router for JSON-RPC requests -var Router = mux.NewRouter() -var srv *http.Server - -// Start the JSON-RPC server. It can be terminated by context -func Start(ctx context.Context) error { - // instantiate a server and run it - srv = &http.Server{ - Handler: Router, - Addr: config.Cfg.RPC.Endpoint, - WriteTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, - } - go func() { - // start listening - go func() { - if err := srv.ListenAndServe(); err != nil { - logger.Printf(logger.WARN, "[RPC] Server listen failed: %s", err.Error()) - } - }() - select { - case <-ctx.Done(): - if err := srv.Shutdown(context.Background()); err != nil { - logger.Printf(logger.WARN, "[RPC] Server shutdownn failed: %s", err.Error()) - } - } - }() - return nil -} - -// Register a JSON-RPC path in a service-specific processor -func Register(m service.Module) { - path, hdlr := m.RPC() - Router.HandleFunc(path, hdlr) -} diff --git a/src/gnunet/service/client.go b/src/gnunet/service/client.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/service/dht/blocks/hello.go b/src/gnunet/service/dht/blocks/hello.go @@ -20,8 +20,11 @@ package blocks import ( "bytes" + "crypto/sha512" "encoding/binary" + "errors" "fmt" + "gnunet/enums" "gnunet/util" "net/url" "strconv" @@ -31,6 +34,12 @@ import ( "github.com/bfix/gospel/data" ) +// HELLO-related errors +var ( + ErrHelloExpired = errors.New("expired HELLO") + ErrHelloSignature = errors.New("failed HELLO signature") +) + //---------------------------------------------------------------------- // HELLO URLs are used for bootstrapping a node and for adding nodes // outside of GNUnet message exchange (e.g. command-line tools) @@ -43,10 +52,10 @@ const helloPrefix = "gnunet://hello/" // All addresses expire at the same time /this different from HELLO // messages (see message.HeeloMsg). type HelloBlock struct { - PeerID *util.PeerID `` // peer identifier - Signature *ed25519.EdSignature `` // signature - Expire util.AbsoluteTime `` // Expiration date - AddrBin []byte `size:"*"` // raw address data + PeerID *util.PeerID `` // peer identifier + Signature []byte `size:"64"` // signature + Expire util.AbsoluteTime `` // Expiration date + AddrBin []byte `size:"*"` // raw address data // transient attributes addrs []*util.Address // cooked address data @@ -66,7 +75,7 @@ func (h *HelloBlock) Addresses() []*util.Address { // ParseHelloURL parses a HELLO URL of the following form: // gnunet://hello/<PeerID>/<signature>/<expire>?<addrs> // The addresses are encoded. -func ParseHelloURL(u string) (h *HelloBlock, err error) { +func ParseHelloURL(u string, checkExpiry bool) (h *HelloBlock, err error) { // check and trim prefix if !strings.HasPrefix(u, helloPrefix) { err = fmt.Errorf("invalid HELLO-URL prefix: '%s'", u) @@ -92,10 +101,7 @@ func ParseHelloURL(u string) (h *HelloBlock, err error) { h.PeerID = util.NewPeerID(buf) // (2) parse signature - if buf, err = util.DecodeStringToBinary(p[1], 64); err != nil { - return - } - if h.Signature, err = ed25519.NewEdSignatureFromBytes(buf); err != nil { + if h.Signature, err = util.DecodeStringToBinary(p[1], 64); err != nil { return } @@ -108,18 +114,24 @@ func ParseHelloURL(u string) (h *HelloBlock, err error) { return } h.Expire = util.NewAbsoluteTimeEpoch(exp) + if checkExpiry && h.Expire.Expired() { + err = ErrHelloExpired + return + } // (5) process addresses. h.addrs = make([]*util.Address, 0) - var ua string for _, a := range strings.Split(q[1], "&") { - // unescape URL query - if ua, err = url.QueryUnescape(a); err != nil { + // reformat to standard address format + ap := strings.SplitN(a, "=", 2) + var q string + if q, err = url.QueryUnescape(ap[1]); err != nil { return } + as := ap[0] + "://" + q // parse address and append it to list var addr *util.Address - if addr, err = util.ParseAddress(ua); err != nil { + if addr, err = util.ParseAddress(as); err != nil { return } h.addrs = append(h.addrs, addr) @@ -127,6 +139,15 @@ func ParseHelloURL(u string) (h *HelloBlock, err error) { // (6) generate raw address data so block is complete h.finalize() + + // check signature + var ok bool + if ok, err = h.Verify(); err != nil { + return + } + if !ok { + err = ErrHelloSignature + } return } @@ -142,11 +163,26 @@ func ParseHelloFromBytes(buf []byte) (h *HelloBlock, err error) { // finalize block data (generate dependent fields) func (h *HelloBlock) finalize() (err error) { if h.addrs == nil { - err = data.Unmarshal(h.addrs, h.AddrBin) + // read addresses from the binary representation + pos := 0 + h.addrs = make([]*util.Address, 0) + for { + var as string + as, pos = util.ReadCString(h.AddrBin, pos) + if pos == -1 { + break + } + var addr *util.Address + if addr, err = util.ParseAddress(as); err != nil { + return + } + h.addrs = append(h.addrs, addr) + } } else if h.AddrBin == nil { + // generate binary representation of addresses wrt := new(bytes.Buffer) for _, a := range h.addrs { - wrt.WriteString(a.String()) + wrt.WriteString(a.URI()) wrt.WriteByte(0) } h.AddrBin = wrt.Bytes() @@ -170,14 +206,16 @@ func (h *HelloBlock) URL() string { u := fmt.Sprintf("%s%s/%s/%d?", helloPrefix, h.PeerID.String(), - util.EncodeBinaryToString(h.Signature.Bytes()), + util.EncodeBinaryToString(h.Signature), h.Expire.Epoch(), ) for i, a := range h.addrs { if i > 0 { u += "&" } - u += url.QueryEscape(a.URI()) + au := a.URI() + p := strings.SplitN(au, "://", 2) + u += p[0] + "=" + url.QueryEscape(p[1]) } return u } @@ -186,7 +224,7 @@ func (h *HelloBlock) URL() string { // timestamp is ignored in the comparision. func (h *HelloBlock) Equals(g *HelloBlock) bool { if !h.PeerID.Equals(g.PeerID) || - !util.Equals(h.Signature.Bytes(), g.Signature.Bytes()) || + !util.Equals(h.Signature, g.Signature) || len(h.addrs) != len(g.addrs) { return false } @@ -202,25 +240,38 @@ func (h *HelloBlock) Equals(g *HelloBlock) bool { func (h *HelloBlock) Verify() (bool, error) { // assemble signed data and public key sd := h.signedData() - pub := ed25519.NewPublicKeyFromBytes(h.PeerID.Key) - return pub.EdVerify(sd, h.Signature) + pub := h.PeerID.PublicKey() + sig, err := ed25519.NewEdSignatureFromBytes(h.Signature) + if err != nil { + return false, err + } + return pub.EdVerify(sd, sig) } // Sign the HELLO data with private key -func (h *HelloBlock) Sign(prv *ed25519.PrivateKey) (err error) { +func (h *HelloBlock) Sign(prv *ed25519.PrivateKey) error { // assemble signed data sd := h.signedData() - h.Signature, err = prv.EdSign(sd) - return + sig, err := prv.EdSign(sd) + if err != nil { + return err + } + h.Signature = sig.Bytes() + return nil } // signedData assembles a data block for sign and verify operations. func (h *HelloBlock) signedData() []byte { + // hash address block + hAddr := sha512.Sum512(h.AddrBin) + var size uint32 = 80 + purpose := uint32(enums.SIG_HELLO) + + // assemble signed data buf := new(bytes.Buffer) - buf.Write(h.PeerID.Key) - binary.Write(buf, binary.BigEndian, h.Expire) - for _, a := range h.addrs { - buf.Write(a.Address) - } + binary.Write(buf, binary.BigEndian, size) + binary.Write(buf, binary.BigEndian, purpose) + binary.Write(buf, binary.BigEndian, h.Expire.Epoch()*1000000) + buf.Write(hAddr[:]) return buf.Bytes() } diff --git a/src/gnunet/service/dht/blocks/hello_test.go b/src/gnunet/service/dht/blocks/hello_test.go @@ -1,44 +0,0 @@ -// This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019-2022 Bernd Fix >Y< -// -// gnunet-go 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-go 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 - -package blocks - -import "testing" - -const ( - helloURL = "gnunet://hello" + - "/7KTBJ90340HF1Q2GB0A57E2XJER4FDHX8HP5GHEB9125VPWPD27G" + - - "/BNMDFN6HJCPWSPNBSEC06MC1K8QN1Z2DHRQSRXDTFR7FTBD4JHN" + - "BJ2RJAAEZ31FWG1Q3PMN3PXGZQ3Q7NTNEKQZFA7TE2Y46FM8E20R" + - "/1653499308" + - "?r5n%2Bip%2Budp%3A1.2.3.4%3A6789" + - "&gnunet%2Btcp%3A12.3.4.5" -) - -func TestHelloURL(t *testing.T) { - - hd, err := ParseHelloURL(helloURL) - if err != nil { - t.Fatal(err) - } - u := hd.URL() - if u != helloURL { - t.Fatal("urls don't match") - } -} diff --git a/src/gnunet/service/dht/module.go b/src/gnunet/service/dht/module.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -25,7 +25,6 @@ import ( "gnunet/message" "gnunet/service" "gnunet/service/dht/blocks" - "net/http" "time" ) @@ -50,16 +49,15 @@ type Module struct { // NewModule returns a new module instance. It initializes the storage // mechanism for persistence. -func NewModule(ctx context.Context, c *core.Core) (m *Module) { +func NewModule(ctx context.Context, c *core.Core) (m *Module, err error) { // create permanent storage handler - store, err := service.NewDHTStore(config.Cfg.DHT.Storage) - if err != nil { - return nil + var store, cache service.DHTStore + if store, err = service.NewDHTStore(config.Cfg.DHT.Storage); err != nil { + return } // create cache handler - cache, err := service.NewDHTStore(config.Cfg.DHT.Cache) - if err != nil { - return nil + if cache, err = service.NewDHTStore(config.Cfg.DHT.Cache); err != nil { + return } // create routing table rt := NewRoutingTable(NewPeerAddress(c.PeerID())) @@ -75,22 +73,21 @@ func NewModule(ctx context.Context, c *core.Core) (m *Module) { // register as listener for core events listener := m.Run(ctx, m.event, m.Filter(), 15*time.Minute, m.heartbeat) c.Register("dht", listener) - return } //---------------------------------------------------------------------- // Get a block from the DHT ["dht:get"] -func (nc *Module) Get(ctx context.Context, query blocks.Query) (block blocks.Block, err error) { +func (m *Module) Get(ctx context.Context, query blocks.Query) (block blocks.Block, err error) { // check if we have the requested block in cache or permanent storage. - block, err = nc.cache.Get(query) + block, err = m.cache.Get(query) if err == nil { // yes: we are done return } - block, err = nc.store.Get(query) + block, err = m.store.Get(query) if err == nil { // yes: we are done return @@ -101,7 +98,7 @@ func (nc *Module) Get(ctx context.Context, query blocks.Query) (block blocks.Blo } // Put a block into the DHT ["dht:put"] -func (nc *Module) Put(ctx context.Context, key blocks.Query, block blocks.Block) error { +func (m *Module) Put(ctx context.Context, key blocks.Query, block blocks.Block) error { return nil } @@ -126,9 +123,20 @@ func (m *Module) event(ctx context.Context, ev *core.Event) { // New peer connected: case core.EV_CONNECT: // Add peer to routing table - + m.rtable.Add(NewPeerAddress(ev.Peer)) + + // Peer disconnected: + case core.EV_DISCONNECT: + // Remove peer from routing table + m.rtable.Remove(NewPeerAddress(ev.Peer)) + + // Message received. + case core.EV_MESSAGE: + // process message (if applicable) + if m.ProcessFcn != nil { + m.ProcessFcn(ctx, ev.Msg, ev.Resp) + } } - } // Heartbeat handler for periodic tasks @@ -153,12 +161,3 @@ func (m *Module) Export(fcn map[string]any) { func (m *Module) Import(fcm map[string]any) { // nothing to import now. } - -//---------------------------------------------------------------------- - -// RPC returns the route and handler function for a JSON-RPC request -func (m *Module) RPC() (string, func(http.ResponseWriter, *http.Request)) { - return "/gns/", func(wrt http.ResponseWriter, req *http.Request) { - wrt.Write([]byte(`{"msg": "This is DHT" }`)) - } -} diff --git a/src/gnunet/service/dht/rpc.go b/src/gnunet/service/dht/rpc.go @@ -0,0 +1,46 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019-2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +package dht + +import ( + "net/rpc" + "time" +) + +//---------------------------------------------------------------------- + +type DHTCommand struct{} + +type DHTStats struct { + Started time.Time +} + +func (c *DHTCommand) Status(mode int, stats *DHTStats) error { + *stats = DHTStats{ + Started: time.Now(), + } + return nil +} + +//---------------------------------------------------------------------- + +// InitRPC registers RPC commands for the module +func (m *Module) InitRPC(srv *rpc.Server) { + srv.Register(new(DHTCommand)) +} diff --git a/src/gnunet/service/dht/service.go b/src/gnunet/service/dht/service.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -26,6 +26,7 @@ import ( "gnunet/core" "gnunet/message" "gnunet/service" + "gnunet/transport" "github.com/bfix/gospel/logger" ) @@ -47,10 +48,16 @@ type Service struct { } // NewService creates a new DHT service instance -func NewService(ctx context.Context, c *core.Core) service.Service { - return &Service{ - Module: *NewModule(ctx, c), +func NewService(ctx context.Context, c *core.Core) (service.Service, error) { + mod, err := NewModule(ctx, c) + if err != nil { + return nil, err } + srv := &Service{ + Module: *mod, + } + srv.ProcessFcn = srv.HandleMessage + return srv, nil } // ServeClient processes a client channel. @@ -90,7 +97,7 @@ loop: // HandleMessage handles a DHT request/response message. If the transport channel // is nil, responses are send directly via the transport layer. -func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back service.Responder) bool { +func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back transport.Responder) bool { // assemble log label label := "" if v := ctx.Value("label"); v != nil { diff --git a/src/gnunet/service/gns/block_handler.go b/src/gnunet/service/gns/block_handler.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -46,7 +46,7 @@ var ( // Mapping of RR types to BlockHandler instanciation functions var ( - customHandler = map[int]HdlrInst{ + customHandler = map[enums.GNSType]HdlrInst{ enums.GNS_TYPE_PKEY: NewZoneHandler, enums.GNS_TYPE_EDKEY: NewZoneHandler, enums.GNS_TYPE_GNS2DNS: NewGns2DnsHandler, @@ -76,7 +76,7 @@ type BlockHandler interface { // resource records in the same block. 'cm' maps the resource type // to an integer count (how many records of a type are present in the // GNS block). - Coexist(cm util.Counter[int]) bool + Coexist(cm util.Counter[enums.GNSType]) bool // Records returns a list of RR of the given types associated with // the custom handler @@ -102,8 +102,8 @@ type BlockHandler interface { // BlockHandlerList is a list of block handlers instantiated. type BlockHandlerList struct { - list map[int]BlockHandler // list of handler instances - counts util.Counter[int] // count number of RRs by type + list map[enums.GNSType]BlockHandler // list of handler instances + counts util.Counter[enums.GNSType] // count number of RRs by type } // NewBlockHandlerList instantiates an a list of active block handlers @@ -111,8 +111,8 @@ type BlockHandlerList struct { func NewBlockHandlerList(records []*message.ResourceRecord, labels []string) (*BlockHandlerList, []*message.ResourceRecord, error) { // initialize block handler list hl := &BlockHandlerList{ - list: make(map[int]BlockHandler), - counts: make(util.Counter[int]), + list: make(map[enums.GNSType]BlockHandler), + counts: make(util.Counter[enums.GNSType]), } // first pass: build list of shadow records in this block @@ -153,11 +153,11 @@ func NewBlockHandlerList(records []*message.ResourceRecord, labels []string) (*B logger.Printf(logger.DBG, "[gns] handler_list: skip %v\n", rec) continue } - rrType := int(rec.Type) + rrType := enums.GNSType(rec.Type) hl.counts.Add(rrType) // check for custom handler type - if creat, ok := customHandler[rrType]; ok { + if creat, ok := customHandler[enums.GNSType(rrType)]; ok { // check if a handler for given type already exists var ( hdlr BlockHandler @@ -194,7 +194,7 @@ func NewBlockHandlerList(records []*message.ResourceRecord, labels []string) (*B // GetHandler returns a BlockHandler for the given GNS block type. // If more than one type is given, the first matching hanlder is // returned. -func (hl *BlockHandlerList) GetHandler(types ...int) BlockHandler { +func (hl *BlockHandlerList) GetHandler(types ...enums.GNSType) BlockHandler { for _, t := range types { // return handler for given type if it exists if hdlr, ok := hl.list[t]; ok { @@ -260,7 +260,7 @@ func (h *ZoneKeyHandler) AddRecord(rec *message.ResourceRecord, labels []string) // Coexist return a flag indicating how a resource record of a given type // is to be treated (see BlockHandler interface) -func (h *ZoneKeyHandler) Coexist(cm util.Counter[int]) bool { +func (h *ZoneKeyHandler) Coexist(cm util.Counter[enums.GNSType]) bool { // only one type (GNS_TYPE_PKEY) is present return len(cm) == 1 && cm.Num(enums.GNS_TYPE_PKEY) == 1 } @@ -292,7 +292,7 @@ type Gns2DnsHandler struct { // NewGns2DnsHandler returns a new BlockHandler instance func NewGns2DnsHandler(rec *message.ResourceRecord, labels []string) (BlockHandler, error) { - if int(rec.Type) != enums.GNS_TYPE_GNS2DNS { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_GNS2DNS { return nil, ErrInvalidRecordType } h := &Gns2DnsHandler{ @@ -308,7 +308,7 @@ func NewGns2DnsHandler(rec *message.ResourceRecord, labels []string) (BlockHandl // AddRecord inserts a GNS2DNS record into the handler. func (h *Gns2DnsHandler) AddRecord(rec *message.ResourceRecord, labels []string) error { - if int(rec.Type) != enums.GNS_TYPE_GNS2DNS { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_GNS2DNS { return ErrInvalidRecordType } logger.Printf(logger.DBG, "[gns] GNS2DNS data: %s\n", hex.EncodeToString(rec.Data)) @@ -335,7 +335,7 @@ func (h *Gns2DnsHandler) AddRecord(rec *message.ResourceRecord, labels []string) // Coexist return a flag indicating how a resource record of a given type // is to be treated (see BlockHandler interface) -func (h *Gns2DnsHandler) Coexist(cm util.Counter[int]) bool { +func (h *Gns2DnsHandler) Coexist(cm util.Counter[enums.GNSType]) bool { // only one type (GNS_TYPE_GNS2DNS) is present return len(cm) == 1 && cm.Num(enums.GNS_TYPE_GNS2DNS) > 0 } @@ -367,7 +367,7 @@ type BoxHandler struct { // NewBoxHandler returns a new BlockHandler instance func NewBoxHandler(rec *message.ResourceRecord, labels []string) (BlockHandler, error) { - if int(rec.Type) != enums.GNS_TYPE_BOX { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_BOX { return nil, ErrInvalidRecordType } h := &BoxHandler{ @@ -381,7 +381,7 @@ func NewBoxHandler(rec *message.ResourceRecord, labels []string) (BlockHandler, // AddRecord inserts a BOX record into the handler. func (h *BoxHandler) AddRecord(rec *message.ResourceRecord, labels []string) error { - if int(rec.Type) != enums.GNS_TYPE_BOX { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_BOX { return ErrInvalidRecordType } logger.Printf(logger.DBG, "[box-rr] for labels %v\n", labels) @@ -405,7 +405,7 @@ func (h *BoxHandler) AddRecord(rec *message.ResourceRecord, labels []string) err // Coexist return a flag indicating how a resource record of a given type // is to be treated (see BlockHandler interface) -func (h *BoxHandler) Coexist(cm util.Counter[int]) bool { +func (h *BoxHandler) Coexist(cm util.Counter[enums.GNSType]) bool { // anything goes... return true } @@ -414,7 +414,7 @@ func (h *BoxHandler) Coexist(cm util.Counter[int]) bool { func (h *BoxHandler) Records(kind RRTypeList) *message.RecordSet { rs := message.NewRecordSet() for _, box := range h.boxes { - if kind.HasType(int(box.Type)) { + if kind.HasType(enums.GNSType(box.Type)) { // valid box found: assemble new resource record. rr := new(message.ResourceRecord) rr.Expires = box.rec.Expires @@ -445,7 +445,7 @@ type LehoHandler struct { // NewLehoHandler returns a new BlockHandler instance func NewLehoHandler(rec *message.ResourceRecord, labels []string) (BlockHandler, error) { - if int(rec.Type) != enums.GNS_TYPE_LEHO { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_LEHO { return nil, ErrInvalidRecordType } h := &LehoHandler{ @@ -459,7 +459,7 @@ func NewLehoHandler(rec *message.ResourceRecord, labels []string) (BlockHandler, // AddRecord inserts a LEHO record into the handler. func (h *LehoHandler) AddRecord(rec *message.ResourceRecord, labels []string) error { - if int(rec.Type) != enums.GNS_TYPE_LEHO { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_LEHO { return ErrInvalidRecordType } h.name = string(rec.Data) @@ -469,7 +469,7 @@ func (h *LehoHandler) AddRecord(rec *message.ResourceRecord, labels []string) er // Coexist return a flag indicating how a resource record of a given type // is to be treated (see BlockHandler interface) -func (h *LehoHandler) Coexist(cm util.Counter[int]) bool { +func (h *LehoHandler) Coexist(cm util.Counter[enums.GNSType]) bool { // requires exactly one LEHO and any number of other records. return cm.Num(enums.GNS_TYPE_LEHO) == 1 } @@ -500,7 +500,7 @@ type CnameHandler struct { // NewCnameHandler returns a new BlockHandler instance func NewCnameHandler(rec *message.ResourceRecord, labels []string) (BlockHandler, error) { - if int(rec.Type) != enums.GNS_TYPE_DNS_CNAME { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_DNS_CNAME { return nil, ErrInvalidRecordType } h := &CnameHandler{ @@ -514,7 +514,7 @@ func NewCnameHandler(rec *message.ResourceRecord, labels []string) (BlockHandler // AddRecord inserts a CNAME record into the handler. func (h *CnameHandler) AddRecord(rec *message.ResourceRecord, labels []string) error { - if int(rec.Type) != enums.GNS_TYPE_DNS_CNAME { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_DNS_CNAME { return ErrInvalidRecordType } if h.rec != nil { @@ -527,7 +527,7 @@ func (h *CnameHandler) AddRecord(rec *message.ResourceRecord, labels []string) e // Coexist return a flag indicating how a resource record of a given type // is to be treated (see BlockHandler interface) -func (h *CnameHandler) Coexist(cm util.Counter[int]) bool { +func (h *CnameHandler) Coexist(cm util.Counter[enums.GNSType]) bool { // only a single CNAME allowed return len(cm) == 1 && cm.Num(enums.GNS_TYPE_DNS_CNAME) == 1 } @@ -557,7 +557,7 @@ type VpnHandler struct { // NewVpnHandler returns a new BlockHandler instance func NewVpnHandler(rec *message.ResourceRecord, labels []string) (BlockHandler, error) { - if int(rec.Type) != enums.GNS_TYPE_VPN { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_VPN { return nil, ErrInvalidRecordType } h := &VpnHandler{} @@ -569,7 +569,7 @@ func NewVpnHandler(rec *message.ResourceRecord, labels []string) (BlockHandler, // AddRecord inserts a VPN record into the handler. func (h *VpnHandler) AddRecord(rec *message.ResourceRecord, labels []string) error { - if int(rec.Type) != enums.GNS_TYPE_VPN { + if enums.GNSType(rec.Type) != enums.GNS_TYPE_VPN { return ErrInvalidRecordType } if h.rec != nil { @@ -581,7 +581,7 @@ func (h *VpnHandler) AddRecord(rec *message.ResourceRecord, labels []string) err // Coexist return a flag indicating how a resource record of a given type // is to be treated (see BlockHandler interface) -func (h *VpnHandler) Coexist(cm util.Counter[int]) bool { +func (h *VpnHandler) Coexist(cm util.Counter[enums.GNSType]) bool { // anything goes return true } diff --git a/src/gnunet/service/gns/box.go b/src/gnunet/service/gns/box.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/service/gns/dns.go b/src/gnunet/service/gns/dns.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -46,10 +46,10 @@ var ( //---------------------------------------------------------------------- // RRTypeList is a list of integers representing RR types. -type RRTypeList []int +type RRTypeList []enums.GNSType // NewRRTypeList initializes a new type list with given type values -func NewRRTypeList(args ...int) (res RRTypeList) { +func NewRRTypeList(args ...enums.GNSType) (res RRTypeList) { for _, val := range args { // if GNS_TYPE_ANY is encountered, it becomes the sole type if val == enums.GNS_TYPE_ANY { @@ -74,7 +74,7 @@ func (tl RRTypeList) IsAny() bool { } // HasType returns true if the type is included in the list -func (tl RRTypeList) HasType(t int) bool { +func (tl RRTypeList) HasType(t enums.GNSType) bool { // return true if type is GNS_TYPE_ANY if tl[0] == enums.GNS_TYPE_ANY { return true @@ -164,7 +164,7 @@ func QueryDNS(id int, name string, server net.IP, kind RRTypeList) *message.Reco set := message.NewRecordSet() for _, record := range in.Answer { // check if answer record is of requested type - if kind.HasType(int(record.Header().Rrtype)) { + if kind.HasType(enums.GNSType(record.Header().Rrtype)) { // get wire-format of resource record buf := make([]byte, 2048) n, err := dns.PackRR(record, buf, 0, nil, false) @@ -230,7 +230,7 @@ func (gns *Module) ResolveDNS( // traverse resource records for 'A' and 'AAAA' records. rec_loop: for _, rec := range set.Records { - switch int(rec.Type) { + switch enums.GNSType(rec.Type) { case enums.GNS_TYPE_DNS_AAAA: addr = net.IP(rec.Data) // we prefer IPv6 diff --git a/src/gnunet/service/gns/module.go b/src/gnunet/service/gns/module.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -21,7 +21,6 @@ package gns import ( "context" "fmt" - "net/http" "strings" "gnunet/config" @@ -106,7 +105,6 @@ func NewModule(ctx context.Context, c *core.Core) (m *Module) { // register as listener for core events listener := m.Run(ctx, m.event, m.Filter(), 0, nil) c.Register("gns", listener) - return } @@ -340,7 +338,7 @@ func (m *Module) ResolveRelative( set = message.NewRecordSet() for _, rec := range records { // is this the record type we are looking for? - if kind.HasType(int(rec.Type)) { + if kind.HasType(enums.GNSType(rec.Type)) { // add it to the result if rec = hdlrs.FinalizeRecord(rec); rec != nil { set.AddRecord(rec) @@ -363,7 +361,7 @@ func (m *Module) ResolveRelative( // asking for explicitly. if set.Count > 0 { for _, rec := range records { - if !kind.HasType(int(rec.Type)) && (int(rec.Flags)&enums.GNS_FLAG_SUPPL) != 0 { + if !kind.HasType(enums.GNSType(rec.Type)) && (int(rec.Flags)&enums.GNS_FLAG_SUPPL) != 0 { set.AddRecord(rec) } } @@ -488,12 +486,3 @@ func (m *Module) records(buf []byte) ([]*message.ResourceRecord, error) { } return rs.Records, nil } - -//---------------------------------------------------------------------- - -// RPC returns the route and handler function for a JSON-RPC request -func (m *Module) RPC() (string, func(http.ResponseWriter, *http.Request)) { - return "/gns/", func(wrt http.ResponseWriter, req *http.Request) { - wrt.Write([]byte(`{"msg": "This is GNS" }`)) - } -} diff --git a/src/gnunet/service/gns/rpc.go b/src/gnunet/service/gns/rpc.go @@ -0,0 +1,27 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +package gns + +import "net/rpc" + +//---------------------------------------------------------------------- + +// InitRPC registers RPC commands for the module +func (m *Module) InitRPC(srv *rpc.Server) { +} diff --git a/src/gnunet/service/gns/service.go b/src/gnunet/service/gns/service.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -25,12 +25,14 @@ import ( "io" "gnunet/config" + "gnunet/core" "gnunet/crypto" "gnunet/enums" "gnunet/message" "gnunet/service" "gnunet/service/dht/blocks" "gnunet/service/revocation" + "gnunet/transport" "gnunet/util" "github.com/bfix/gospel/data" @@ -54,15 +56,22 @@ type Service struct { } // NewService creates a new GNS service instance -func NewService() service.Service { - // instantiate service and assemble a new GNS handler. - inst := new(Service) - inst.LookupLocal = inst.LookupNamecache - inst.StoreLocal = inst.StoreNamecache - inst.LookupRemote = inst.LookupDHT - inst.RevocationQuery = inst.QueryKeyRevocation - inst.RevocationRevoke = inst.RevokeKey - return inst +func NewService(ctx context.Context, c *core.Core) service.Service { + // instantiate service + mod := NewModule(ctx, c) + srv := &Service{ + Module: *mod, + } + srv.ProcessFcn = srv.HandleMessage + + // set external function references (external services) + srv.LookupLocal = srv.LookupNamecache + srv.StoreLocal = srv.StoreNamecache + srv.LookupRemote = srv.LookupDHT + srv.RevocationQuery = srv.QueryKeyRevocation + srv.RevocationRevoke = srv.RevokeKey + + return srv } // ServeClient processes a client channel. @@ -100,7 +109,7 @@ func (s *Service) ServeClient(ctx context.Context, id int, mc *service.Connectio } // Handle a single incoming message -func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back service.Responder) bool { +func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back transport.Responder) bool { // assemble log label label := "" if v := ctx.Value("label"); v != nil { @@ -129,7 +138,7 @@ func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back s }() label := m.GetName() - kind := NewRRTypeList(int(m.Type)) + kind := NewRRTypeList(enums.GNSType(m.Type)) recset, err := s.Resolve(ctx, label, m.Zone, kind, int(m.Options), 0) if err != nil { logger.Printf(logger.ERROR, "[gns%s] Failed to lookup block: %s\n", label, err.Error()) @@ -152,7 +161,7 @@ func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back s logger.Printf(logger.DBG, "[gns%s] Record #%d: %v\n", label, i, rec) // is this the record type we are looking for? - if rec.Type == m.Type || int(m.Type) == enums.GNS_TYPE_ANY { + if rec.Type == m.Type || enums.GNSType(m.Type) == enums.GNS_TYPE_ANY { // add it to the response message resp.AddRecord(rec) } @@ -269,7 +278,7 @@ func (s *Service) LookupNamecache(ctx context.Context, query *blocks.GNSQuery) ( block.DerivedKeySig = m.DerivedKeySig sb := new(blocks.SignedGNSBlockData) sb.Purpose = new(crypto.SignaturePurpose) - sb.Purpose.Purpose = enums.SIG_GNS_RECORD_SIGN + sb.Purpose.Purpose = uint32(enums.SIG_GNS_RECORD_SIGN) sb.Purpose.Size = uint32(16 + len(m.EncData)) sb.Expire = m.Expire sb.Data = m.EncData @@ -404,7 +413,7 @@ func (s *Service) LookupDHT(ctx context.Context, query blocks.Query) (block bloc break } // check if result is of requested type - if int(m.Type) != enums.BLOCK_TYPE_GNS_NAMERECORD { + if enums.BlockType(m.Type) != enums.BLOCK_TYPE_GNS_NAMERECORD { logger.Println(logger.ERROR, "[gns] DHT response has wrong type") break } diff --git a/src/gnunet/service/module.go b/src/gnunet/service/module.go @@ -21,7 +21,9 @@ package service import ( "context" "gnunet/core" - "net/http" + "gnunet/message" + "gnunet/transport" + "net/rpc" "time" ) @@ -63,8 +65,8 @@ type Module interface { // Import functions by name Import(map[string]any) - // RPC returns the route and handler for JSON-RPC requests - RPC() (string, func(http.ResponseWriter, *http.Request)) + // InitRPC registers RPC commands for the module + InitRPC(*rpc.Server) // Filter returns the event filter for the module Filter() *core.EventFilter @@ -78,13 +80,18 @@ type Heartbeat func(context.Context) // ModuleImpl is an event-handling type used by Module implementations. type ModuleImpl struct { - ch chan *core.Event // channel for core events. + // channel for core events. + ch chan *core.Event + + // ProcessFcn message: function reference (implemented by service) + ProcessFcn func(ctx context.Context, msg message.Message, back transport.Responder) bool } // NewModuleImplementation returns a new base module and starts func NewModuleImpl() (m *ModuleImpl) { return &ModuleImpl{ - ch: make(chan *core.Event), + ch: make(chan *core.Event), + ProcessFcn: nil, } } @@ -108,7 +115,8 @@ func (m *ModuleImpl) Run( select { // Handle events case event := <-m.ch: - hdlr(ctx, event) + hCtx := context.WithValue(ctx, "label", event.Label) + hdlr(hCtx, event) // wait for terminate signal case <-ctx.Done(): diff --git a/src/gnunet/service/namecache/module.go b/src/gnunet/service/namecache/module.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/service/revocation/module.go b/src/gnunet/service/revocation/module.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/service/revocation/pow.go b/src/gnunet/service/revocation/pow.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -158,7 +158,7 @@ func (rd *RevData) Sign(skey *crypto.ZonePrivate) (err error) { sigBlock := &SignedRevData{ Purpose: &crypto.SignaturePurpose{ Size: uint32(20 + rd.ZoneKeySig.KeySize()), - Purpose: enums.SIG_REVOCATION, + Purpose: uint32(enums.SIG_REVOCATION), }, Timestamp: rd.Timestamp, ZoneKey: &rd.ZoneKeySig.ZoneKey, @@ -180,7 +180,7 @@ func (rd *RevData) Verify(withSig bool) (zbits float64, rc int) { sigBlock := &SignedRevData{ Purpose: &crypto.SignaturePurpose{ Size: uint32(20 + rd.ZoneKeySig.KeySize()), - Purpose: enums.SIG_REVOCATION, + Purpose: uint32(enums.SIG_REVOCATION), }, Timestamp: rd.Timestamp, ZoneKey: &rd.ZoneKeySig.ZoneKey, diff --git a/src/gnunet/service/revocation/pow_test.go b/src/gnunet/service/revocation/pow_test.go @@ -118,7 +118,7 @@ func TestRevocationRFC(t *testing.T) { sigBlock := &SignedRevData{ Purpose: &crypto.SignaturePurpose{ Size: uint32(20 + revData.ZoneKeySig.KeySize()), - Purpose: enums.SIG_REVOCATION, + Purpose: uint32(enums.SIG_REVOCATION), }, Timestamp: revData.Timestamp, ZoneKey: &revData.ZoneKeySig.ZoneKey, diff --git a/src/gnunet/service/revocation/rpc.go b/src/gnunet/service/revocation/rpc.go @@ -0,0 +1,27 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +package revocation + +import "net/rpc" + +//---------------------------------------------------------------------- + +// InitRPC registers RPC commands for the module +func (m *Module) InitRPC(srv *rpc.Server) { +} diff --git a/src/gnunet/service/revocation/service.go b/src/gnunet/service/revocation/service.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -23,8 +23,10 @@ import ( "fmt" "io" + "gnunet/core" "gnunet/message" "gnunet/service" + "gnunet/transport" "github.com/bfix/gospel/logger" ) @@ -39,10 +41,14 @@ type Service struct { } // NewService creates a new revocation service instance -func NewService() service.Service { - // instantiate service and assemble a new Revocation handler. - inst := new(Service) - return inst +func NewService(ctx context.Context, c *core.Core) service.Service { + // instantiate service + mod := NewModule(ctx, c) + srv := &Service{ + Module: *mod, + } + srv.ProcessFcn = srv.HandleMessage + return srv } // ServeClient processes a client channel. @@ -80,7 +86,7 @@ func (s *Service) ServeClient(ctx context.Context, id int, mc *service.Connectio } // Handle a single incoming message -func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back service.Responder) bool { +func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back transport.Responder) bool { // assemble log label label := "" if v := ctx.Value("label"); v != nil { diff --git a/src/gnunet/service/rpc.go b/src/gnunet/service/rpc.go @@ -0,0 +1,66 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2019-2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +package service + +import ( + "context" + "net/http" + "net/rpc" + "time" + + "github.com/bfix/gospel/logger" + "github.com/gorilla/mux" +) + +//---------------------------------------------------------------------- +// JSON-RPC interface for services to be used as the primary client API +// for perform, manage and monitor GNUnet activities. +//---------------------------------------------------------------------- + +// StartRPC the JSON-RPC server. It can be terminated by context +func StartRPC(ctx context.Context, endpoint string) (srvRPC *rpc.Server, err error) { + + // setup RPC request handler + router := mux.NewRouter() + srvRPC = rpc.NewServer() + router.HandleFunc("/", srvRPC.ServeHTTP) + + // instantiate a server and run it + srv := &http.Server{ + Handler: router, + Addr: endpoint, + WriteTimeout: 15 * time.Second, + ReadTimeout: 15 * time.Second, + } + go func() { + // start listening + go func() { + if err := srv.ListenAndServe(); err != nil { + logger.Printf(logger.WARN, "[RPC] Server listen failed: %s", err.Error()) + } + }() + select { + case <-ctx.Done(): + if err := srv.Shutdown(context.Background()); err != nil { + logger.Printf(logger.WARN, "[RPC] Server shutdownn failed: %s", err.Error()) + } + } + }() + return +} diff --git a/src/gnunet/service/service.go b/src/gnunet/service/service.go @@ -20,9 +20,9 @@ package service import ( "context" - "errors" "fmt" "gnunet/message" + "gnunet/transport" "gnunet/util" "github.com/bfix/gospel/logger" @@ -30,31 +30,6 @@ import ( //---------------------------------------------------------------------- -// Responder is a back-channel for messages generated during -// message processing. The Connection type is a responder -// and used as such in ServeClient(). -type Responder interface { - // Handle outgoing message - Send(ctx context.Context, msg message.Message) error -} - -// TransportResponder is used as a responder in message handling for -// messages received from Transport. -type TransportResponder struct { - Peer *util.PeerID - SendFcn func(context.Context, *util.PeerID, message.Message) error -} - -// Send a message back to caller. -func (r *TransportResponder) Send(ctx context.Context, msg message.Message) error { - if r.SendFcn == nil { - return errors.New("no send function defined") - } - return r.SendFcn(ctx, r.Peer, msg) -} - -//---------------------------------------------------------------------- - // Service is an interface for GNUnet services type Service interface { Module @@ -67,7 +42,7 @@ type Service interface { // Handle a single incoming message (either locally from a socket // connection or from Transport). Response messages can be send // via a Responder. Returns true if message was processed. - HandleMessage(ctx context.Context, msg message.Message, resp Responder) bool + HandleMessage(ctx context.Context, msg message.Message, resp transport.Responder) bool } // SocketHandler handles incoming connections on the local service socket. diff --git a/src/gnunet/service/store.go b/src/gnunet/service/store.go @@ -79,7 +79,7 @@ type KVStore Store[string, string] // NewDHTStore creates a new storage handler with given spec // for use with DHT queries and blocks func NewDHTStore(spec string) (DHTStore, error) { - specs := strings.SplitN(spec, ":", 2) + specs := strings.Split(spec, ":") if len(specs) < 2 { return nil, ErrStoreInvalidSpec } diff --git a/src/gnunet/test/gnunet-dhtu/main.go b/src/gnunet/test/gnunet-dhtu/main.go @@ -0,0 +1,218 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +package main + +import ( + "context" + "encoding/hex" + "flag" + "fmt" + "gnunet/config" + "gnunet/core" + "gnunet/service" + "gnunet/service/dht" + "gnunet/util" + "log" + "net/rpc" + "time" + + "github.com/bfix/gospel/logger" +) + +//---------------------------------------------------------------------- +// Test Go node with DHTU GNUnet nodes +//---------------------------------------------------------------------- + +func main() { + // handle command-line arguments + var ( + remoteId string + remoteAddr string + cfgFile string + ) + flag.StringVar(&cfgFile, "c", "gnunet-config.json", "configuration file") + flag.StringVar(&remoteId, "i", "", "peer id of remote node") + flag.StringVar(&remoteAddr, "a", "", "address of remote node") + flag.Parse() + + // read configuration file and set missing arguments. + if err := config.ParseConfig(cfgFile); err != nil { + logger.Printf(logger.ERROR, "[gnunet-dhtu] Invalid configuration file: %s\n", err.Error()) + return + } + + // convert arguments + var ( + rId *util.PeerID + rAddr *util.Address + buf []byte + err error + ) + if rAddr, err = util.ParseAddress(remoteAddr); err != nil { + log.Fatal(err) + } + if len(remoteId) > 0 { + if buf, err = util.DecodeStringToBinary(remoteId, 32); err != nil { + log.Fatal(err) + } + rId = util.NewPeerID(buf) + } + + // setup execution context + ctx, cancel := context.WithCancel(context.Background()) + defer func() { + cancel() + time.Sleep(time.Second) + }() + + // create and run node + node, err := NewTestNode(ctx) + if err != nil { + log.Fatal(err) + } + defer node.Shutdown() + + // show our HELLO URL + ep := config.Cfg.Local.Endpoints[0] + as := fmt.Sprintf("%s://%s:%d", ep.Network, ep.Address, ep.Port) + listen, err := util.ParseAddress(as) + if err != nil { + log.Fatal(err) + } + aList := []*util.Address{listen} + logger.Println(logger.INFO, "HELLO: "+node.HelloURL(aList)) + + // learn bootstrap address (triggers HELLO) + node.Learn(ctx, rId, rAddr) + + // run forever + var ch chan struct{} + <-ch +} + +//---------------------------------------------------------------------- +// create and run a node with given spec +//---------------------------------------------------------------------- + +type TestNode struct { + id int + peer *core.Peer + core *core.Core + addr *util.Address +} + +func (n *TestNode) Shutdown() { + n.core.Shutdown() +} +func (n *TestNode) HelloURL(a []*util.Address) string { + hd, err := n.peer.HelloData(time.Hour, a) + if err != nil { + return "" + } + return hd.URL() +} + +func (n *TestNode) Learn(ctx context.Context, peer *util.PeerID, addr *util.Address) { + label := "@" + if peer != nil { + label = peer.String() + } + log.Printf("[%d] Learning %s for %s", n.id, addr.StringAll(), label) + if err := n.core.Learn(ctx, peer, addr); err != nil { + log.Println("Learn: " + err.Error()) + } +} + +func NewTestNode(ctx context.Context) (node *TestNode, err error) { + + // create test node + node = new(TestNode) + node.id = util.NextID() + + // create core service + if node.core, err = core.NewCore(ctx, config.Cfg.Local); err != nil { + return + } + node.peer = node.core.Peer() + log.Printf("[%d] Node %s starting", node.id, node.peer.GetID()) + log.Printf("[%d] --> %s", node.id, hex.EncodeToString(node.peer.GetID().Key)) + + // start a new DHT service + dht, err := dht.NewService(ctx, node.core) + if err != nil { + log.Fatal(err) + } + + // start JSON-RPC server on request + var rpc *rpc.Server + if rpc, err = service.StartRPC(ctx, config.Cfg.RPC.Endpoint); err != nil { + logger.Printf(logger.ERROR, "[gnunet-dhtu] RPC failed to start: %s", err.Error()) + return + } + dht.InitRPC(rpc) + + // start listening on the network + list, err := node.core.Addresses() + if err != nil { + log.Fatal(err) + } + for _, addr := range list { + s := addr.Network() + "://" + addr.String() + if node.addr, err = util.ParseAddress(s); err != nil { + continue + } + log.Printf("[%d] Listening on %s", node.id, s) + } + + // register as event listener + incoming := make(chan *core.Event) + node.core.Register(config.Cfg.Local.Name, core.NewListener(incoming, nil)) + + // heart beat + tick := time.NewTicker(5 * time.Minute) + + // run event handler + go func() { + for { + select { + // show incoming event + case ev := <-incoming: + switch ev.ID { + case core.EV_CONNECT: + log.Printf("[%d] <<< Peer %s connected", node.id, ev.Peer) + case core.EV_DISCONNECT: + log.Printf("[%d] <<< Peer %s diconnected", node.id, ev.Peer) + case core.EV_MESSAGE: + log.Printf("[%d] <<< Msg from %s of type %d", node.id, ev.Peer, ev.Msg.Header().MsgType) + log.Printf("[%d] <<< --> %s", node.id, ev.Msg.String()) + } + + // handle termination signal + case <-ctx.Done(): + log.Printf("[%d] Shutting down node", node.id) + return + + // handle heart beat + case now := <-tick.C: + log.Printf("[%d] Heart beat at %s", node.id, now.String()) + } + } + }() + return +} diff --git a/src/gnunet/transport/endpoint.go b/src/gnunet/transport/endpoint.go @@ -107,6 +107,8 @@ func (ep *PaketEndpoint) Run(ctx context.Context, hdlr chan *TransportMessage) ( if err != nil { break } + // label message + tm.Label = ep.addr.String() // send transport message to handler go func() { hdlr <- tm @@ -143,8 +145,10 @@ func (ep *PaketEndpoint) read() (tm *TransportMessage, err error) { } // return transport message return &TransportMessage{ - Peer: peer, - Msg: msg, + Peer: peer, + Msg: msg, + Resp: nil, + Label: "", }, nil } diff --git a/src/gnunet/transport/responder.go b/src/gnunet/transport/responder.go @@ -0,0 +1,52 @@ +// This file is part of gnunet-go, a GNUnet-implementation in Golang. +// Copyright (C) 2022 Bernd Fix >Y< +// +// gnunet-go 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-go 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 + +package transport + +import ( + "context" + "errors" + "gnunet/message" + "gnunet/util" +) + +//---------------------------------------------------------------------- +// Responder is a back-channel for messages generated during +// message processing. The Connection type is a responder +// and used as such in ServeClient(). +type Responder interface { + // Handle outgoing message + Send(ctx context.Context, msg message.Message) error +} + +//---------------------------------------------------------------------- +// TransportResponder is used as a responder in message handling for +// messages received from Transport. It is used by Endpoint instances +// to define custom responders for messages received. +type TransportResponder struct { + Peer *util.PeerID + SendFcn func(context.Context, *util.PeerID, message.Message) error +} + +// Send a message back to caller. The specifics are handled in the callback. +func (r *TransportResponder) Send(ctx context.Context, msg message.Message) error { + if r.SendFcn == nil { + return errors.New("no send function defined") + } + return r.SendFcn(ctx, r.Peer, msg) +} diff --git a/src/gnunet/transport/transport.go b/src/gnunet/transport/transport.go @@ -43,8 +43,22 @@ var ( // Msg is the exchanged GNUnet message. The packet itself satisfies the // message.Message interface. type TransportMessage struct { - Peer *util.PeerID // remote peer - Msg message.Message // GNUnet message + // Peer is a identifier for a remote peer + Peer *util.PeerID + + // Msg is a generic GNnet message + Msg message.Message + + // Non-serialized (transient) attributes: + + // Resp is an optional custom endpoint responder that can be set by + // endpoints for messages received from the internet if they want to + // handle responses directly (instead of core/transport/endpoint + // resolving the return path). Set to nil if not used. + Resp Responder + + // Label for log messages during message processing + Label string } // Bytes returns the binary representation of a transport message @@ -70,8 +84,10 @@ func NewTransportMessage(peer *util.PeerID, msg message.Message) (tm *TransportM peer = util.NewPeerID(nil) } tm = &TransportMessage{ - Peer: peer, - Msg: msg, + Peer: peer, + Msg: msg, + Resp: nil, + Label: "", } return } @@ -109,13 +125,24 @@ func (t *Transport) Shutdown() { // Send a message over suitable endpoint func (t *Transport) Send(ctx context.Context, addr net.Addr, msg *TransportMessage) (err error) { - // use the first endpoint able to handle address - return t.endpoints.ProcessRange(func(_ int, ep Endpoint) error { + // select best endpoint able to handle address + var bestEp Endpoint + err = t.endpoints.ProcessRange(func(_ int, ep Endpoint) error { if ep.CanSendTo(addr) { - return ep.Send(ctx, addr, msg) + if bestEp == nil { + bestEp = ep + } + // TODO: compare endpoints, select better one: + // if ep.Better(bestEp) { + // bestEp = ep + // } } return nil }, true) + if err != nil { + return + } + return bestEp.Send(ctx, addr, msg) } //---------------------------------------------------------------------- diff --git a/src/gnunet/util/address.go b/src/gnunet/util/address.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/array.go b/src/gnunet/util/array.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -120,3 +120,15 @@ func StringList(b []byte) []string { } return res } + +// ReadCString reads a \0-terminate string from a buffer starting at the +// specified position. Returns the string and the new position (-1 for end +// of buffer reached) +func ReadCString(buf []byte, pos int) (string, int) { + for idx := pos; idx < len(buf); idx++ { + if buf[idx] == 0 { + return string(buf[pos:idx]), idx + 1 + } + } + return "", -1 +} diff --git a/src/gnunet/util/base32.go b/src/gnunet/util/base32.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/base32_test.go b/src/gnunet/util/base32_test.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/database.go b/src/gnunet/util/database.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/format.go b/src/gnunet/util/format.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/fs.go b/src/gnunet/util/fs.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/id.go b/src/gnunet/util/id.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/misc.go b/src/gnunet/util/misc.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/peer_id.go b/src/gnunet/util/peer_id.go @@ -18,7 +18,11 @@ package util -import "bytes" +import ( + "bytes" + + "github.com/bfix/gospel/crypto/ed25519" +) // PeerID is the 32-byte binary representation od a Ed25519 key type PeerID struct { @@ -49,3 +53,7 @@ func (p *PeerID) Equals(q *PeerID) bool { func (p *PeerID) String() string { return EncodeBinaryToString(p.Key) } + +func (p *PeerID) PublicKey() *ed25519.PublicKey { + return ed25519.NewPublicKeyFromBytes(p.Key) +} diff --git a/src/gnunet/util/rnd.go b/src/gnunet/util/rnd.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published diff --git a/src/gnunet/util/time.go b/src/gnunet/util/time.go @@ -1,5 +1,5 @@ // This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019, 2020 Bernd Fix >Y< +// Copyright (C) 2019-2022 Bernd Fix >Y< // // gnunet-go is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published @@ -28,7 +28,7 @@ import ( //---------------------------------------------------------------------- // AbsoluteTime refers to a unique point in time. -// The value is the elapsed time in milliseconds (Unix epoch), so no timestamp +// The value is the elapsed time in microseconds (Unix epoch), so no timestamp // before January 1st, 1970 is possible (not a restriction for GNUnet). type AbsoluteTime struct { Val uint64 `order:"big"` diff --git a/test.sh b/test.sh @@ -1,4 +0,0 @@ -#!/bin/bash - -cd src/gnunet/ -go test $* -gcflags "-N -l" ./...