61 #define LOG(kind, ...) \ 62 GNUNET_log_from (kind, "dns", __VA_ARGS__); 170 struct sockaddr_storage src_addr;
175 struct sockaddr_storage dst_addr;
277 if (NULL != hijacker)
282 for (
unsigned int i = 0; i < 8; i++)
284 for (
unsigned int i = 0; i <= UINT16_MAX; i++)
310 uint16_t source_port;
311 uint16_t destination_port;
320 "Got no response for request %llu, dropping\n",
327 "Transmitting response for request %llu\n",
365 hdr->size = htons ((uint16_t) reply_len);
372 tun.
flags = htons (0);
373 if (rr->
src_addr.ss_family == AF_INET)
388 struct sockaddr_in *src = (
struct sockaddr_in *) &rr->
src_addr;
389 struct sockaddr_in *dst = (
struct sockaddr_in *) &rr->
dst_addr;
391 source_port = dst->sin_port;
392 destination_port = src->sin_port;
395 reply_len - off -
sizeof(
struct 408 struct sockaddr_in6 *src = (
struct sockaddr_in6 *) &rr->
src_addr;
409 struct sockaddr_in6 *dst = (
struct sockaddr_in6 *) &rr->
dst_addr;
411 source_port = dst->sin6_port;
412 destination_port = src->sin6_port;
415 reply_len - off -
sizeof(
struct 436 udp.
len = htons (reply_len - off);
437 if (AF_INET == rr->
src_addr.ss_family)
466 "# DNS requests answered via TUN interface"),
496 "Sending information about request %llu to local client\n",
559 "Request %llu now in phase %d\n",
566 for (cr = clients_head; NULL != cr; cr = cr->
next)
578 for (cr = clients_head; NULL != cr; cr = cr->
next)
597 salen =
sizeof(
struct sockaddr_in);
598 sa = (
const struct sockaddr *) &rr->
dst_addr;
602 salen =
sizeof(
struct sockaddr_in6);
603 sa = (
const struct sockaddr *) &rr->
dst_addr;
620 "# DNS exit failed (failed to open socket)"),
630 for (cr = clients_head; NULL != cr; cr = cr->
next)
642 for (cr = clients_head; NULL != cr; cr = cr->
next)
711 for (
unsigned int i = 0; i < UINT16_MAX; i++)
745 "Processing DNS result from stub resolver\n");
756 "# External DNS response discarded (no matching request)"),
759 "Received DNS reply that does not match any pending request. Dropping.\n");
763 "Got a response from the stub resolver for DNS request %llu intercepted locally!\n",
826 "Received DNS response with ID %llu from local client!\n",
832 "# Client response discarded (no matching request)"),
867 "Changing DNS reply according to client specifications\n");
884 query_or_response == 1) )
922 struct sockaddr_in *srca4;
923 struct sockaddr_in6 *srca6;
924 struct sockaddr_in *dsta4;
925 struct sockaddr_in6 *dsta6;
928 "Intercepted message via DNS hijacker\n");
929 msize = ntohs (message->
size);
941 switch (ntohs (tun->
proto))
949 (ntohs (ip4->total_length) != msize) ||
954 _ (
"Received malformed IPv4-UDP packet on TUN interface.\n"));
973 _ (
"Received malformed IPv6-UDP packet on TUN interface.\n"));
984 "Got non-IP packet with %u bytes and protocol %u from TUN\n"),
985 (
unsigned int) msize,
996 _ (
"DNS interceptor got non-DNS packet (dropped)\n"));
999 "# Non-DNS UDP packet received via TUN interface"),
1016 switch (ntohs (tun->
proto))
1020 srca4 = (
struct sockaddr_in*) &rr->
src_addr;
1021 dsta4 = (
struct sockaddr_in*) &rr->
dst_addr;
1022 memset (srca4, 0,
sizeof(
struct sockaddr_in));
1023 memset (dsta4, 0,
sizeof(
struct sockaddr_in));
1024 srca4->sin_family = AF_INET;
1025 dsta4->sin_family = AF_INET;
1030 #if HAVE_SOCKADDR_IN_SIN_LEN 1031 srca4->sin_len =
sizeof(
struct sockaddr_in);
1032 dsta4->sin_len =
sizeof(
struct sockaddr_in);
1039 srca6 = (
struct sockaddr_in6*) &rr->
src_addr;
1040 dsta6 = (
struct sockaddr_in6*) &rr->
dst_addr;
1041 memset (srca6, 0,
sizeof(
struct sockaddr_in6));
1042 memset (dsta6, 0,
sizeof(
struct sockaddr_in6));
1043 srca6->sin6_family = AF_INET6;
1044 dsta6->sin6_family = AF_INET6;
1049 #if HAVE_SOCKADDR_IN_SIN_LEN 1050 srca6->sin6_len =
sizeof(
struct sockaddr_in6);
1051 dsta6->sin6_len =
sizeof(
struct sockaddr_in6);
1065 "Creating new DNS request %llu\n",
1069 "# DNS requests received via TUN interface"),
1117 _ (
"need a valid IPv4 or IPv6 address\n"));
1128 _ (
"`%s' is not SUID or the path is invalid, " 1129 "will not run DNS interceptor\n"),
1145 "No entry 'IFNAME' in configuration!\n");
1158 "No entry 'IPV6ADDR' in configuration!\n");
1171 "No entry 'IPV6PREFIX' in configuration!\n");
1185 "No entry 'IPV4ADDR' in configuration!\n");
1196 "No entry 'IPV4MASK' in configuration!\n");
1204 "SKIP_ROUTING_SETUP");
1253 if (-1 == getresgid (&rgid,
1258 "getresgid failed: %s\n",
1261 else if (sgid != rgid)
1263 if (-1 == setregid (sgid,
1266 "setregid failed: %s\n",
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
size_t payload_length
Number of bytes in payload.
uint32_t flags
NBO encoding of enum GNUNET_DNS_Flags for the client.
static int check_client_response(void *cls, const struct GNUNET_DNS_Response *resp)
Check a response from a client.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static int udp
Option -u: UDP requested.
static unsigned int phase
Processing stage that we are in.
DNS flags (largely RFC 1035 / RFC 2136).
char * payload
Payload of the UDP packet (the UDP payload), can be either query or already the response.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static uint64_t request_id_gen
Generator for unique request IDs.
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_DNS_CLIENT_RESPONSE.
#define GNUNET_UNUSED
gcc-ism to document unused arguments
The handle to a helper process.
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
Starts a helper and begins reading from it.
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
struct ClientRecord * next
Kept in doubly-linked list.
static struct GNUNET_DNSSTUB_Context * dnsstub
Handle to the DNS Stub resolver.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
static void send_request_to_client(struct RequestRecord *rr, struct ClientRecord *cr)
Show the payload of the given request record to the client (and wait for a response).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
This client wants to be called on the results of a DNS resolution (either resolved by PRE-RESOLUTION ...
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
void GNUNET_HELPER_stop(struct GNUNET_HELPER_Handle *h, int soft_kill)
Kills the helper, closes the pipe, frees the handle and calls wait() on the helper process...
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_REQUEST
Type of messages between the gnunet-helper-dns and the service.
Set this flag to see all requests just before they are returned to the network.
struct sockaddr_storage src_addr
Source address of the original request (for sending response).
Message from client to DNS service: here is my reply.
int GNUNET_OS_check_helper_binary(const char *binary, int check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv4 UDP checksum.
static char * helper_argv[8]
Command-line arguments we are giving to the hijacker process.
#define DNS_PORT
Port number for DNS.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
#define LOG(kind,...)
Generic logging shorthand.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
RequestPhase
Phases each request goes through.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static struct ClientRecord * clients_head
Head of DLL of clients we consult.
struct GNUNET_MQ_Handle * mq
Message queue to talk to client.
Showing the request to all monitor clients.
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv6 UDP checksum.
GNUNET_SERVICE_MAIN("dns", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(client_init, GNUNET_MESSAGE_TYPE_DNS_CLIENT_INIT, struct GNUNET_DNS_Register, NULL), GNUNET_MQ_hd_var_size(client_response, GNUNET_MESSAGE_TYPE_DNS_CLIENT_RESPONSE, struct GNUNET_DNS_Response, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static unsigned long long ipv6prefix
IPv6 prefix (0..127) from configuration file.
Handle to a client that is connected to a service.
enum RequestPhase phase
In which phase this this request?
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
static void handle_client_response(void *cls, const struct GNUNET_DNS_Response *resp)
Handle a response from a client.
#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_RESPONSE
Type of messages between the gnunet-helper-dns and the service.
static struct GNUNET_HELPER_Handle * hijacker
Handle to DNS hijacker helper process ("gnunet-helper-dns").
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_INIT
Initial message from client to DNS service for registration.
Showing the request to all monitor clients.
enum GNUNET_DNS_Flags flags
Flags for the client.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
Global Internet query is now pending.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Message from client to DNS service to register itself.
static void cleanup_rr(struct RequestRecord *rr)
We're done processing a DNS request, free associated memory.
static const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration to use.
Entry we keep for each active request.
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *progname)
Given the name of a helper, service or daemon binary construct the full path to the binary using the ...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
uint64_t request_id
Unique request ID.
Entry we keep for each client.
unsigned int client_wait_list_length
Length of the client_wait_list.
uint64_t request_id
ID of this request, also basis for hashing.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Handle to the stub resolver.
struct GNUNET_DNSSTUB_RequestSocket * GNUNET_DNSSTUB_resolve(struct GNUNET_DNSSTUB_Context *ctx, const void *request, size_t request_len, GNUNET_DNSSTUB_ResultCallback rc, void *rc_cls)
Perform DNS resolution using our default IP from init.
uint64_t request_id
Unique request ID.
uint32_t reserved
Always zero.
struct GNUNET_MQ_Envelope * env
static unsigned long long payload
How much data are we currently storing in the database?
static struct ClientRecord * clients_tail
Tail of DLL of clients we consult.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Set this flag to see all requests first prior to resolution (for monitoring).
static int process_helper_messages(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer fro...
#define GNUNET_MESSAGE_TYPE_DNS_HELPER
Type of messages between the gnunet-helper-dns and the service.
Handle to a message queue.
struct ClientRecord * prev
Kept in doubly-linked list.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected, setup our data structures.
enum RadiotapType __attribute__
static void request_done(struct RequestRecord *rr)
We're done with some request, finish processing.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's...
struct sockaddr_storage dst_addr
Destination address of the original request (for potential use as exit).
Message from DNS service to client: please handle a request.
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
struct ClientRecord ** client_wait_list
List of clients that still need to see this request (each entry is set to NULL when the client is don...
#define GNUNET_log(kind,...)
static void cleanup_task(void *cls)
Task run during shutdown.
static void handle_client_init(void *cls, const struct GNUNET_DNS_Register *reg)
We got a new client.
Request has just been received.
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".
This client should be called on requests that have not yet been resolved as this client provides a re...
static struct RequestRecord requests[UINT16_MAX+1]
Array of all open requests.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
UDP socket we are using for sending DNS requests to the Internet.
static int global_ret
Global return value from 'main'.
static void next_phase(struct RequestRecord *rr)
A client has completed its processing for this request.
struct GNUNET_SERVICE_Client * client
Handle to the client.
Some client has told us to drop the request.
GNUNET_DNS_Flags
Flags that specify when to call the client's handler.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
A client disconnected, clean up after it.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Showing the request to PRE-RESOLUTION clients to find an answer.
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
uint32_t drop_flag
Zero to drop, 1 for no change (no payload), 2 for update (message has payload).
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_malloc(size)
Wrapper around malloc.
IPC messages between DNS API and DNS service.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_DNSSTUB_RequestSocket * rs
Socket we are using to transmit this request (must match if we receive a response).
#define gettext_noop(String)
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg_, struct GNUNET_SERVICE_Handle *service)
static void process_dns_result(void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t r)
Callback called from DNSSTUB resolver when a resolution succeeded.
Client (or global DNS request) has resulted in a response.