GNUnet 0.21.1
gnunet-daemon-pt.c File Reference

tool to manipulate DNS and VPN services to perform protocol translation (IPvX over GNUnet) More...

Include dependency graph for gnunet-daemon-pt.c:

Go to the source code of this file.

Data Structures

struct  ReplyContext
 Information tracked per DNS reply that we are processing. More...
 
struct  CadetExit
 Handle to a peer that advertised that it is willing to serve as a DNS exit. More...
 
struct  RequestContext
 State we keep for a request that is going out via CADET. More...
 
struct  DnsResponseMessage
 Message with a DNS response. More...
 

Macros

#define TIMEOUT   GNUNET_TIME_UNIT_MINUTES
 After how long do we time out if we could not get an IP from VPN or CADET? More...
 
#define MAX_DNS_SIZE   (8 * 1024)
 How many bytes of payload do we allow at most for a DNS reply? Given that this is pretty much limited to loopback, we can be pretty high (Linux loopback defaults to 16k, most local UDP packets should survive up to 9k (NFS), so 8k should be pretty safe in general). More...
 
#define MAX_OPEN_TUNNELS   4
 How many channels do we open at most at the same time? More...
 

Enumerations

enum  RequestGroup { ANSWERS = 0 , AUTHORITY_RECORDS = 1 , ADDITIONAL_RECORDS = 2 , END = 3 }
 Which group of DNS records are we currently processing? More...
 

Functions

static void try_open_exit (void)
 We are short on cadet exits, try to open another one. More...
 
static uint32_t get_channel_weight (struct CadetExit *exit)
 Compute the weight of the given exit. More...
 
static struct CadetExitchoose_exit ()
 Choose a cadet exit for a DNS request. More...
 
static void finish_request (struct ReplyContext *rc)
 We're done modifying all records in the response. More...
 
static void submit_request (struct ReplyContext *rc)
 Process the next record of the given request context. More...
 
static void vpn_allocation_callback (void *cls, int af, const void *address)
 Callback invoked from the VPN service once a redirection is available. More...
 
static void modify_address (struct ReplyContext *rc, struct GNUNET_DNSPARSER_Record *rec)
 Modify the given DNS record by asking VPN to create a channel to the given address. More...
 
static int work_test (const struct GNUNET_DNSPARSER_Record *ra, unsigned int ra_len)
 Test if any of the given records need protocol-translation work. More...
 
static void dns_post_request_handler (void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request)
 This function is called AFTER we got an IP address for a DNS request. More...
 
static void timeout_request (void *cls)
 Task run if the time to answer a DNS request via CADET is over. More...
 
static void dns_pre_request_handler (void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request)
 This function is called before the DNS request has been given to a "local" DNS resolver. More...
 
static GNUNET_NETWORK_STRUCT_END int check_dns_response (void *cls, const struct DnsResponseMessage *msg)
 Process a request via cadet to perform a DNS query. More...
 
static void handle_dns_response (void *cls, const struct DnsResponseMessage *msg)
 Process a request via cadet to perform a DNS query. More...
 
static void abort_all_requests (struct CadetExit *exit)
 Abort all pending DNS requests with the given cadet exit. More...
 
static void cleanup (void *cls)
 Function scheduled as very last function, cleans up after us. More...
 
static void cadet_channel_end_cb (void *cls, const struct GNUNET_CADET_Channel *channel)
 Function called whenever a channel is destroyed. More...
 
static void channel_idle_notify_cb (void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
 Function called whenever a channel has excess capacity. More...
 
static void handle_dht_result (void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
 Function called whenever we find an advertisement for a DNS exit in the DHT. More...
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg_)
 Main function that will be run by the scheduler. More...
 
int main (int argc, char *const *argv)
 The main function. More...
 

Variables

static struct CadetExitexit_head
 Head of DLL of cadet exits. More...
 
static struct CadetExitexit_tail
 Tail of DLL of cadet exits. More...
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 The handle to the configuration used throughout the process. More...
 
static struct GNUNET_VPN_Handlevpn_handle
 The handle to the VPN. More...
 
static struct GNUNET_CADET_Handlecadet_handle
 The handle to the CADET service. More...
 
static struct GNUNET_STATISTICS_Handlestats
 Statistics. More...
 
static struct GNUNET_DNS_Handledns_post_handle
 The handle to DNS post-resolution modifications. More...
 
static struct GNUNET_DNS_Handledns_pre_handle
 The handle to DNS pre-resolution modifications. More...
 
static struct GNUNET_DHT_Handledht
 Handle to access the DHT. More...
 
static struct GNUNET_DHT_GetHandledht_get
 Our DHT GET operation to find DNS exits. More...
 
static int ipv4_pt
 Are we doing IPv4-pt? More...
 
static int ipv6_pt
 Are we doing IPv6-pt? More...
 
static int dns_channel
 Are we channeling DNS queries? More...
 
static unsigned int dns_exit_available
 Number of DNS exit peers we currently have in the cadet channel. More...
 

Detailed Description

tool to manipulate DNS and VPN services to perform protocol translation (IPvX over GNUnet)

Author
Christian Grothoff

Definition in file gnunet-daemon-pt.c.

Macro Definition Documentation

◆ TIMEOUT

#define TIMEOUT   GNUNET_TIME_UNIT_MINUTES

After how long do we time out if we could not get an IP from VPN or CADET?

Definition at line 39 of file gnunet-daemon-pt.c.

◆ MAX_DNS_SIZE

#define MAX_DNS_SIZE   (8 * 1024)

How many bytes of payload do we allow at most for a DNS reply? Given that this is pretty much limited to loopback, we can be pretty high (Linux loopback defaults to 16k, most local UDP packets should survive up to 9k (NFS), so 8k should be pretty safe in general).

Definition at line 48 of file gnunet-daemon-pt.c.

◆ MAX_OPEN_TUNNELS

#define MAX_OPEN_TUNNELS   4

How many channels do we open at most at the same time?

Definition at line 53 of file gnunet-daemon-pt.c.

Enumeration Type Documentation

◆ RequestGroup

Which group of DNS records are we currently processing?

Enumerator
ANSWERS 

DNS answers.

AUTHORITY_RECORDS 

DNS authority records.

ADDITIONAL_RECORDS 

DNS additional records.

END 

We're done processing.

Definition at line 59 of file gnunet-daemon-pt.c.

60{
64 ANSWERS = 0,
65
70
75
79 END = 3
80};
@ ANSWERS
DNS answers.
@ ADDITIONAL_RECORDS
DNS additional records.
@ END
We're done processing.
@ AUTHORITY_RECORDS
DNS authority records.

Function Documentation

◆ try_open_exit()

static void try_open_exit ( void  )
static

We are short on cadet exits, try to open another one.

Definition at line 1052 of file gnunet-daemon-pt.c.

1053{
1054 struct CadetExit *pos;
1055 uint32_t candidate_count;
1056 uint32_t candidate_selected;
1057 struct GNUNET_HashCode port;
1058
1061 &port);
1062 candidate_count = 0;
1063 for (pos = exit_head; NULL != pos; pos = pos->next)
1064 if (NULL == pos->cadet_channel)
1065 candidate_count++;
1066 if (0 == candidate_count)
1067 {
1069 "No DNS exits available yet.\n");
1070 return;
1071 }
1073 candidate_count);
1074 candidate_count = 0;
1075 for (pos = exit_head; NULL != pos; pos = pos->next)
1076 if (NULL == pos->cadet_channel)
1077 {
1078 candidate_count++;
1079 if (candidate_selected < candidate_count)
1080 {
1081 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1082 GNUNET_MQ_hd_var_size (dns_response,
1084 struct DnsResponseMessage,
1085 pos),
1087 };
1088
1089
1090 /* move to the head of the DLL */
1091 pos->cadet_channel
1093 pos,
1094 &pos->peer,
1095 &port,
1098 cadet_handlers);
1099 if (NULL == pos->cadet_channel)
1100 {
1101 GNUNET_break (0);
1102 continue;
1103 }
1105 exit_tail,
1106 pos);
1108 exit_tail,
1109 pos);
1111 return;
1112 }
1113 }
1114 GNUNET_assert (NULL == exit_head);
1115}
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct CadetExit * exit_head
Head of DLL of cadet exits.
static unsigned int dns_exit_available
Number of DNS exit peers we currently have in the cadet channel.
static void channel_idle_notify_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever a channel has excess capacity.
static struct GNUNET_CADET_Handle * cadet_handle
The handle to the CADET service.
static struct CadetExit * exit_tail
Tail of DLL of cadet exits.
static void cadet_channel_end_cb(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
#define GNUNET_APPLICATION_PORT_INTERNET_RESOLVER
Internet DNS resolution (external DNS gateway).
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1015
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
#define GNUNET_log(kind,...)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET
Type of messages containing an DNS reply from a DNS exit service.
Handle to a peer that advertised that it is willing to serve as a DNS exit.
struct CadetExit * next
Kept in a DLL.
struct GNUNET_CADET_Channel * cadet_channel
Channel we use for DNS requests over CADET, NULL if we did not initialize a channel to this peer yet.
struct GNUNET_PeerIdentity peer
Identity of the peer that is providing the exit for us.
Message with a DNS response.
A 512-bit hashcode.
Message handler for a specific message type.

References CadetExit::cadet_channel, cadet_channel_end_cb(), cadet_handle, channel_idle_notify_cb(), dns_exit_available, exit_head, exit_tail, GNUNET_APPLICATION_PORT_INTERNET_RESOLVER, GNUNET_assert, GNUNET_break, GNUNET_CADET_channel_create(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, CadetExit::next, CadetExit::peer, and port.

Referenced by cadet_channel_end_cb(), handle_dht_result(), and timeout_request().

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

◆ get_channel_weight()

static uint32_t get_channel_weight ( struct CadetExit exit)
static

Compute the weight of the given exit.

The higher the weight, the more likely it will be that the channel will be chosen. A weigt of zero means that we should close the channel as it is so bad, that we should not use it.

Parameters
exitexit to calculate the weight for
Returns
weight of the channel

Definition at line 319 of file gnunet-daemon-pt.c.

320{
321 uint32_t dropped;
322 uint32_t drop_percent;
323 uint32_t good_percent;
324
326 dropped = exit->num_transmitted - exit->num_answered;
327 if (exit->num_transmitted > 0)
328 drop_percent = (uint32_t) ((100LL * dropped) / exit->num_transmitted);
329 else
330 drop_percent = 50; /* no data */
331 if ((exit->num_transmitted > 20) &&
332 (drop_percent > 25))
333 return 0; /* statistically significant, and > 25% loss, die */
334 good_percent = 100 - drop_percent;
335 GNUNET_assert (0 != good_percent);
336 if (UINT32_MAX / good_percent / good_percent < exit->num_transmitted)
337 return UINT32_MAX; /* formula below would overflow */
338 return 1 + good_percent * good_percent * exit->num_transmitted;
339}
unsigned long long drop_percent
Set to non-zero values to create random drops to test retransmissions.
unsigned int num_answered
How many DNS requests were answered via this channel?
unsigned int num_transmitted
How many DNS requests did we transmit via this channel?

References drop_percent, GNUNET_assert, CadetExit::num_answered, and CadetExit::num_transmitted.

Referenced by choose_exit(), and timeout_request().

Here is the caller graph for this function:

◆ choose_exit()

static struct CadetExit * choose_exit ( )
static

Choose a cadet exit for a DNS request.

We try to use a channel that is reliable and currently available. All existing channels are given a base weight of 1, plus a score relating to the total number of queries answered in relation to the total number of queries we sent to that channel. That score is doubled if the channel is currently idle.

Returns
NULL if no exit is known, otherwise the exit that we should use to queue a message with

Definition at line 354 of file gnunet-daemon-pt.c.

355{
356 struct CadetExit *pos;
357 uint64_t total_transmitted;
358 uint64_t selected_offset;
359 uint32_t channel_weight;
360
361 total_transmitted = 0;
362 for (pos = exit_head; NULL != pos; pos = pos->next)
363 {
364 if (NULL == pos->cadet_channel)
365 break;
366 channel_weight = get_channel_weight (pos);
367 total_transmitted += channel_weight;
368 /* double weight for idle channels */
369 if (0 != pos->idle)
370 total_transmitted += channel_weight;
371 }
372 if (0 == total_transmitted)
373 {
374 /* no channels available, or only a very bad one... */
375 return exit_head;
376 }
378 total_transmitted);
379 total_transmitted = 0;
380 for (pos = exit_head; NULL != pos; pos = pos->next)
381 {
382 if (NULL == pos->cadet_channel)
383 break;
384 channel_weight = get_channel_weight (pos);
385 total_transmitted += channel_weight;
386 /* double weight for idle channels */
387 if (0 != pos->idle)
388 total_transmitted += channel_weight;
389 if (total_transmitted > selected_offset)
390 return pos;
391 }
392 GNUNET_break (0);
393 return NULL;
394}
static uint32_t get_channel_weight(struct CadetExit *exit)
Compute the weight of the given exit.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
int idle
Size of the window, 0 if we are busy.

References CadetExit::cadet_channel, exit_head, get_channel_weight(), GNUNET_break, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u64(), CadetExit::idle, and CadetExit::next.

Referenced by cadet_channel_end_cb(), and dns_pre_request_handler().

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

◆ finish_request()

static void finish_request ( struct ReplyContext rc)
static

We're done modifying all records in the response.

Submit the reply and free the resources of the rc.

Parameters
rccontext to process

Definition at line 404 of file gnunet-daemon-pt.c.

405{
406 char *buf;
407 size_t buf_len;
408
409 if (GNUNET_SYSERR ==
412 &buf,
413 &buf_len))
414 {
416 _ ("Failed to pack DNS request. Dropping.\n"));
418 }
419 else
420 {
422 gettext_noop ("# DNS requests mapped to VPN"),
423 1, GNUNET_NO);
425 buf_len,
426 buf);
427 GNUNET_free (buf);
428 }
430 GNUNET_free (rc);
431}
#define gettext_noop(String)
Definition: gettext.h:70
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define MAX_DNS_SIZE
How many bytes of payload do we allow at most for a DNS reply? Given that this is pretty much limited...
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:947
int GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, uint16_t max, char **buf, size_t *buf_length)
Given a DNS packet p, generate the corresponding UDP payload.
Definition: dnsparser.c:1392
void GNUNET_DNS_request_answer(struct GNUNET_DNS_RequestHandle *rh, uint16_t reply_length, const char *reply)
If a GNUNET_DNS_RequestHandler calls this function, the request is supposed to be answered with the d...
Definition: dns_api.c:296
void GNUNET_DNS_request_drop(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the request is to be dropped and no response shou...
Definition: dns_api.c:265
@ GNUNET_NO
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
struct GNUNET_DNS_RequestHandle * rh
Handle to submit the final result.
struct GNUNET_DNSPARSER_Packet * dns
DNS packet that is being modified.

References _, ReplyContext::dns, gettext_noop, GNUNET_DNS_request_answer(), GNUNET_DNS_request_drop(), GNUNET_DNSPARSER_free_packet(), GNUNET_DNSPARSER_pack(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, MAX_DNS_SIZE, ReplyContext::rh, and stats.

Referenced by submit_request().

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

◆ submit_request()

static void submit_request ( struct ReplyContext rc)
static

Process the next record of the given request context.

When done, submit the reply and free the resources of the rc.

Parameters
rccontext to process

Definition at line 555 of file gnunet-daemon-pt.c.

556{
557 struct GNUNET_DNSPARSER_Record *ra;
558 unsigned int ra_len;
559 unsigned int i;
560
561 while (1)
562 {
563 switch (rc->group)
564 {
565 case ANSWERS:
566 ra = rc->dns->answers;
567 ra_len = rc->dns->num_answers;
568 break;
569
571 ra = rc->dns->authority_records;
572 ra_len = rc->dns->num_authority_records;
573 break;
574
576 ra = rc->dns->additional_records;
577 ra_len = rc->dns->num_additional_records;
578 break;
579
580 case END:
581 finish_request (rc);
582 return;
583
584 default:
585 GNUNET_assert (0);
586 }
587 for (i = rc->offset; i < ra_len; i++)
588 {
589 switch (ra[i].type)
590 {
592 if (ipv4_pt)
593 {
594 rc->offset = i + 1;
595 modify_address (rc,
596 &ra[i]);
597 return;
598 }
599 break;
600
602 if (ipv6_pt)
603 {
604 rc->offset = i + 1;
605 modify_address (rc,
606 &ra[i]);
607 return;
608 }
609 break;
610 }
611 }
612 rc->group++;
613 }
614}
static int ipv4_pt
Are we doing IPv4-pt?
static int ipv6_pt
Are we doing IPv6-pt?
static void modify_address(struct ReplyContext *rc, struct GNUNET_DNSPARSER_Record *rec)
Modify the given DNS record by asking VPN to create a channel to the given address.
static void finish_request(struct ReplyContext *rc)
We're done modifying all records in the response.
static uint32_t type
Type string converted to DNS type value.
#define GNUNET_DNSPARSER_TYPE_A
#define GNUNET_DNSPARSER_TYPE_AAAA
unsigned int num_answers
Number of answers in the packet, should be 0 for queries.
struct GNUNET_DNSPARSER_Record * answers
Array of all answers in the packet, must contain "num_answers" entries.
unsigned int num_additional_records
Number of additional records in the packet, should be 0 for queries.
struct GNUNET_DNSPARSER_Record * additional_records
Array of all additional answers in the packet, must contain "num_additional_records" entries.
struct GNUNET_DNSPARSER_Record * authority_records
Array of all authority records in the packet, must contain "num_authority_records" entries.
unsigned int num_authority_records
Number of authoritative answers in the packet, should be 0 for queries.
A DNS response record.
unsigned int offset
Offset in the current record group that is being modified.
enum RequestGroup group
Group that is being modified.

References GNUNET_DNSPARSER_Packet::additional_records, ADDITIONAL_RECORDS, GNUNET_DNSPARSER_Packet::answers, ANSWERS, GNUNET_DNSPARSER_Packet::authority_records, AUTHORITY_RECORDS, ReplyContext::dns, END, finish_request(), GNUNET_assert, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, ReplyContext::group, ipv4_pt, ipv6_pt, modify_address(), GNUNET_DNSPARSER_Packet::num_additional_records, GNUNET_DNSPARSER_Packet::num_answers, GNUNET_DNSPARSER_Packet::num_authority_records, ReplyContext::offset, and type.

Referenced by dns_post_request_handler(), and vpn_allocation_callback().

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

◆ vpn_allocation_callback()

static void vpn_allocation_callback ( void *  cls,
int  af,
const void *  address 
)
static

Callback invoked from the VPN service once a redirection is available.

Provides the IP address that can now be used to reach the requested destination. We substitute the active record and then continue with 'submit_request' to look at the other records.

Parameters
clsour struct ReplyContext
afaddress family, AF_INET or AF_INET6; AF_UNSPEC on error; will match 'result_af' from the request
addressIP address (struct in_addr or struct in_addr6, depending on 'af') that the VPN allocated for the redirection; traffic to this IP will now be redirected to the specified target peer; NULL on error

Definition at line 461 of file gnunet-daemon-pt.c.

464{
465 struct ReplyContext *rc = cls;
466
467 rc->rr = NULL;
468 if (af == AF_UNSPEC)
469 {
472 GNUNET_free (rc);
473 return;
474 }
476 gettext_noop ("# DNS records modified"),
477 1,
478 GNUNET_NO);
479 switch (rc->rec->type)
480 {
482 GNUNET_assert (AF_INET == af);
484 address,
485 sizeof(struct in_addr));
486 break;
487
489 GNUNET_assert (AF_INET6 == af);
491 address,
492 sizeof(struct in6_addr));
493 break;
494
495 default:
496 GNUNET_assert (0);
497 return;
498 }
499 rc->rec = NULL;
500 submit_request (rc);
501}
static char * address
GNS address for this phone.
static void submit_request(struct ReplyContext *rc)
Process the next record of the given request context.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void * data
Binary record data.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
union GNUNET_DNSPARSER_Record::@20 data
Payload of the record (which one of these is valid depends on the 'type').
Information tracked per DNS reply that we are processing.
struct GNUNET_DNSPARSER_Record * rec
Record for which we have an active redirection request.
struct GNUNET_VPN_RedirectionRequest * rr
Active redirection request with the VPN.

References address, GNUNET_DNSPARSER_RawRecord::data, GNUNET_DNSPARSER_Record::data, ReplyContext::dns, gettext_noop, GNUNET_assert, GNUNET_DNS_request_drop(), GNUNET_DNSPARSER_free_packet(), GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_free, GNUNET_memcpy, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_DNSPARSER_Record::raw, ReplyContext::rec, ReplyContext::rh, ReplyContext::rr, stats, submit_request(), and GNUNET_DNSPARSER_Record::type.

Referenced by modify_address().

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

◆ modify_address()

static void modify_address ( struct ReplyContext rc,
struct GNUNET_DNSPARSER_Record rec 
)
static

Modify the given DNS record by asking VPN to create a channel to the given address.

When done, continue with submitting other records from the request context ('submit_request' is our continuation).

Parameters
rccontext to process
recrecord to modify

Definition at line 514 of file gnunet-daemon-pt.c.

516{
517 int af;
518
519 switch (rec->type)
520 {
522 af = AF_INET;
523 GNUNET_assert (rec->data.raw.data_len == sizeof(struct in_addr));
524 break;
525
527 af = AF_INET6;
528 GNUNET_assert (rec->data.raw.data_len == sizeof(struct in6_addr));
529 break;
530
531 default:
532 GNUNET_assert (0);
533 return;
534 }
535 rc->rec = rec;
537 af,
538 af,
539 rec->data.raw.data,
541 TIMEOUT),
543 rc);
544}
static struct GNUNET_VPN_Handle * vpn_handle
The handle to the VPN.
#define TIMEOUT
After how long do we time out if we could not get an IP from VPN or CADET?
static void vpn_allocation_callback(void *cls, int af, const void *address)
Callback invoked from the VPN service once a redirection is available.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct GNUNET_VPN_RedirectionRequest * GNUNET_VPN_redirect_to_ip(struct GNUNET_VPN_Handle *vh, int result_af, int addr_af, const void *addr, struct GNUNET_TIME_Absolute expiration_time, GNUNET_VPN_AllocationCallback cb, void *cb_cls)
Tell the VPN that forwarding to the Internet via some exit node is requested.
Definition: vpn_api.c:439
size_t data_len
Number of bytes in data.

References GNUNET_DNSPARSER_RawRecord::data, GNUNET_DNSPARSER_Record::data, GNUNET_DNSPARSER_RawRecord::data_len, GNUNET_assert, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_TIME_relative_to_absolute(), GNUNET_VPN_redirect_to_ip(), GNUNET_DNSPARSER_Record::raw, ReplyContext::rec, ReplyContext::rr, TIMEOUT, GNUNET_DNSPARSER_Record::type, vpn_allocation_callback(), and vpn_handle.

Referenced by submit_request().

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

◆ work_test()

static int work_test ( const struct GNUNET_DNSPARSER_Record ra,
unsigned int  ra_len 
)
static

Test if any of the given records need protocol-translation work.

Parameters
raarray of records
ra_lennumber of entries in ra
Returns
GNUNET_YES if any of the given records require protocol-translation

Definition at line 625 of file gnunet-daemon-pt.c.

627{
628 unsigned int i;
629
630 for (i = 0; i < ra_len; i++)
631 {
632 switch (ra[i].type)
633 {
635 if (ipv4_pt)
636 return GNUNET_YES;
637 break;
638
640 if (ipv6_pt)
641 return GNUNET_YES;
642 break;
643 }
644 }
645 return GNUNET_NO;
646}
@ GNUNET_YES

References GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_NO, GNUNET_YES, ipv4_pt, ipv6_pt, and type.

Referenced by dns_post_request_handler().

Here is the caller graph for this function:

◆ dns_post_request_handler()

static void dns_post_request_handler ( void *  cls,
struct GNUNET_DNS_RequestHandle rh,
size_t  request_length,
const char *  request 
)
static

This function is called AFTER we got an IP address for a DNS request.

Now, the PT daemon has the chance to substitute the IP address with one from the VPN range to channel requests destined for this IP address via VPN and CADET.

Parameters
clsclosure
rhrequest handle to user for reply
request_lengthnumber of bytes in request
requestudp payload of the DNS request

Definition at line 661 of file gnunet-daemon-pt.c.

665{
666 struct GNUNET_DNSPARSER_Packet *dns;
667 struct ReplyContext *rc;
668 int work;
669
671 gettext_noop ("# DNS replies intercepted"),
672 1, GNUNET_NO);
674 request_length);
675 if (NULL == dns)
676 {
678 _ ("Failed to parse DNS request. Dropping.\n"));
680 return;
681 }
682 work = GNUNET_NO;
689 if (! work)
690 {
693 return;
694 }
695 rc = GNUNET_new (struct ReplyContext);
696 rc->rh = rh;
697 rc->dns = dns;
698 rc->offset = 0;
699 rc->group = ANSWERS;
700 submit_request (rc);
701}
static void work(void *cls)
Function called to process work items.
static int work_test(const struct GNUNET_DNSPARSER_Record *ra, unsigned int ra_len)
Test if any of the given records need protocol-translation work.
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:40
struct GNUNET_DNSPARSER_Packet * GNUNET_DNSPARSER_parse(const char *udp_payload, size_t udp_payload_length)
Parse a UDP payload of a DNS packet in to a nice struct for further processing and manipulation.
Definition: dnsparser.c:727
void GNUNET_DNS_request_forward(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the client has no desire to interfer with the req...
Definition: dns_api.c:237
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Easy-to-process, parsed version of a DNS packet.

References _, GNUNET_DNSPARSER_Packet::additional_records, GNUNET_DNSPARSER_Packet::answers, ANSWERS, GNUNET_DNSPARSER_Packet::authority_records, ReplyContext::dns, gettext_noop, GNUNET_DNS_request_drop(), GNUNET_DNS_request_forward(), GNUNET_DNSPARSER_free_packet(), GNUNET_DNSPARSER_parse(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), ReplyContext::group, GNUNET_DNSPARSER_Packet::num_additional_records, GNUNET_DNSPARSER_Packet::num_answers, GNUNET_DNSPARSER_Packet::num_authority_records, ReplyContext::offset, request, ReplyContext::rh, stats, submit_request(), work(), and work_test().

Referenced by run().

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

◆ timeout_request()

static void timeout_request ( void *  cls)
static

Task run if the time to answer a DNS request via CADET is over.

Parameters
clsthe struct RequestContext to abort

Definition at line 710 of file gnunet-daemon-pt.c.

711{
712 struct RequestContext *rc = cls;
713 struct CadetExit *exit = rc->exit;
714
716 gettext_noop ("# DNS requests dropped (timeout)"),
717 1,
718 GNUNET_NO);
720 GNUNET_free (rc);
721 if ((0 == get_channel_weight (exit)) &&
722 (NULL == exit->receive_queue_head))
723 {
724 /* this straw broke the camel's back: this channel now has
725 such a low score that it will not be used; close it! */
727 exit->cadet_channel = NULL;
729 exit_tail,
730 exit);
732 exit_tail,
733 exit);
734 /* go back to semi-innocent: mark as not great, but
735 avoid a prohibitively negative score (see
736 #get_channel_weight(), which checks for a certain
737 minimum number of transmissions before making
738 up an opinion) */exit->num_transmitted = 5;
739 exit->num_answered = 0;
741 /* now try to open an alternative exit */
742 try_open_exit ();
743 }
744}
static void try_open_exit(void)
We are short on cadet exits, try to open another one.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct RequestContext * receive_queue_head
Head of DLL of requests waiting for a response.
State we keep for a request that is going out via CADET.
struct CadetExit * exit
Exit that was chosen for this request.
struct GNUNET_DNS_RequestHandle * rh
Handle for interaction with DNS service.

References CadetExit::cadet_channel, dns_exit_available, RequestContext::exit, exit_head, exit_tail, get_channel_weight(), gettext_noop, GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_DNS_request_drop(), GNUNET_free, GNUNET_NO, GNUNET_STATISTICS_update(), CadetExit::num_answered, CadetExit::num_transmitted, CadetExit::receive_queue_head, RequestContext::rh, stats, and try_open_exit().

Referenced by dns_pre_request_handler().

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

◆ dns_pre_request_handler()

static void dns_pre_request_handler ( void *  cls,
struct GNUNET_DNS_RequestHandle rh,
size_t  request_length,
const char *  request 
)
static

This function is called before the DNS request has been given to a "local" DNS resolver.

Channeling for DNS requests was enabled, so we now need to send the request via some CADET channel to a DNS EXIT for resolution.

Parameters
clsclosure
rhrequest handle to user for reply
request_lengthnumber of bytes in request
requestudp payload of the DNS request

Definition at line 759 of file gnunet-daemon-pt.c.

763{
764 struct RequestContext *rc;
765 struct GNUNET_MQ_Envelope *env;
766 struct GNUNET_MessageHeader *hdr;
767 struct GNUNET_TUN_DnsHeader dns;
768 struct CadetExit *exit;
769
771 gettext_noop ("# DNS requests intercepted"),
772 1, GNUNET_NO);
773 if (0 == dns_exit_available)
774 {
777 "# DNS requests dropped (DNS cadet channel down)"),
778 1, GNUNET_NO);
780 return;
781 }
782 if (request_length < sizeof(dns))
783 {
786 "# DNS requests dropped (malformed)"),
787 1, GNUNET_NO);
789 return;
790 }
791 exit = choose_exit ();
792 GNUNET_assert (NULL != exit);
793 GNUNET_assert (NULL != exit->cadet_channel);
794
796 request_length,
798 GNUNET_memcpy (&hdr[1],
799 request,
800 request_length);
801 rc = GNUNET_new (struct RequestContext);
802 rc->exit = exit;
803 rc->rh = rh;
806 rc);
807 GNUNET_memcpy (&dns,
808 request,
809 sizeof(dns));
810 rc->dns_id = dns.id;
811 rc->env = env;
813 exit->receive_queue_tail,
814 rc);
815 if (0 < exit->idle)
816 exit->idle--;
817 exit->num_transmitted++;
820}
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static void timeout_request(void *cls)
Task run if the time to answer a DNS request via CADET is over.
static struct CadetExit * choose_exit()
Choose a cadet exit for a DNS request.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition: cadet_api.c:1066
struct GNUNET_MQ_Envelope * GNUNET_MQ_env_copy(struct GNUNET_MQ_Envelope *env)
Function to copy an envelope.
Definition: mq.c:359
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1278
struct RequestContext * receive_queue_tail
Tail of DLL of requests waiting for a response.
Header for all communications.
struct GNUNET_SCHEDULER_Task * timeout_task
Task used to abort this operation with timeout.
struct GNUNET_MQ_Envelope * env
Envelope with the request we are transmitting.
uint16_t dns_id
ID of the original DNS request (used to match the reply).

References CadetExit::cadet_channel, choose_exit(), dns_exit_available, RequestContext::dns_id, env, RequestContext::env, RequestContext::exit, gettext_noop, GNUNET_assert, GNUNET_CADET_get_mq(), GNUNET_CONTAINER_DLL_remove, GNUNET_DNS_request_drop(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, GNUNET_MQ_env_copy(), GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_TUN_DnsHeader::id, CadetExit::idle, CadetExit::num_transmitted, CadetExit::receive_queue_head, CadetExit::receive_queue_tail, request, RequestContext::rh, stats, TIMEOUT, timeout_request(), and RequestContext::timeout_task.

Referenced by run().

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

◆ check_dns_response()

static GNUNET_NETWORK_STRUCT_END int check_dns_response ( void *  cls,
const struct DnsResponseMessage msg 
)
static

Process a request via cadet to perform a DNS query.

Parameters
clsthe struct CadetExit which got the message
msgthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 854 of file gnunet-daemon-pt.c.

856{
857 return GNUNET_OK; /* all OK */
858}
@ GNUNET_OK

References GNUNET_OK.

◆ handle_dns_response()

static void handle_dns_response ( void *  cls,
const struct DnsResponseMessage msg 
)
static

Process a request via cadet to perform a DNS query.

Parameters
clsthe struct CadetExit which got the message
msgthe actual message

Definition at line 868 of file gnunet-daemon-pt.c.

870{
871 struct CadetExit *exit = cls;
872 size_t mlen;
873 struct RequestContext *rc;
874
875 mlen = ntohs (msg->header.size) - sizeof(*msg);
876 for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next)
877 {
878 if (msg->dns.id == rc->dns_id)
879 {
881 gettext_noop ("# DNS replies received"),
882 1,
883 GNUNET_NO);
885 mlen + sizeof(struct GNUNET_TUN_DnsHeader),
886 (const void *) &msg->dns);
889 rc);
892 GNUNET_free (rc);
894 return;
895 }
896 }
898 gettext_noop ("# DNS replies dropped (too late?)"),
899 1, GNUNET_NO);
900}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:285
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct RequestContext * next
We keep these in a DLL.
uint16_t mlen
Length of the request message that follows this struct.

References RequestContext::dns_id, RequestContext::env, RequestContext::exit, gettext_noop, GNUNET_CONTAINER_DLL_remove, GNUNET_DNS_request_answer(), GNUNET_free, GNUNET_MQ_discard(), GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), RequestContext::mlen, msg, RequestContext::next, CadetExit::num_answered, CadetExit::receive_queue_head, CadetExit::receive_queue_tail, RequestContext::rh, GNUNET_MessageHeader::size, stats, and RequestContext::timeout_task.

Here is the call graph for this function:

◆ abort_all_requests()

static void abort_all_requests ( struct CadetExit exit)
static

Abort all pending DNS requests with the given cadet exit.

Parameters
exitcadet exit to abort requests for

Definition at line 909 of file gnunet-daemon-pt.c.

910{
911 struct RequestContext *rc;
912
913 while (NULL != (rc = exit->receive_queue_head))
914 {
917 rc);
921 GNUNET_free (rc);
922 }
923}

References RequestContext::env, RequestContext::exit, GNUNET_CONTAINER_DLL_remove, GNUNET_DNS_request_drop(), GNUNET_free, GNUNET_MQ_discard(), GNUNET_SCHEDULER_cancel(), CadetExit::receive_queue_head, CadetExit::receive_queue_tail, RequestContext::rh, and RequestContext::timeout_task.

Referenced by cleanup().

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

◆ cleanup()

static void cleanup ( void *  cls)
static

Function scheduled as very last function, cleans up after us.

Parameters
clsclosure, NULL

Definition at line 932 of file gnunet-daemon-pt.c.

933{
934 struct CadetExit *exit;
935
937 "Protocol translation daemon is shutting down now\n");
938 if (NULL != vpn_handle)
939 {
941 vpn_handle = NULL;
942 }
943 while (NULL != (exit = exit_head))
944 {
946 exit_tail,
947 exit);
948 if (NULL != exit->cadet_channel)
949 {
951 exit->cadet_channel = NULL;
952 }
953 abort_all_requests (exit);
954 GNUNET_free (exit);
955 }
956 if (NULL != cadet_handle)
957 {
959 cadet_handle = NULL;
960 }
961 if (NULL != dns_post_handle)
962 {
964 dns_post_handle = NULL;
965 }
966 if (NULL != dns_pre_handle)
967 {
969 dns_pre_handle = NULL;
970 }
971 if (NULL != stats)
972 {
974 stats = NULL;
975 }
976 if (NULL != dht_get)
977 {
979 dht_get = NULL;
980 }
981 if (NULL != dht)
982 {
984 dht = NULL;
985 }
986}
static struct GNUNET_DNS_Handle * dns_pre_handle
The handle to DNS pre-resolution modifications.
static struct GNUNET_DHT_Handle * dht
Handle to access the DHT.
static struct GNUNET_DNS_Handle * dns_post_handle
The handle to DNS post-resolution modifications.
static void abort_all_requests(struct CadetExit *exit)
Abort all pending DNS requests with the given cadet exit.
static struct GNUNET_DHT_GetHandle * dht_get
Our DHT GET operation to find DNS exits.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:774
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1235
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1060
void GNUNET_DNS_disconnect(struct GNUNET_DNS_Handle *dh)
Disconnect from the DNS service.
Definition: dns_api.c:363
@ GNUNET_ERROR_TYPE_DEBUG
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:512

References abort_all_requests(), CadetExit::cadet_channel, cadet_handle, dht, dht_get, dns_post_handle, dns_pre_handle, exit_head, exit_tail, GNUNET_CADET_channel_destroy(), GNUNET_CADET_disconnect(), GNUNET_CONTAINER_DLL_remove, GNUNET_DHT_disconnect(), GNUNET_DHT_get_stop(), GNUNET_DNS_disconnect(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_STATISTICS_destroy(), GNUNET_VPN_disconnect(), GNUNET_YES, stats, and vpn_handle.

Referenced by run().

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

◆ cadet_channel_end_cb()

static void cadet_channel_end_cb ( void *  cls,
const struct GNUNET_CADET_Channel channel 
)
static

Function called whenever a channel is destroyed.

Should clean up the associated state and attempt to build a new one.

It must NOT call GNUNET_CADET_channel_destroy on the channel.

Parameters
clsclosure (the struct CadetExit set from GNUNET_CADET_connect)
channelconnection to the other end (henceforth invalid)
channel_ctxplace where local state associated with the channel is stored

Definition at line 1001 of file gnunet-daemon-pt.c.

1003{
1004 struct CadetExit *exit = cls;
1005 struct CadetExit *alt;
1006 struct RequestContext *rc;
1007
1008 exit->cadet_channel = NULL;
1010 /* open alternative channels */
1011 /* our channel is now closed, move our requests to an alternative
1012 channel */
1013 alt = choose_exit ();
1014 while (NULL != (rc = exit->receive_queue_head))
1015 {
1018 rc);
1019 rc->exit = alt;
1021 alt->receive_queue_tail,
1022 rc);
1024 GNUNET_MQ_env_copy (rc->env));
1025 }
1026 try_open_exit ();
1027}

References CadetExit::cadet_channel, choose_exit(), dns_exit_available, RequestContext::env, RequestContext::exit, GNUNET_CADET_get_mq(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_MQ_env_copy(), GNUNET_MQ_send(), CadetExit::receive_queue_head, CadetExit::receive_queue_tail, and try_open_exit().

Referenced by try_open_exit().

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

◆ channel_idle_notify_cb()

static void channel_idle_notify_cb ( void *  cls,
const struct GNUNET_CADET_Channel channel,
int  window_size 
)
static

Function called whenever a channel has excess capacity.

Parameters
clsthe struct CadetExit
channelconnection to the other end
window_sizehow much capacity do we have

Definition at line 1038 of file gnunet-daemon-pt.c.

1041{
1042 struct CadetExit *pos = cls;
1043
1044 pos->idle = window_size;
1045}

References CadetExit::idle.

Referenced by try_open_exit().

Here is the caller graph for this function:

◆ handle_dht_result()

static void handle_dht_result ( void *  cls,
struct GNUNET_TIME_Absolute  exp,
const struct GNUNET_HashCode key,
const struct GNUNET_PeerIdentity trunc_peer,
const struct GNUNET_DHT_PathElement get_path,
unsigned int  get_path_length,
const struct GNUNET_DHT_PathElement put_path,
unsigned int  put_path_length,
enum GNUNET_BLOCK_Type  type,
size_t  size,
const void *  data 
)
static

Function called whenever we find an advertisement for a DNS exit in the DHT.

If we don't have a cadet channel, we should build one; otherwise, we should save the advertisement for later use.

Parameters
clsclosure
expwhen will this value expire
keykey of the result
trunc_peerpeer that was truncated (or NULL if not truncated)
get_pathpeers on reply path (or NULL if not recorded) [0] = datastore's first neighbor, [length - 1] = local peer
get_path_lengthnumber of entries in get_path
put_pathpeers on the PUT path (or NULL if not recorded) [0] = origin, [length - 1] = datastore
put_path_lengthnumber of entries in put_path
typetype of the result
sizenumber of bytes in data
datapointer to the result data

Definition at line 1139 of file gnunet-daemon-pt.c.

1149{
1150 const struct GNUNET_DNS_Advertisement *ad;
1151 struct CadetExit *exit;
1152
1153 if (sizeof(struct GNUNET_DNS_Advertisement) != size)
1154 {
1155 GNUNET_break (0);
1156 return;
1157 }
1158 ad = data;
1159 for (exit = exit_head; NULL != exit; exit = exit->next)
1160 if (0 == GNUNET_memcmp (&ad->peer,
1161 &exit->peer))
1162 break;
1163 if (NULL == exit)
1164 {
1165 exit = GNUNET_new (struct CadetExit);
1166 exit->peer = ad->peer;
1167 /* channel is closed, so insert at the end */
1169 exit_tail,
1170 exit);
1171 }
1174 ad->expiration_time));
1176 try_open_exit ();
1177}
#define MAX_OPEN_TUNNELS
How many channels do we open at most at the same time?
static char * data
The data to insert into the dht.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the maximum of two absolute time values.
Definition: time.c:367
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
static unsigned int size
Size of the "table".
Definition: peer.c:68
struct GNUNET_TIME_Absolute expiration
At what time did the peer's advertisement expire?
This is the structure describing an DNS exit service.
Definition: block_dns.h:45
struct GNUNET_PeerIdentity peer
The peer providing this service.
Definition: block_dns.h:65
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition: block_dns.h:60

References data, dns_exit_available, exit_head, exit_tail, CadetExit::expiration, GNUNET_DNS_Advertisement::expiration_time, GNUNET_break, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_memcmp, GNUNET_new, GNUNET_TIME_absolute_max(), GNUNET_TIME_absolute_ntoh(), MAX_OPEN_TUNNELS, CadetExit::next, GNUNET_DNS_Advertisement::peer, CadetExit::peer, size, and try_open_exit().

Referenced by run().

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

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle cfg_ 
)
static

Main function that will be run by the scheduler.

Parameters
clsclosure
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL!)
cfg_configuration

Definition at line 1189 of file gnunet-daemon-pt.c.

1192{
1193 struct GNUNET_HashCode dns_key;
1194
1195 cfg = cfg_;
1197 cfg);
1199 "pt",
1200 "TUNNEL_IPV4");
1202 "pt",
1203 "TUNNEL_IPV6");
1205 "pt",
1206 "TUNNEL_DNS");
1207 if (! (ipv4_pt || ipv6_pt || dns_channel))
1208 {
1210 _ ("No useful service enabled. Exiting.\n"));
1212 return;
1213 }
1215 if (ipv4_pt || ipv6_pt)
1216 {
1221 NULL);
1222 if (NULL == dns_post_handle)
1223 {
1225 _ ("Failed to connect to %s service. Exiting.\n"),
1226 "DNS");
1228 return;
1229 }
1231 if (NULL == vpn_handle)
1232 {
1234 _ ("Failed to connect to %s service. Exiting.\n"),
1235 "VPN");
1237 return;
1238 }
1239 }
1240 if (dns_channel)
1241 {
1246 NULL);
1247 if (NULL == dns_pre_handle)
1248 {
1250 _ ("Failed to connect to %s service. Exiting.\n"),
1251 "DNS");
1253 return;
1254 }
1256 if (NULL == cadet_handle)
1257 {
1259 _ ("Failed to connect to %s service. Exiting.\n"),
1260 "CADET");
1262 return;
1263 }
1264 dht = GNUNET_DHT_connect (cfg, 1);
1265 if (NULL == dht)
1266 {
1268 _ ("Failed to connect to %s service. Exiting.\n"),
1269 "DHT");
1271 return;
1272 }
1273 GNUNET_CRYPTO_hash ("dns",
1274 strlen ("dns"),
1275 &dns_key);
1278 &dns_key,
1279 1,
1281 NULL, 0,
1283 NULL);
1284 }
1285}
static void dns_pre_request_handler(void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request)
This function is called before the DNS request has been given to a "local" DNS resolver.
static int dns_channel
Are we channeling DNS queries?
static const struct GNUNET_CONFIGURATION_Handle * cfg
The handle to the configuration used throughout the process.
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
static void handle_dht_result(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
Function called whenever we find an advertisement for a DNS exit in the DHT.
static void dns_post_request_handler(void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request)
This function is called AFTER we got an IP address for a DNS request.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:894
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:1037
struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start(struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, size_t xquery_size, GNUNET_DHT_GetIterator iter, void *iter_cls)
Perform an asynchronous GET operation on the DHT identified.
Definition: dht_api.c:1162
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
struct GNUNET_DNS_Handle * GNUNET_DNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_DNS_Flags flags, GNUNET_DNS_RequestHandler rh, void *rh_cls)
Connect to the service-dns.
Definition: dns_api.c:340
@ GNUNET_DNS_FLAG_PRE_RESOLUTION
This client should be called on requests that have not yet been resolved as this client provides a re...
@ GNUNET_DNS_FLAG_POST_RESOLUTION
This client wants to be called on the results of a DNS resolution (either resolved by PRE-RESOLUTION ...
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1340
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:490
@ GNUNET_BLOCK_TYPE_DNS
Block for storing DNS exit service advertisements.

References _, cadet_handle, cfg, cleanup(), dht, dht_get, dns_channel, dns_post_handle, dns_post_request_handler(), dns_pre_handle, dns_pre_request_handler(), GNUNET_BLOCK_TYPE_DNS, GNUNET_CADET_connect(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CRYPTO_hash(), GNUNET_DHT_connect(), GNUNET_DHT_get_start(), GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_DNS_connect(), GNUNET_DNS_FLAG_POST_RESOLUTION, GNUNET_DNS_FLAG_PRE_RESOLUTION, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), GNUNET_VPN_connect(), handle_dht_result(), ipv4_pt, ipv6_pt, stats, and vpn_handle.

Referenced by main().

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

◆ main()

int main ( int  argc,
char *const *  argv 
)

The main function.

Parameters
argcnumber of arguments from the command line
argvcommand line arguments
Returns
0 ok, 1 on error

Definition at line 1296 of file gnunet-daemon-pt.c.

1298{
1299 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1301 };
1302 int ret;
1303
1305 argv,
1306 &argc,
1307 &argv))
1308 return 2;
1309 ret = (GNUNET_OK ==
1310 GNUNET_PROGRAM_run (argc,
1311 argv,
1312 "gnunet-daemon-pt",
1313 gettext_noop (
1314 "Daemon to run to perform IP protocol translation to GNUnet"),
1315 options,
1316 &run,
1317 NULL))
1318 ? 0
1319 : 1;
1320 GNUNET_free_nz ((void *) argv);
1321 return ret;
1322}
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static int ret
Final status code.
Definition: gnunet-arm.c:94
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg_)
Main function that will be run by the scheduler.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
Definition of a command line option.

References gettext_noop, GNUNET_free_nz, GNUNET_GETOPT_OPTION_END, GNUNET_OK, GNUNET_PROGRAM_run(), GNUNET_STRINGS_get_utf8_args(), options, ret, and run().

Here is the call graph for this function:

Variable Documentation

◆ exit_head

struct CadetExit* exit_head
static

Head of DLL of cadet exits.

Cadet exits with an open channel are always at the beginning (so we do not have to traverse the entire list to find them).

Definition at line 232 of file gnunet-daemon-pt.c.

Referenced by choose_exit(), cleanup(), handle_dht_result(), timeout_request(), and try_open_exit().

◆ exit_tail

struct CadetExit* exit_tail
static

Tail of DLL of cadet exits.

Definition at line 237 of file gnunet-daemon-pt.c.

Referenced by cleanup(), handle_dht_result(), timeout_request(), and try_open_exit().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

The handle to the configuration used throughout the process.

Definition at line 242 of file gnunet-daemon-pt.c.

Referenced by run().

◆ vpn_handle

struct GNUNET_VPN_Handle* vpn_handle
static

The handle to the VPN.

Definition at line 247 of file gnunet-daemon-pt.c.

Referenced by cleanup(), modify_address(), and run().

◆ cadet_handle

struct GNUNET_CADET_Handle* cadet_handle
static

The handle to the CADET service.

Definition at line 252 of file gnunet-daemon-pt.c.

Referenced by cleanup(), run(), and try_open_exit().

◆ stats

◆ dns_post_handle

struct GNUNET_DNS_Handle* dns_post_handle
static

The handle to DNS post-resolution modifications.

Definition at line 262 of file gnunet-daemon-pt.c.

Referenced by cleanup(), and run().

◆ dns_pre_handle

struct GNUNET_DNS_Handle* dns_pre_handle
static

The handle to DNS pre-resolution modifications.

Definition at line 267 of file gnunet-daemon-pt.c.

Referenced by cleanup(), and run().

◆ dht

struct GNUNET_DHT_Handle* dht
static

Handle to access the DHT.

Definition at line 272 of file gnunet-daemon-pt.c.

Referenced by cleanup(), and run().

◆ dht_get

struct GNUNET_DHT_GetHandle* dht_get
static

Our DHT GET operation to find DNS exits.

Definition at line 277 of file gnunet-daemon-pt.c.

Referenced by cleanup(), and run().

◆ ipv4_pt

int ipv4_pt
static

Are we doing IPv4-pt?

Definition at line 282 of file gnunet-daemon-pt.c.

Referenced by run(), submit_request(), and work_test().

◆ ipv6_pt

int ipv6_pt
static

Are we doing IPv6-pt?

Definition at line 287 of file gnunet-daemon-pt.c.

Referenced by run(), submit_request(), and work_test().

◆ dns_channel

int dns_channel
static

Are we channeling DNS queries?

Definition at line 292 of file gnunet-daemon-pt.c.

Referenced by run().

◆ dns_exit_available

unsigned int dns_exit_available
static

Number of DNS exit peers we currently have in the cadet channel.

Used to see if using the cadet channel makes any sense right now, as well as to decide if we should open new channels.

Definition at line 299 of file gnunet-daemon-pt.c.

Referenced by cadet_channel_end_cb(), dns_pre_request_handler(), handle_dht_result(), timeout_request(), and try_open_exit().