GNUnet 0.25.0
 
Loading...
Searching...
No Matches
plugin_gnsrecord_gns.c File Reference

gnsrecord plugin to provide the API for fundamental GNS records This includes the VPN record because GNS resolution is expected to understand VPN records and (if needed) map the result to A/AAAA. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_gnsrecord_plugin.h"
#include <inttypes.h>
Include dependency graph for plugin_gnsrecord_gns.c:

Go to the source code of this file.

Functions

static char * gns_value_to_string (void *cls, uint32_t type, const void *data, size_t data_size)
 Convert the 'value' of a record to a string.
 
static int gns_string_to_value (void *cls, uint32_t type, const char *s, void **data, size_t *data_size)
 Convert human-readable version of a 'value' of a record to the binary representation.
 
static uint32_t gns_typename_to_number (void *cls, const char *gns_typename)
 Convert a type name (e.g.
 
static const char * gns_number_to_typename (void *cls, uint32_t type)
 Convert a type number to the corresponding type string (e.g.
 
static enum GNUNET_GenericReturnValue gns_is_critical (void *cls, uint32_t type)
 
void * libgnunet_plugin_gnsrecord_gns_init (void *cls)
 Entry point for the plugin.
 
void * libgnunet_plugin_gnsrecord_gns_done (void *cls)
 Exit point from the plugin.
 

Variables

struct { 
 
   const char *   name 
 
   uint32_t   number 
 
gns_name_map [] 
 Mapping of record type numbers to human-readable record type names.
 

Detailed Description

gnsrecord plugin to provide the API for fundamental GNS records This includes the VPN record because GNS resolution is expected to understand VPN records and (if needed) map the result to A/AAAA.

Author
Christian Grothoff

Definition in file plugin_gnsrecord_gns.c.

Function Documentation

◆ gns_value_to_string()

static char * gns_value_to_string ( void *  cls,
uint32_t  type,
const void *  data,
size_t  data_size 
)
static

Convert the 'value' of a record to a string.

Parameters
clsclosure, unused
typetype of the record
datavalue in binary encoding
data_sizenumber of bytes in data
Returns
NULL on error, otherwise human-readable representation of the value

Definition at line 46 of file plugin_gnsrecord_gns.c.

50{
51 const char *cdata;
53
54 switch (type)
55 {
58 if (GNUNET_OK !=
61 type,
62 &pk))
63 return NULL;
65
70
71 // See https://www.rfc-editor.org/rfc/rfc9498.html#name-gns2dns
73 const char *name;
74 const char *dns_server_name;
75 char *nstr;
76
77 name = (const char *) data;
78 /* DNS server IP/name must be UTF-8 */
79 dns_server_name = name + strlen (name) + 1;
80 GNUNET_asprintf (&nstr, "%s@%s", name, dns_server_name);
81 return nstr;
82 }
83
85 struct GNUNET_TUN_GnsVpnRecord vpn;
86 char *vpn_str;
87
88 cdata = data;
89 if ((data_size <= sizeof(vpn)) || ('\0' != cdata[data_size - 1]))
90 return NULL; /* malformed */
91 /* need to memcpy for alignment */
92 GNUNET_memcpy (&vpn, data, sizeof(vpn));
93 GNUNET_asprintf (&vpn_str,
94 "%u %s %s",
95 (unsigned int) ntohs (vpn.proto),
96 (const char *) GNUNET_i2s_full (&vpn.peer),
97 (const char *) &cdata[sizeof(vpn)]);
98 return vpn_str;
99 }
100
103 uint32_t rt;
104 char *box_str;
105 char *ival;
106
107 cdata = data;
108 if (data_size < sizeof(struct GNUNET_GNSRECORD_BoxRecord))
109 return NULL; /* malformed */
110 GNUNET_memcpy (&box, data, sizeof(box));
111 rt = ntohl (box.record_type);
113 &cdata[sizeof(box)],
114 data_size - sizeof(box));
115 if (NULL == ival)
116 return NULL; /* malformed */
117 GNUNET_asprintf (&box_str,
118 "%u %u %u %s",
119 (unsigned int) ntohs (box.protocol),
120 (unsigned int) ntohs (box.service),
121 (unsigned int) rt,
122 ival);
123 GNUNET_free (ival);
124 return box_str;
125 }
128 uint32_t rt;
129 char *box_str;
130 char *ival;
131 char *prefix;
132
133 cdata = data;
134 if (data_size < sizeof(struct GNUNET_GNSRECORD_SBoxRecord))
135 return NULL; /* malformed */
136 GNUNET_memcpy (&box, data, sizeof(box));
137 rt = ntohl (box.record_type);
138
139 prefix = GNUNET_strdup (&cdata[sizeof(box)]);
140 ival = GNUNET_GNSRECORD_value_to_string (rt, &cdata[sizeof(box)
141 + strlen (prefix)
142 + 1],
143 data_size - sizeof(box)
144 - strlen (prefix) - 1);
145 if (NULL == ival)
146 return NULL; /* malformed */
147 GNUNET_asprintf (&box_str,
148 "%s %u %s",
149 prefix,
150 (unsigned int) rt,
151 ival);
153 GNUNET_free (ival);
154 return box_str;
155 }
157 return GNUNET_strdup (_ (
158 "This is a memento of an older block for internal maintenance."));
159 }
160 default:
161 return NULL;
162 }
163}
#define GNUNET_GNSRECORD_TYPE_BOX
Box record.
#define GNUNET_GNSRECORD_TYPE_NICK
GNS zone nickname.
#define GNUNET_GNSRECORD_TYPE_TOMBSTONE
Record type to indicate a previously delete record (PRIVATE only)
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Delegation to DNS.
#define GNUNET_GNSRECORD_TYPE_REDIRECT
Redirection record.
#define GNUNET_GNSRECORD_TYPE_VPN
VPN resolution.
#define GNUNET_GNSRECORD_TYPE_LEHO
GNS legacy hostname.
#define GNUNET_GNSRECORD_TYPE_SBOX
SBox record.
#define GNUNET_GNSRECORD_TYPE_PKEY
WARNING: This header is generated! In order to add GNS record types, you must register them in GANA,...
#define GNUNET_GNSRECORD_TYPE_EDKEY
GNS zone delegation (EDKEY)
static int prefix
If printing the value of PREFIX has been requested.
static char * data
The data to insert into the dht.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static uint32_t type
Type string converted to DNS type value.
static size_t data_size
Number of bytes in data.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_CRYPTO_PublicKey *key)
Build a #GNUNET_GNSRECORD_PublicKey from zone delegation resource record data.
char * GNUNET_GNSRECORD_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the binary value data of a record of type type to a human-readable string.
Definition gnsrecord.c:147
char * GNUNET_CRYPTO_public_key_to_string(const struct GNUNET_CRYPTO_PublicKey *key)
Creates a (Base32) string representation of the public key.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_free(ptr)
Wrapper around free.
#define _(String)
GNU gettext support macro.
Definition platform.h:179
const char * name
An identity key as per LSD0001.
Record type used to box up SRV and TLSA records.
Record type used to box up SMIMEA records.
Payload of GNS VPN record.

References _, data, data_size, GNUNET_asprintf(), GNUNET_CRYPTO_public_key_to_string(), GNUNET_free, GNUNET_GNSRECORD_identity_from_data(), GNUNET_GNSRECORD_TYPE_BOX, GNUNET_GNSRECORD_TYPE_EDKEY, GNUNET_GNSRECORD_TYPE_GNS2DNS, GNUNET_GNSRECORD_TYPE_LEHO, GNUNET_GNSRECORD_TYPE_NICK, GNUNET_GNSRECORD_TYPE_PKEY, GNUNET_GNSRECORD_TYPE_REDIRECT, GNUNET_GNSRECORD_TYPE_SBOX, GNUNET_GNSRECORD_TYPE_TOMBSTONE, GNUNET_GNSRECORD_TYPE_VPN, GNUNET_GNSRECORD_value_to_string(), GNUNET_i2s_full(), GNUNET_memcpy, GNUNET_OK, GNUNET_strdup, GNUNET_strndup, name, GNUNET_TUN_GnsVpnRecord::peer, pk, prefix, GNUNET_TUN_GnsVpnRecord::proto, GNUNET_GNSRECORD_BoxRecord::protocol, GNUNET_GNSRECORD_BoxRecord::record_type, GNUNET_GNSRECORD_SBoxRecord::record_type, GNUNET_GNSRECORD_BoxRecord::service, and type.

Referenced by libgnunet_plugin_gnsrecord_gns_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ gns_string_to_value()

static int gns_string_to_value ( void *  cls,
uint32_t  type,
const char *  s,
void **  data,
size_t *  data_size 
)
static

Convert human-readable version of a 'value' of a record to the binary representation.

Parameters
clsclosure, unused
typetype of the record
shuman-readable string
dataset to value in binary encoding (will be allocated)
data_sizeset to number of bytes in data
Returns
GNUNET_OK on success

Definition at line 178 of file plugin_gnsrecord_gns.c.

183{
185 uint32_t record_type;
186
187 if (NULL == s)
188 return GNUNET_SYSERR;
189 switch (type)
190 {
193 if (GNUNET_OK !=
195 {
197 _ ("Unable to parse zone key record `%s'\n"),
198 s);
199 return GNUNET_SYSERR;
200 }
202 if (GNUNET_OK !=
204 (char **) data,
205 data_size,
206 &record_type))
207 return GNUNET_SYSERR;
208 if (record_type != type)
209 {
211 _ ("Record type does not match parsed record type\n"));
212 return GNUNET_SYSERR;
213 }
214 return GNUNET_OK;
215
219 *data = GNUNET_strdup (s);
220 *data_size = strlen (s);
221 return GNUNET_OK;
222
223 // See https://www.rfc-editor.org/rfc/rfc9498.html#name-gns2dns
225 char *cpy;
226 char *at;
227
228 cpy = GNUNET_strdup (s);
229 at = strchr (cpy, '@');
230 if (NULL == at)
231 {
233 _ ("Unable to parse GNS2DNS record `%s'\n"),
234 s);
235 GNUNET_free (cpy);
236 return GNUNET_SYSERR;
237 }
238 *at = '\0';
239 at++;
240
241 /* The DNS server location/name is in UTF-8 */
242 *data_size = strlen (s) + 1;
243 *data = cpy;
244 return GNUNET_OK;
245 }
246
248 struct GNUNET_TUN_GnsVpnRecord *vpn;
249 char s_peer[103 + 1];
250 char s_serv[253 + 1];
251 unsigned int proto;
252
253 if (3 != sscanf (s, "%u %103s %253s", &proto, s_peer, s_serv))
254 {
256 _ ("Unable to parse VPN record string `%s'\n"),
257 s);
258 return GNUNET_SYSERR;
259 }
260 *data_size = sizeof(struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1;
261 *data = vpn = GNUNET_malloc (*data_size);
262 if (GNUNET_OK !=
264 strlen (s_peer),
265 &vpn->peer.public_key))
266 {
267 GNUNET_free (vpn);
268 *data_size = 0;
269 return GNUNET_SYSERR;
270 }
271 vpn->proto = htons ((uint16_t) proto);
272 strcpy ((char *) &vpn[1], s_serv);
273 return GNUNET_OK;
274 }
275
277 struct GNUNET_GNSRECORD_BoxRecord *box;
278 size_t rest;
279 unsigned int protocol;
280 unsigned int service;
281 unsigned int rrtype;
282 void *bval;
283 size_t bval_size;
284
285 if (3 != sscanf (s, "%u %u %u ", &protocol, &service, &rrtype))
286 {
288 _ ("Unable to parse BOX record string `%s'\n"),
289 s);
290 return GNUNET_SYSERR;
291 }
292 rest = snprintf (NULL, 0, "%u %u %u ", protocol, service, rrtype);
294 &s[rest],
295 &bval,
296 &bval_size))
297 return GNUNET_SYSERR;
298 *data_size = sizeof(struct GNUNET_GNSRECORD_BoxRecord) + bval_size;
299 *data = box = GNUNET_malloc (*data_size);
300 box->protocol = htons (protocol);
301 box->service = htons (service);
302 box->record_type = htonl (rrtype);
303 GNUNET_memcpy (&box[1], bval, bval_size);
304 GNUNET_free (bval);
305 return GNUNET_OK;
306 }
308 struct GNUNET_GNSRECORD_SBoxRecord *box;
309 size_t rest;
310 char *prefix;
311 char *p;
312 char *underscore_prefix;
313 unsigned int rrtype;
314 void *bval;
315 size_t bval_size;
316 size_t prefix_size;
317
318 prefix = GNUNET_malloc (strlen (s) + 1);
319 if (2 != sscanf (s, "%s %u ", prefix, &rrtype))
320 {
322 _ ("Unable to parse SBOX record string `%s'\n"),
323 s);
325 return GNUNET_SYSERR;
326 }
327 underscore_prefix = strrchr (prefix, '.');
328 if (underscore_prefix == NULL)
329 {
330 underscore_prefix = prefix;
331 }
332 else
333 {
334 underscore_prefix++;
335 }
336 if ('_' != underscore_prefix[0])
337 {
339 _ (
340 "Unable to parse SBOX record string `%s', the rightmost label `%s' does not start with an underscore\n"),
341 prefix, underscore_prefix);
343 return GNUNET_SYSERR;
344 }
345 rest = snprintf (NULL, 0, "%s %u ", prefix, rrtype);
347 &s[rest],
348 &bval,
349 &bval_size))
350 {
352 return GNUNET_SYSERR;
353 }
354 prefix_size = strlen (prefix) + 1;
355 *data_size = sizeof(struct GNUNET_GNSRECORD_SBoxRecord) + prefix_size
356 + bval_size;
358 p = *data;
359 box = *data;
360 box->record_type = htonl (rrtype);
361 p += sizeof(struct GNUNET_GNSRECORD_SBoxRecord);
362 GNUNET_memcpy (p, prefix, prefix_size);
363 p += prefix_size;
364 GNUNET_memcpy (p, bval, bval_size);
365 GNUNET_free (bval);
367 return GNUNET_OK;
368 }
370 *data_size = 0;
371 *data = NULL;
372 return GNUNET_OK;
373 }
374
375 default:
376 return GNUNET_SYSERR;
377 }
378}
static uint8_t proto
Protocol to use.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
int GNUNET_GNSRECORD_string_to_value(uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of the value s of a record of type type to the respective binary repre...
Definition gnsrecord.c:169
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_data_from_identity(const struct GNUNET_CRYPTO_PublicKey *key, char **data, size_t *data_size, uint32_t *type)
Create record data and size from an identity key.
ssize_t GNUNET_CRYPTO_public_key_get_length(const struct GNUNET_CRYPTO_PublicKey *key)
Get the compacted length of a GNUNET_CRYPTO_PublicKey.
Definition crypto_pkey.c:85
#define GNUNET_log(kind,...)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition crypto_ecc.c:361
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_public_key_from_string(const char *str, struct GNUNET_CRYPTO_PublicKey *key)
Parses a (Base32) string representation of the public key.
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_malloc(size)
Wrapper around malloc.
uint32_t record_type
GNS record type of the boxed record.
uint16_t service
Service of the boxed record (aka port number), in NBO.
uint16_t protocol
Protocol of the boxed record (6 = TCP, 17 = UDP, etc.).
uint32_t record_type
GNS record type of the boxed record.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
struct GNUNET_PeerIdentity peer
The peer to contact.
uint16_t proto
The protocol to use.

References _, data, data_size, GNUNET_CRYPTO_eddsa_public_key_from_string(), GNUNET_CRYPTO_public_key_from_string(), GNUNET_CRYPTO_public_key_get_length(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_GNSRECORD_data_from_identity(), GNUNET_GNSRECORD_string_to_value(), GNUNET_GNSRECORD_TYPE_BOX, GNUNET_GNSRECORD_TYPE_EDKEY, GNUNET_GNSRECORD_TYPE_GNS2DNS, GNUNET_GNSRECORD_TYPE_LEHO, GNUNET_GNSRECORD_TYPE_NICK, GNUNET_GNSRECORD_TYPE_PKEY, GNUNET_GNSRECORD_TYPE_REDIRECT, GNUNET_GNSRECORD_TYPE_SBOX, GNUNET_GNSRECORD_TYPE_TOMBSTONE, GNUNET_GNSRECORD_TYPE_VPN, GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_OK, GNUNET_strdup, GNUNET_SYSERR, p, GNUNET_TUN_GnsVpnRecord::peer, pk, prefix, proto, GNUNET_TUN_GnsVpnRecord::proto, GNUNET_GNSRECORD_BoxRecord::protocol, GNUNET_PeerIdentity::public_key, GNUNET_GNSRECORD_BoxRecord::record_type, GNUNET_GNSRECORD_SBoxRecord::record_type, GNUNET_GNSRECORD_BoxRecord::service, service, and type.

Referenced by libgnunet_plugin_gnsrecord_gns_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ gns_typename_to_number()

static uint32_t gns_typename_to_number ( void *  cls,
const char *  gns_typename 
)
static

Convert a type name (e.g.

"AAAA") to the corresponding number.

Parameters
clsclosure, unused
gns_typenamename to convert
Returns
corresponding number, UINT32_MAX on error

Definition at line 414 of file plugin_gnsrecord_gns.c.

416{
417 unsigned int i;
418
419 i = 0;
420 while ((NULL != gns_name_map[i].name) &&
421 (0 != strcasecmp (gns_typename, gns_name_map[i].name)))
422 i++;
423 return gns_name_map[i].number;
424}
static struct @37 gns_name_map[]
Mapping of record type numbers to human-readable record type names.

References gns_name_map, and name.

Referenced by libgnunet_plugin_gnsrecord_gns_init().

Here is the caller graph for this function:

◆ gns_number_to_typename()

static const char * gns_number_to_typename ( void *  cls,
uint32_t  type 
)
static

Convert a type number to the corresponding type string (e.g.

1 to "A")

Parameters
clsclosure, unused
typenumber of a type to convert
Returns
corresponding typestring, NULL on error

Definition at line 435 of file plugin_gnsrecord_gns.c.

437{
438 unsigned int i;
439
440 i = 0;
441 while ( (NULL != gns_name_map[i].name) &&
442 (type != gns_name_map[i].number) )
443 i++;
444 return gns_name_map[i].name;
445}
uint32_t number

References gns_name_map, name, number, and type.

Referenced by libgnunet_plugin_gnsrecord_gns_init().

Here is the caller graph for this function:

◆ gns_is_critical()

static enum GNUNET_GenericReturnValue gns_is_critical ( void *  cls,
uint32_t  type 
)
static

Definition at line 449 of file plugin_gnsrecord_gns.c.

References GNUNET_GNSRECORD_TYPE_EDKEY, GNUNET_GNSRECORD_TYPE_GNS2DNS, GNUNET_GNSRECORD_TYPE_PKEY, GNUNET_GNSRECORD_TYPE_REDIRECT, GNUNET_NO, GNUNET_YES, and type.

Referenced by libgnunet_plugin_gnsrecord_gns_init().

Here is the caller graph for this function:

◆ libgnunet_plugin_gnsrecord_gns_init()

void * libgnunet_plugin_gnsrecord_gns_init ( void *  cls)

Entry point for the plugin.

Parameters
clsNULL
Returns
the exported block API

Definition at line 469 of file plugin_gnsrecord_gns.c.

470{
472
479 return api;
480}
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static char * gns_value_to_string(void *cls, uint32_t type, const void *data, size_t data_size)
Convert the 'value' of a record to a string.
static int gns_string_to_value(void *cls, uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of a 'value' of a record to the binary representation.
static const char * gns_number_to_typename(void *cls, uint32_t type)
Convert a type number to the corresponding type string (e.g.
static uint32_t gns_typename_to_number(void *cls, const char *gns_typename)
Convert a type name (e.g.
static enum GNUNET_GenericReturnValue gns_is_critical(void *cls, uint32_t type)
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
GNUNET_GNSRECORD_IsCriticalFunction is_critical
Is critical.
GNUNET_GNSRECORD_TypenameToNumberFunction typename_to_number
Typename to number.
GNUNET_GNSRECORD_NumberToTypenameFunction number_to_typename
Number to typename.
GNUNET_GNSRECORD_ValueToStringFunction value_to_string
Conversion to string.
GNUNET_GNSRECORD_StringToValueFunction string_to_value
Conversion to binary.

References gns_is_critical(), gns_number_to_typename(), gns_string_to_value(), gns_typename_to_number(), gns_value_to_string(), GNUNET_new, GNUNET_GNSRECORD_PluginFunctions::is_critical, GNUNET_GNSRECORD_PluginFunctions::number_to_typename, GNUNET_GNSRECORD_PluginFunctions::string_to_value, GNUNET_GNSRECORD_PluginFunctions::typename_to_number, and GNUNET_GNSRECORD_PluginFunctions::value_to_string.

Here is the call graph for this function:

◆ libgnunet_plugin_gnsrecord_gns_done()

void * libgnunet_plugin_gnsrecord_gns_done ( void *  cls)

Exit point from the plugin.

Parameters
clsthe return value from libgnunet_plugin_block_test_init()
Returns
NULL

Definition at line 493 of file plugin_gnsrecord_gns.c.

494{
496
497 GNUNET_free (api);
498 return NULL;
499}
void * cls
Closure for all of the callbacks.

References GNUNET_GNSRECORD_PluginFunctions::cls, and GNUNET_free.

Variable Documentation

◆ name

const char* name

◆ number

uint32_t number

Definition at line 388 of file plugin_gnsrecord_gns.c.

Referenced by gns_number_to_typename().

◆ [struct]

struct { ... } gns_name_map[]
Initial value:

Mapping of record type numbers to human-readable record type names.

Referenced by gns_number_to_typename(), and gns_typename_to_number().