Skip to content

Commit

Permalink
Add libsodium based DNSCurve implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
vstakhov committed Feb 11, 2014
1 parent d63bad4 commit 9743c3d
Show file tree
Hide file tree
Showing 6 changed files with 357 additions and 55 deletions.
38 changes: 37 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ SET(RSPAMD_VERSION_PATCH 0)

CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)

OPTION(ENABLE_CURVE "Enable DNSCurve plugin" OFF)

INCLUDE(CheckFunctionExists)
INCLUDE(CheckSymbolExists)

Expand All @@ -18,6 +20,36 @@ ENDIF(NOT HAVE_GETADDRINFO)

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")

IF(ENABLE_CURVE MATCHES "ON")
FIND_LIBRARY(LIBSODIUM NAMES sodium PATH_SUFFIXES lib64 lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw
/opt/local
/opt/csw
/opt
DOC "Path where the libsodium library can be found")
IF(NOT LIBSODIUM)
MESSAGE(FATAL_ERROR "libsodium is required for DNSCurve support")
ENDIF(NOT LIBSODIUM)

FIND_PATH(LIBSODIUM_INCLUDE sodium.h PATHS /opt/include
/usr/include
/usr/local/include
DOC "Path where the libsodium header files can be found")
IF(NOT LIBSODIUM_INCLUDE)
MESSAGE(FATAL_ERROR "libsodium header is required for DNSCurve support")
ENDIF(NOT LIBSODIUM_INCLUDE)
GET_FILENAME_COMPONENT(LIBSODIUM_PATH "${LIBSODIUM}" PATH)
INCLUDE_DIRECTORIES("${LIBSODIUM_INCLUDE}")
LINK_DIRECTORIES("${LIBSODIUM_PATH}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_SODIUM")
ENDIF(ENABLE_CURVE MATCHES "ON")


SET(LIBRDNSSRC src/dns_util.c
src/dns.c
src/punycode.c
Expand All @@ -34,4 +66,8 @@ ADD_SUBDIRECTORY(contrib/libottery)
ADD_SUBDIRECTORY(test)

ADD_LIBRARY(rdns STATIC ${LIBRDNSSRC})
TARGET_LINK_LIBRARIES(rdns rdns-ottery)
TARGET_LINK_LIBRARIES(rdns rdns-ottery)

IF(ENABLE_CURVE MATCHES "ON")
TARGET_LINK_LIBRARIES(rdns sodium)
ENDIF(ENABLE_CURVE MATCHES "ON")
16 changes: 12 additions & 4 deletions include/rdns.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

struct rdns_reply;
struct rdns_request;
struct rdns_io_channel;

typedef void (*dns_callback_type) (struct rdns_reply *reply, void *arg);

Expand Down Expand Up @@ -103,14 +104,17 @@ struct rdns_reply {
enum dns_rcode code;
};

typedef void (*rdns_periodic_callback)(void *user_data);

struct rdns_async_context {
void *data;
void* (*add_read)(void *priv_data, int fd, void *user_data);
void (*del_read)(void *priv_data, void *ev_data);
void* (*add_write)(void *priv_data, int fd, void *user_data);
void (*del_write)(void *priv_data, void *ev_data);
void* (*add_timer)(void *priv_data, double after, void *user_data);
void* (*add_periodic)(void *priv_data, double after, void *user_data);
void* (*add_periodic)(void *priv_data, double after,
rdns_periodic_callback cb, void *user_data);
void (*repeat_timer)(void *priv_data, void *ev_data);
void (*del_timer)(void *priv_data, void *ev_data);
void (*cleanup)(void *priv_data);
Expand All @@ -123,17 +127,22 @@ enum rdns_plugin_type {
RDNS_PLUGIN_NETWORK = 0//!< use the specified plugin instead of send/recv functions
};

typedef ssize_t (*rdns_network_send_callback) (int fd, const void *buf, size_t len);
typedef ssize_t (*rdns_network_recv_callback) (int fd, void *buf, size_t len);
typedef ssize_t (*rdns_network_send_callback) (struct rdns_request *req, void *plugin_data);
typedef ssize_t (*rdns_network_recv_callback) (struct rdns_io_channel *ioc, void *buf,
size_t len, void *plugin_data, struct rdns_request **req_out);
typedef void (*rdns_network_finish_callback) (struct rdns_request *req, void *plugin_data);
typedef void (*rdns_plugin_dtor_callback) (void *plugin_data);

struct rdns_plugin {
enum rdns_plugin_type type;
union {
struct {
rdns_network_send_callback send_cb;
rdns_network_recv_callback recv_cb;
rdns_network_finish_callback finish_cb;
} network_plugin;
} cb;
rdns_plugin_dtor_callback *dtor;
void *data;
};

Expand Down Expand Up @@ -233,7 +242,6 @@ void rdns_request_unref (struct rdns_request *req);

void rdns_process_read (int fd, void *arg);
void rdns_process_timer (void *arg);
void rdns_process_periodic (void *arg);
void rdns_process_retransmit (int fd, void *arg);

#endif
4 changes: 1 addition & 3 deletions include/rdns_curve.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
#ifndef RDNS_CURVE_H_
#define RDNS_CURVE_H_

#define RDSN_CURVE_PUBKEY_LEN 32

struct rdns_curve_ctx;

/**
Expand All @@ -42,7 +40,7 @@ struct rdns_curve_ctx* rdns_curve_ctx_new (void);
* @param pubkey pubkey bytes (must be `RDSN_CURVE_PUBKEY_LEN`)
*/
void rdns_curve_ctx_add_key (struct rdns_curve_ctx *ctx,
const char *name, const char *pubkey);
const char *name, const unsigned char *pubkey);

/**
* Destroy curve context
Expand Down
86 changes: 48 additions & 38 deletions src/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,8 @@ rdns_send_request (struct rdns_request *req, int fd, bool new_req)
r = send (fd, req->packet, req->pos, 0);
}
else {
r = resolver->network_plugin->cb.network_plugin.send_cb (fd, req->packet,
req->pos);
r = resolver->network_plugin->cb.network_plugin.send_cb (req,
resolver->network_plugin->data);
}
if (r == -1) {
if (errno == EAGAIN || errno == EINTR) {
Expand Down Expand Up @@ -691,48 +691,48 @@ rdns_make_reply (struct rdns_request *req, enum dns_rcode rcode)
return rep;
}

static bool
rdns_parse_reply (int sock, uint8_t *in, int r, struct rdns_resolver *resolver,
struct rdns_request **req_out, struct rdns_reply **_rep)
static struct rdns_request *
rdns_find_dns_request (uint8_t *in, struct rdns_io_channel *ioc)
{
struct dns_header *header = (struct dns_header *)in;
struct rdns_request *req;
struct rdns_reply *rep;
struct rdns_io_channel *ioc;
struct rdns_reply_entry *elt;
uint8_t *pos;
struct rdns_request *req;
int id;
int i, t;

/* First check header fields */
if (header->qr == 0) {
DNS_DEBUG ("got request while waiting for reply");
return false;
}

/* Find io channel */
HASH_FIND_INT (resolver->io_channels, &sock, ioc);
if (ioc == NULL) {
DNS_DEBUG ("io channel is not found for this resolver: %d", sock);
return false;
}

/* Now try to find corresponding request */
id = header->qid;
HASH_FIND_INT (ioc->requests, &id, req);
if (req == NULL) {
/* No such requests found */
DNS_DEBUG ("DNS request with id %d has not been found for IO channel", (int)id);
}

return req;
}

static bool
rdns_parse_reply (uint8_t *in, int r, struct rdns_request *req,
struct rdns_reply **_rep)
{
struct dns_header *header = (struct dns_header *)in;
struct rdns_reply *rep;
struct rdns_io_channel *ioc;
struct rdns_reply_entry *elt;
uint8_t *pos;

int i, t;

/* First check header fields */
if (header->qr == 0) {
DNS_DEBUG ("got request while waiting for reply");
return false;
}
*req_out = req;

/*
* Now we have request and query data is now at the end of header, so compare
* request QR section and reply QR section
*/
if ((pos = rdns_request_reply_cmp (req, in + sizeof (struct dns_header),
r - sizeof (struct dns_header))) == NULL) {
DNS_DEBUG ("DNS request with id %d is for different query, ignoring", (int)id);
DNS_DEBUG ("DNS request with id %d is for different query, ignoring", (int)req->id);
return false;
}
/*
Expand Down Expand Up @@ -770,23 +770,33 @@ rdns_parse_reply (int sock, uint8_t *in, int r, struct rdns_resolver *resolver,
void
rdns_process_read (int fd, void *arg)
{
struct rdns_resolver *resolver = arg;
struct rdns_request *req = NULL;
int r;
struct rdns_reply *rep;
uint8_t in[UDP_PACKET_SIZE];
struct rdns_io_channel *ioc = arg;
struct rdns_resolver *resolver;
struct rdns_request *req = NULL;
ssize_t r;
struct rdns_reply *rep;
uint8_t in[UDP_PACKET_SIZE];

/* This function is called each time when we have data on one of server's sockets */
resolver = ioc->resolver;

/* First read packet from socket */
if (resolver->network_plugin == NULL) {
r = read (fd, in, sizeof (in));
if (r > (int)(sizeof (struct dns_header) + sizeof (struct dns_query))) {
req = rdns_find_dns_request (in, ioc);
}
}
else {
r = resolver->network_plugin->cb.network_plugin.recv_cb (fd, in, sizeof (in));
r = resolver->network_plugin->cb.network_plugin.recv_cb (ioc, in,
sizeof (in), resolver->network_plugin->data, &req);
if (req == NULL &&
r > (int)(sizeof (struct dns_header) + sizeof (struct dns_query))) {
req = rdns_find_dns_request (in, ioc);
}
}
if (r > (int)(sizeof (struct dns_header) + sizeof (struct dns_query))) {
if (rdns_parse_reply (fd, in, r, resolver, &req, &rep)) {

if (req != NULL) {
if (rdns_parse_reply (in, r, req, &rep)) {
UPSTREAM_OK (req->io->srv);
rdns_request_ref (req);
req->func (rep, req->arg);
Expand Down Expand Up @@ -1105,7 +1115,7 @@ rdns_resolver_init (struct rdns_resolver *resolver)
ioc->srv = serv;
ioc->resolver = resolver;
ioc->async_io = resolver->async->add_read (resolver->async->data,
ioc->sock, resolver);
ioc->sock, ioc);
ioc->ref = 1;
serv->cur_io_channel = ioc;
CDL_PREPEND (serv->io_channels, ioc);
Expand All @@ -1116,7 +1126,7 @@ rdns_resolver_init (struct rdns_resolver *resolver)

if (resolver->async->add_periodic) {
resolver->periodic = resolver->async->add_periodic (resolver->async->data,
UPSTREAM_REVIVE_TIME, resolver);
UPSTREAM_REVIVE_TIME, rdns_process_periodic, resolver);
}

resolver->initialized = true;
Expand Down
Loading

0 comments on commit 9743c3d

Please sign in to comment.