summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/eth/CMakeLists.txt8
-rw-r--r--src/ipcpd/eth/eth.c17
-rw-r--r--src/ipcpd/ipcp.c13
-rw-r--r--src/ipcpd/shim-data.c34
-rw-r--r--src/ipcpd/shim-data.h19
-rw-r--r--src/ipcpd/udp/CMakeLists.txt34
-rw-r--r--src/ipcpd/udp/udp.c (renamed from src/ipcpd/udp/main.c)309
-rw-r--r--src/ipcpd/udp/udp4.c42
-rw-r--r--src/ipcpd/udp/udp6.c42
-rw-r--r--src/ipcpd/unicast/CMakeLists.txt5
10 files changed, 339 insertions, 184 deletions
diff --git a/src/ipcpd/eth/CMakeLists.txt b/src/ipcpd/eth/CMakeLists.txt
index 17ae74fc..44299a59 100644
--- a/src/ipcpd/eth/CMakeLists.txt
+++ b/src/ipcpd/eth/CMakeLists.txt
@@ -90,13 +90,13 @@ if (HAVE_ETH)
set(ETH_LLC_SOURCES
# Add source files here
- ${CMAKE_CURRENT_SOURCE_DIR}/llc.c
- )
+ llc.c
+ )
set(ETH_DIX_SOURCES
# Add source files here
- ${CMAKE_CURRENT_SOURCE_DIR}/dix.c
- )
+ dix.c
+ )
set(IPCP_ETH_LLC_TARGET ipcpd-eth-llc CACHE INTERNAL "")
set(IPCP_ETH_DIX_TARGET ipcpd-eth-dix CACHE INTERNAL "")
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index 1028ee03..d39b478c 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -113,7 +113,6 @@
#define ETH_MTU_MAX 1500
#endif /* BUILD_ETH_DIX */
-#define MAC_SIZE 6
#define ETH_TYPE_LENGTH_SIZE sizeof(uint16_t)
#define ETH_HEADER_SIZE (2 * MAC_SIZE + ETH_TYPE_LENGTH_SIZE)
@@ -694,11 +693,11 @@ static int eth_ipcp_name_query_req(const uint8_t * hash,
static int eth_ipcp_name_query_reply(const uint8_t * hash,
uint8_t * r_addr)
{
- uint64_t address = 0;
+ struct addr addr;
- memcpy(&address, r_addr, MAC_SIZE);
+ memcpy(&addr.mac, r_addr, MAC_SIZE);
- shim_data_dir_add_entry(eth_data.shim_data, hash, address);
+ shim_data_dir_add_entry(eth_data.shim_data, hash, addr);
shim_data_dir_query_respond(eth_data.shim_data, hash);
@@ -1699,7 +1698,7 @@ static int eth_ipcp_flow_alloc(int fd,
uint8_t ssap = 0;
#endif
uint8_t r_addr[MAC_SIZE];
- uint64_t addr = 0;
+ struct addr addr;
assert(hash);
@@ -1708,10 +1707,12 @@ static int eth_ipcp_flow_alloc(int fd,
HASH_VAL32(hash));
return -1;
}
+
addr = shim_data_dir_get_addr(eth_data.shim_data, hash);
+ memcpy(r_addr, &addr.mac, MAC_SIZE);
- pthread_rwlock_wrlock(&eth_data.flows_lock);
#ifdef BUILD_ETH_LLC
+ pthread_rwlock_wrlock(&eth_data.flows_lock);
ssap = bmp_allocate(eth_data.saps);
if (!bmp_is_id_valid(eth_data.saps, ssap)) {
pthread_rwlock_unlock(&eth_data.flows_lock);
@@ -1721,10 +1722,8 @@ static int eth_ipcp_flow_alloc(int fd,
eth_data.fd_to_ef[fd].sap = ssap;
eth_data.ef_to_fd[ssap] = fd;
-#endif
pthread_rwlock_unlock(&eth_data.flows_lock);
-
- memcpy(r_addr, &addr, MAC_SIZE);
+#endif
if (eth_ipcp_alloc(r_addr,
#if defined(BUILD_ETH_DIX)
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index a47b6226..62995727 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -74,7 +74,8 @@ static char * ipcp_type_str[] = {
"broadcast",
"eth-llc",
"eth-dix",
- "udp"
+ "udp4",
+ "udp6"
};
static char * dir_hash_str[] = {
@@ -228,8 +229,10 @@ static int ipcp_rib_read(const char * path,
strcpy(buf, "eth-llc\n");
else if (ipcpd.type == IPCP_ETH_DIX)
strcpy(buf, "eth-dix\n");
- else if (ipcpd.type == IPCP_UDP)
- strcpy(buf, "udp\n");
+ else if (ipcpd.type == IPCP_UDP4)
+ strcpy(buf, "udp4\n");
+ else if (ipcpd.type == IPCP_UDP6)
+ strcpy(buf, "udp6\n");
else
strcpy(buf, "bug\n");
}
@@ -455,7 +458,9 @@ static void do_bootstrap(ipcp_config_msg_t * conf_msg,
conf = ipcp_config_msg_to_s(conf_msg);
switch(conf.type) { /* FIXED algorithms */
- case IPCP_UDP:
+ case IPCP_UDP4:
+ /* FALLTHRU */
+ case IPCP_UDP6:
conf.layer_info.dir_hash_algo = (enum pol_dir_hash) HASH_MD5;
break;
case IPCP_BROADCAST:
diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c
index 1fac63ac..8801213a 100644
--- a/src/ipcpd/shim-data.c
+++ b/src/ipcpd/shim-data.c
@@ -51,7 +51,7 @@ struct reg_entry {
struct dir_entry {
struct list_head list;
uint8_t * hash;
- uint64_t addr;
+ struct addr addr;
};
static void destroy_dir_query(struct dir_query * query)
@@ -108,14 +108,12 @@ static void reg_entry_destroy(struct reg_entry * entry)
{
assert(entry);
- if (entry->hash != NULL)
- free(entry->hash);
-
+ free(entry->hash);
free(entry);
}
-static struct dir_entry * dir_entry_create(uint8_t * hash,
- uint64_t addr)
+static struct dir_entry * dir_entry_create(uint8_t * hash,
+ struct addr addr)
{
struct dir_entry * entry = malloc(sizeof(*entry));
if (entry == NULL)
@@ -133,9 +131,7 @@ static void dir_entry_destroy(struct dir_entry * entry)
{
assert(entry);
- if (entry->hash != NULL)
- free(entry->hash);
-
+ free(entry->hash);
free(entry);
}
@@ -258,13 +254,15 @@ static struct reg_entry * find_reg_entry_by_hash(struct shim_data * data,
static struct dir_entry * find_dir_entry(struct shim_data * data,
const uint8_t * hash,
- uint64_t addr)
+ struct addr addr)
{
struct list_head * h;
list_for_each(h, &data->directory) {
struct dir_entry * e = list_entry(h, struct dir_entry, list);
- if (e->addr == addr &&
- !memcmp(e->hash, hash, ipcp_dir_hash_len()))
+ if (memcmp(&e->addr, &addr, sizeof(addr)) != 0)
+ continue;
+
+ if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0)
return e;
}
@@ -364,7 +362,7 @@ bool shim_data_reg_has(struct shim_data * data,
int shim_data_dir_add_entry(struct shim_data * data,
const uint8_t * hash,
- uint64_t addr)
+ struct addr addr)
{
struct dir_entry * entry;
uint8_t * entry_hash;
@@ -400,7 +398,7 @@ int shim_data_dir_add_entry(struct shim_data * data,
int shim_data_dir_del_entry(struct shim_data * data,
const uint8_t * hash,
- uint64_t addr)
+ struct addr addr)
{
struct dir_entry * e;
if (data == NULL)
@@ -437,11 +435,11 @@ bool shim_data_dir_has(struct shim_data * data,
return ret;
}
-uint64_t shim_data_dir_get_addr(struct shim_data * data,
- const uint8_t * hash)
+struct addr shim_data_dir_get_addr(struct shim_data * data,
+ const uint8_t * hash)
{
struct dir_entry * entry;
- uint64_t addr;
+ struct addr addr = {0};
pthread_rwlock_rdlock(&data->dir_lock);
@@ -449,7 +447,7 @@ uint64_t shim_data_dir_get_addr(struct shim_data * data,
if (entry == NULL) {
pthread_rwlock_unlock(&data->dir_lock);
log_warn("No address for " HASH_FMT32 ".", HASH_VAL32(hash));
- return 0; /* undefined behaviour, 0 may be a valid address */
+ return addr; /* undefined behaviour, 0 may be a valid address */
}
addr = entry->addr;
diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h
index 372b4ea7..ea4ce413 100644
--- a/src/ipcpd/shim-data.h
+++ b/src/ipcpd/shim-data.h
@@ -25,9 +25,12 @@
#include <ouroboros/list.h>
-#include <sys/types.h>
#include <pthread.h>
#include <stdint.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+
+#define MAC_SIZE 6
enum dir_query_state {
QUERY_INIT = 0,
@@ -46,6 +49,14 @@ struct dir_query {
pthread_cond_t cond;
};
+struct addr {
+ union {
+ uint8_t mac[MAC_SIZE];
+ struct in_addr ip4;
+ struct in6_addr ip6;
+ };
+};
+
struct shim_data {
struct list_head registry;
pthread_rwlock_t reg_lock;
@@ -72,16 +83,16 @@ bool shim_data_reg_has(struct shim_data * data,
int shim_data_dir_add_entry(struct shim_data * data,
const uint8_t * hash,
- uint64_t addr);
+ struct addr addr);
int shim_data_dir_del_entry(struct shim_data * data,
const uint8_t * hash,
- uint64_t addr);
+ struct addr addr);
bool shim_data_dir_has(struct shim_data * data,
const uint8_t * hash);
-uint64_t shim_data_dir_get_addr(struct shim_data * data,
+struct addr shim_data_dir_get_addr(struct shim_data * data,
const uint8_t * hash);
struct dir_query * shim_data_dir_query_create(struct shim_data * data,
diff --git a/src/ipcpd/udp/CMakeLists.txt b/src/ipcpd/udp/CMakeLists.txt
index 5abf5a00..27e32094 100644
--- a/src/ipcpd/udp/CMakeLists.txt
+++ b/src/ipcpd/udp/CMakeLists.txt
@@ -12,16 +12,25 @@ include_directories(${CURRENT_BINARY_PARENT_DIR})
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
-set(IPCP_UDP_TARGET ipcpd-udp CACHE INTERNAL "")
+set(IPCP_UDP4_TARGET ipcpd-udp4 CACHE INTERNAL "")
+set(IPCP_UDP6_TARGET ipcpd-udp6 CACHE INTERNAL "")
-set(UDP_SOURCES
+set(UDP4_SOURCES
# Add source files here
- ${CMAKE_CURRENT_SOURCE_DIR}/main.c
- )
+ udp4.c
+)
-add_executable(ipcpd-udp ${UDP_SOURCES} ${IPCP_SOURCES})
+set(UDP6_SOURCES
+ # Add source files here
+ udp6.c
+)
+
+add_executable(ipcpd-udp4 ${UDP4_SOURCES} ${IPCP_SOURCES})
+target_link_libraries(ipcpd-udp4 LINK_PUBLIC ouroboros-dev)
+
+add_executable(ipcpd-udp6 ${UDP6_SOURCES} ${IPCP_SOURCES})
+target_link_libraries(ipcpd-udp6 LINK_PUBLIC ouroboros-dev)
-target_link_libraries(ipcpd-udp LINK_PUBLIC ouroboros-dev)
# Find the nsupdate executable
find_program(NSUPDATE_EXECUTABLE
@@ -55,15 +64,18 @@ else ()
endif ()
set(IPCP_UDP_RD_THR 3 CACHE STRING
- "Number of reader threads in UDP IPCP")
+ "Number of reader threads in UDP IPCPs")
set(IPCP_UDP_WR_THR 3 CACHE STRING
- "Number of writer threads in UDP IPCP")
+ "Number of writer threads in UDP IPCPs")
set(IPCP_UDP_MPL 5000 CACHE STRING
- "Default maximum packet lifetime for the UDP IPCP, in ms")
+ "Default maximum packet lifetime for the UDP IPCPs, in ms")
include(AddCompileFlags)
if (CMAKE_BUILD_TYPE MATCHES "Debug*")
- add_compile_flags(ipcpd-udp -DCONFIG_OUROBOROS_DEBUG)
+ add_compile_flags(ipcpd-udp4 -DCONFIG_OUROBOROS_DEBUG)
+ add_compile_flags(ipcpd-udp6 -DCONFIG_OUROBOROS_DEBUG)
endif ()
-install(TARGETS ipcpd-udp RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
+install(TARGETS ipcpd-udp4 RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
+install(TARGETS ipcpd-udp6 RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
+
diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/udp.c
index 5f770a61..d6d38362 100644
--- a/src/ipcpd/udp/main.c
+++ b/src/ipcpd/udp/udp.c
@@ -20,23 +20,14 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#if defined(__linux__) || defined(__CYGWIN__)
-#define _DEFAULT_SOURCE
-#else
-#define _POSIX_C_SOURCE 200112L
-#endif
-
#include "config.h"
-#define OUROBOROS_PREFIX "ipcpd/udp"
-
#include <ouroboros/bitmap.h>
#include <ouroboros/endian.h>
#include <ouroboros/hash.h>
#include <ouroboros/list.h>
#include <ouroboros/utils.h>
#include <ouroboros/dev.h>
-#include <ouroboros/ipcp-dev.h>
#include <ouroboros/fqueue.h>
#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
@@ -59,12 +50,11 @@
#define FLOW_REQ 1
#define FLOW_REPLY 2
-#define THIS_TYPE IPCP_UDP
-#define IPCP_UDP_MAX_PACKET_SIZE 8980
#define OUR_HEADER_LEN sizeof(uint32_t) /* adds eid */
-#define IPCP_UDP_BUF_SIZE 8980
-#define IPCP_UDP_MSG_SIZE 8980
+#define IPCP_UDP_BUF_SIZE IPCP_UDP_MAX_PACKET_SIZE
+#define IPCP_UDP_MSG_SIZE IPCP_UDP_MAX_PACKET_SIZE
+
#define DNS_TTL 86400
#define SADDR ((struct sockaddr *) &udp_data.s_saddr)
@@ -102,24 +92,23 @@ struct mgmt_msg {
} __attribute__((packed));
struct mgmt_frame {
- struct list_head next;
- struct sockaddr_in r_saddr;
- uint8_t buf[MGMT_FRAME_BUF_SIZE];
- size_t len;
+ struct list_head next;
+ struct __SOCKADDR r_saddr;
+ uint8_t buf[MGMT_FRAME_BUF_SIZE];
+ size_t len;
};
/* UDP flow */
struct uf {
- int d_eid;
- struct sockaddr_in r_saddr;
+ int d_eid;
+ struct __SOCKADDR r_saddr;
};
struct {
struct shim_data * shim_data;
- uint32_t dns_addr;
-
- struct sockaddr_in s_saddr;
+ struct __ADDR dns_addr;
+ struct __SOCKADDR s_saddr;
int s_fd;
fset_t * np1_flows;
@@ -136,6 +125,12 @@ struct {
struct list_head mgmt_frames;
} udp_data;
+static const char * __inet_ntop(const struct __ADDR * addr,
+ char * buf)
+{
+ return inet_ntop(__AF, addr, buf, __ADDRSTRLEN);
+}
+
static int udp_data_init(void)
{
int i;
@@ -197,11 +192,11 @@ static void udp_data_fini(void)
pthread_mutex_destroy(&udp_data.mgmt_lock);
}
-static int udp_ipcp_port_alloc(const struct sockaddr_in * r_saddr,
- uint32_t s_eid,
- const uint8_t * dst,
- qosspec_t qs,
- const buffer_t * data)
+static int udp_ipcp_port_alloc(const struct __SOCKADDR * r_saddr,
+ uint32_t s_eid,
+ const uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data)
{
uint8_t * buf;
struct mgmt_msg * msg;
@@ -236,6 +231,8 @@ static int udp_ipcp_port_alloc(const struct sockaddr_in * r_saddr,
if (sendto(udp_data.s_fd, msg, len + data->len,
SENDTO_FLAGS,
(const struct sockaddr *) r_saddr, sizeof(*r_saddr)) < 0) {
+ log_err("Failed to send flow allocation request: %s.",
+ strerror(errno));
free(buf);
return -1;
}
@@ -245,11 +242,11 @@ static int udp_ipcp_port_alloc(const struct sockaddr_in * r_saddr,
return 0;
}
-static int udp_ipcp_port_alloc_resp(const struct sockaddr_in * r_saddr,
- uint32_t s_eid,
- uint32_t d_eid,
- int8_t response,
- const buffer_t * data)
+static int udp_ipcp_port_alloc_resp(const struct __SOCKADDR * r_saddr,
+ uint32_t s_eid,
+ uint32_t d_eid,
+ int8_t response,
+ const buffer_t * data)
{
struct mgmt_msg * msg;
@@ -278,11 +275,11 @@ static int udp_ipcp_port_alloc_resp(const struct sockaddr_in * r_saddr,
return 0;
}
-static int udp_ipcp_port_req(struct sockaddr_in * c_saddr,
- int d_eid,
- const uint8_t * dst,
- qosspec_t qs,
- const buffer_t * data)
+static int udp_ipcp_port_req(struct __SOCKADDR * c_saddr,
+ int d_eid,
+ const uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data)
{
int fd;
@@ -305,20 +302,26 @@ static int udp_ipcp_port_req(struct sockaddr_in * c_saddr,
return 0;
}
-static int udp_ipcp_port_alloc_reply(const struct sockaddr_in * saddr,
- uint32_t s_eid,
- uint32_t d_eid,
- int8_t response,
- const buffer_t * data)
+static int udp_ipcp_port_alloc_reply(const struct __SOCKADDR * saddr,
+ uint32_t s_eid,
+ uint32_t d_eid,
+ int8_t response,
+ const buffer_t * data)
{
time_t mpl = IPCP_UDP_MPL;
pthread_rwlock_wrlock(&udp_data.flows_lock);
if (memcmp(&udp_data.fd_to_uf[s_eid].r_saddr, saddr, sizeof(*saddr))) {
+ char ipstr[__ADDRSTRLEN];
pthread_rwlock_unlock(&udp_data.flows_lock);
- log_err("Flow allocation reply for %u from wrong source.",
- s_eid);
+ #ifdef BUILD_IPCP_UDP4
+ __inet_ntop(&saddr->sin_addr, ipstr);
+ #else
+ __inet_ntop(&saddr->sin6_addr, ipstr);
+ #endif
+ log_err("Flow allocation reply for %u from wrong source %s.",
+ s_eid, ipstr);
return -1;
}
@@ -338,9 +341,9 @@ static int udp_ipcp_port_alloc_reply(const struct sockaddr_in * saddr,
return 0;
}
-static int udp_ipcp_mgmt_frame(const uint8_t * buf,
- size_t len,
- struct sockaddr_in c_saddr)
+static int udp_ipcp_mgmt_frame(struct __SOCKADDR c_saddr,
+ const uint8_t * buf,
+ size_t len)
{
struct mgmt_msg * msg;
size_t msg_len;
@@ -411,7 +414,7 @@ static void * udp_ipcp_mgmt_handler(void * o)
pthread_mutex_unlock(&udp_data.mgmt_lock);
- udp_ipcp_mgmt_frame(frame->buf, frame->len, frame->r_saddr);
+ udp_ipcp_mgmt_frame(frame->r_saddr, frame->buf, frame->len);
free(frame);
}
@@ -438,7 +441,7 @@ static void * udp_ipcp_packet_reader(void * o)
while (true) {
struct mgmt_frame * frame;
- struct sockaddr_in r_saddr;
+ struct __SOCKADDR r_saddr;
socklen_t len;
struct shm_du_buff * sdb;
uint8_t * head;
@@ -521,9 +524,9 @@ static void * udp_ipcp_packet_writer(void * o)
pthread_cleanup_push(cleanup_fqueue, fq);
while (true) {
- struct sockaddr_in saddr;
- int eid;
- int fd;
+ struct __SOCKADDR saddr;
+ int eid;
+ int fd;
fevent(udp_data.np1_flows, fq, NULL);
while ((fd = fqueue_next(fq)) >= 0) {
struct shm_du_buff * sdb;
@@ -578,29 +581,39 @@ static void * udp_ipcp_packet_writer(void * o)
return (void *) 1;
}
-static const char * inet4_ntop(const void * addr,
- char * buf)
+static bool is_addr_specified(const struct __ADDR * addr)
{
- return inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN);
+#ifdef BUILD_IPCP_UDP4
+ return addr->s_addr != 0;
+#else
+ return !IN6_IS_ADDR_UNSPECIFIED(addr);
+#endif
}
static int udp_ipcp_bootstrap(struct ipcp_config * conf)
{
- char ipstr[INET_ADDRSTRLEN];
- char dnsstr[INET_ADDRSTRLEN];
+ char ipstr[__ADDRSTRLEN];
+ char dnsstr[__ADDRSTRLEN];
int i = 1;
+#ifdef BUILD_IPCP_UDP4
+ struct udp4_config * udp;
+ udp = &conf->udp4;
+#else
+ struct udp6_config * udp;
+ udp = &conf->udp6;
+#endif
assert(conf != NULL);
assert(conf->type == THIS_TYPE);
assert(conf->layer_info.dir_hash_algo == (enum pol_dir_hash) HASH_MD5);
- if (inet4_ntop(&conf->udp.ip_addr, ipstr) == NULL) {
+ if (__inet_ntop(&udp->ip_addr, ipstr) == NULL) {
log_err("Failed to convert IP address.");
return -1;
}
- if (conf->udp.dns_addr != 0) {
- if (inet4_ntop(&conf->udp.dns_addr, dnsstr) == NULL) {
+ if (is_addr_specified(&udp->dns_addr)) {
+ if (__inet_ntop(&udp->dns_addr, dnsstr) == NULL) {
log_err("Failed to convert DNS address.");
return -1;
}
@@ -612,24 +625,29 @@ static int udp_ipcp_bootstrap(struct ipcp_config * conf)
}
/* UDP listen server */
- udp_data.s_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ udp_data.s_fd = socket(__AF, SOCK_DGRAM, IPPROTO_UDP);
if (udp_data.s_fd < 0) {
log_err("Can't create socket: %s", strerror(errno));
goto fail_socket;
}
memset((char *) &udp_data.s_saddr, 0, sizeof(udp_data.s_saddr));
- udp_data.s_saddr.sin_family = AF_INET;
- udp_data.s_saddr.sin_addr.s_addr = conf->udp.ip_addr;
- udp_data.s_saddr.sin_port = htons(conf->udp.port);
-
+#ifdef BUILD_IPCP_UDP4
+ udp_data.s_saddr.sin_family = AF_INET;
+ udp_data.s_saddr.sin_addr = udp->ip_addr;
+ udp_data.s_saddr.sin_port = htons(udp->port);
+#else
+ udp_data.s_saddr.sin6_family = AF_INET6;
+ udp_data.s_saddr.sin6_addr = udp->ip_addr;
+ udp_data.s_saddr.sin6_port = htons(udp->port);
+#endif
if (bind(udp_data.s_fd, SADDR, SADDR_SIZE) < 0) {
log_err("Couldn't bind to %s:%d. %s.",
- ipstr, conf->udp.port, strerror(errno));
+ ipstr, udp->port, strerror(errno));
goto fail_bind;
}
- udp_data.dns_addr = conf->udp.dns_addr;
+ udp_data.dns_addr = udp->dns_addr;
if (pthread_create(&udp_data.mgmt_handler, NULL,
udp_ipcp_mgmt_handler, NULL)) {
@@ -653,10 +671,10 @@ static int udp_ipcp_bootstrap(struct ipcp_config * conf)
}
}
- log_dbg("Bootstrapped IPCP over UDP with pid %d.", getpid());
+ log_dbg("Bootstrapped " TYPE_STR " with pid %d.", getpid());
log_dbg("Bound to IP address %s.", ipstr);
- log_dbg("Using port %u.", conf->udp.port);
- if (conf->udp.dns_addr != 0)
+ log_dbg("Using port %u.", udp->port);
+ if (is_addr_specified(&udp_data.dns_addr))
log_dbg("DNS server address is %s.", dnsstr);
else
log_dbg("DNS server not in use.");
@@ -734,26 +752,26 @@ static int ddns_send(char * cmd)
return 0;
}
-static uint32_t ddns_resolve(char * name,
- uint32_t dns_addr)
+static struct __ADDR ddns_resolve(char * name,
+ struct __ADDR dns_addr)
{
- pid_t pid = -1;
- int wstatus;
- int pipe_fd[2];
- char dnsstr[INET_ADDRSTRLEN];
- char buf[IPCP_UDP_BUF_SIZE];
- ssize_t count = 0;
- char * substr = NULL;
- char * substr2 = NULL;
- char * addr_str = "Address:";
- uint32_t ip_addr = 0;
-
- if (inet4_ntop(&dns_addr, dnsstr) == NULL)
- return 0;
+ pid_t pid = -1;
+ int wstatus;
+ int pipe_fd[2];
+ char dnsstr[__ADDRSTRLEN];
+ char buf[IPCP_UDP_BUF_SIZE];
+ ssize_t count = 0;
+ char * substr = NULL;
+ char * substr2 = NULL;
+ char * addr_str = "Address:";
+ struct __ADDR ip_addr = __ADDR_ANY_INIT;
+
+ if (__inet_ntop(&dns_addr, dnsstr) == NULL)
+ return ip_addr;
if (pipe(pipe_fd)) {
log_err("Failed to create pipe: %s.", strerror(errno));
- return 0;
+ return ip_addr;
}
pid = fork();
@@ -761,7 +779,7 @@ static uint32_t ddns_resolve(char * name,
log_err("Failed to fork: %s.", strerror(errno));
close(pipe_fd[0]);
close(pipe_fd[1]);
- return -1;
+ return ip_addr;
}
if (pid == 0) {
@@ -781,7 +799,7 @@ static uint32_t ddns_resolve(char * name,
if (count <= 0) {
log_err("Failed to communicate with nslookup.");
close(pipe_fd[0]);
- return 0;
+ return ip_addr;
}
close(pipe_fd[0]);
@@ -802,12 +820,13 @@ static uint32_t ddns_resolve(char * name,
if (substr2 == NULL || strstr(substr2, addr_str) == NULL) {
log_err("Failed to resolve DNS address.");
- return 0;
+ return ip_addr;
}
- if (inet_pton(AF_INET, substr2 + strlen(addr_str) + 1, &ip_addr) != 1) {
+ if (inet_pton(__AF, substr2 + strlen(addr_str) + 1, &ip_addr) != 1) {
log_err("Failed to resolve DNS address.");
- return 0;
+ assert(!is_addr_specified(&ip_addr));
+ return ip_addr;
}
return ip_addr;
@@ -817,11 +836,11 @@ static uint32_t ddns_resolve(char * name,
static int udp_ipcp_reg(const uint8_t * hash)
{
#ifdef HAVE_DDNS
- char ipstr[INET_ADDRSTRLEN];
- char dnsstr[INET_ADDRSTRLEN];
- char cmd[1000];
- uint32_t dns_addr;
- uint32_t ip_addr;
+ char ipstr[__ADDRSTRLEN];
+ char dnsstr[__ADDRSTRLEN];
+ char cmd[1000];
+ struct __ADDR dns_addr;
+ struct __ADDR ip_addr;
#endif
char * hashstr;
@@ -847,16 +866,19 @@ static int udp_ipcp_reg(const uint8_t * hash)
dns_addr = udp_data.dns_addr;
- if (dns_addr != 0) {
- ip_addr = udp_data.s_saddr.sin_addr.s_addr;
-
- if (inet4_ntop(&ip_addr, ipstr) == NULL) {
+ if (is_addr_specified(&dns_addr)) {
+#ifdef BUILD_IPCP_UDP4
+ ip_addr = udp_data.s_saddr.sin_addr;
+#else
+ ip_addr = udp_data.s_saddr.sin6_addr;
+#endif
+ if (__inet_ntop(&ip_addr, ipstr) == NULL) {
log_err("Failed to convert IP address to string.");
free(hashstr);
return -1;
}
- if (inet4_ntop(&dns_addr, dnsstr) == NULL) {
+ if (__inet_ntop(&dns_addr, dnsstr) == NULL) {
log_err("Failed to convert DNS address to string.");
free(hashstr);
return -1;
@@ -881,12 +903,12 @@ static int udp_ipcp_reg(const uint8_t * hash)
static int udp_ipcp_unreg(const uint8_t * hash)
{
#ifdef HAVE_DDNS
- char dnsstr[INET_ADDRSTRLEN];
+ char dnsstr[__ADDRSTRLEN];
/* max DNS name length + max IP length + max command length */
- char cmd[100];
- uint32_t dns_addr;
+ char cmd[100];
+ struct __ADDR dns_addr;
#endif
- char * hashstr;
+ char * hashstr;
assert(hash);
@@ -903,8 +925,8 @@ static int udp_ipcp_unreg(const uint8_t * hash)
dns_addr = udp_data.dns_addr;
- if (dns_addr != 0) {
- if (inet4_ntop(&dns_addr, dnsstr) == NULL) {
+ if (is_addr_specified(&dns_addr)) {
+ if (__inet_ntop(&dns_addr, dnsstr) == NULL) {
log_err("Failed to convert DNS address to string.");
free(hashstr);
return -1;
@@ -925,11 +947,13 @@ static int udp_ipcp_unreg(const uint8_t * hash)
static int udp_ipcp_query(const uint8_t * hash)
{
- uint32_t ip_addr = 0;
- char * hashstr;
- struct hostent * h;
+ struct addr addr = {};
+ char * hashstr;
+ struct addrinfo hints;
+ struct addrinfo * ai;
#ifdef HAVE_DDNS
- uint32_t dns_addr = 0;
+ struct __ADDR dns_addr = __ADDR_ANY_INIT;
+ struct __ADDR ip_addr = __ADDR_ANY_INIT;
#endif
assert(hash);
@@ -949,28 +973,42 @@ static int udp_ipcp_query(const uint8_t * hash)
#ifdef HAVE_DDNS
dns_addr = udp_data.dns_addr;
- if (dns_addr != 0) {
+ if (is_addr_specified(&dns_addr)) {
ip_addr = ddns_resolve(hashstr, dns_addr);
- if (ip_addr == 0) {
+ if (!is_addr_specified(&ip_addr)) {
log_err("Could not resolve %s.", hashstr);
free(hashstr);
return -1;
}
} else {
#endif
- h = gethostbyname(hashstr);
- if (h == NULL) {
- log_err("Could not resolve %s.", hashstr);
+ memset(&hints, 0, sizeof(hints));
+
+ hints.ai_family = __AF;
+ if (getaddrinfo(hashstr, NULL, &hints, &ai) != 0) {
+ log_err("Could not resolve %s: %s.", hashstr,
+ gai_strerror(errno));
free(hashstr);
return -1;
}
- ip_addr = *((uint32_t *) (h->h_addr_list[0]));
+ if (ai->ai_family != __AF) {
+ log_err("Wrong addres family for %s.", hashstr);
+ freeaddrinfo(ai);
+ free(hashstr);
+ return -1;
+ }
+
+ #ifdef BUILD_IPCP_UDP4
+ addr.ip4 = ((struct sockaddr_in *) (ai->ai_addr))->sin_addr;
+ #else
+ addr.ip6 = ((struct sockaddr_in6 *) (ai->ai_addr))->sin6_addr;
+ #endif
+ freeaddrinfo(ai);
#ifdef HAVE_DDNS
}
#endif
-
- if (shim_data_dir_add_entry(udp_data.shim_data, hash, ip_addr)) {
+ if (shim_data_dir_add_entry(udp_data.shim_data, hash, addr)) {
log_err("Failed to add directory entry.");
free(hashstr);
return -1;
@@ -986,9 +1024,10 @@ static int udp_ipcp_flow_alloc(int fd,
qosspec_t qs,
const buffer_t * data)
{
- struct sockaddr_in r_saddr; /* Server address */
- uint32_t ip_addr = 0;
- char ipstr[INET_ADDRSTRLEN];
+ struct __SOCKADDR r_saddr; /* Server address */
+ struct __ADDR ip_addr;
+ struct addr addr;
+ char ipstr[__ADDRSTRLEN];
(void) qs;
@@ -999,9 +1038,13 @@ static int udp_ipcp_flow_alloc(int fd,
return -1;
}
- ip_addr = (uint32_t) shim_data_dir_get_addr(udp_data.shim_data, dst);
-
- if (inet4_ntop(&ip_addr, ipstr) == NULL) {
+ addr = shim_data_dir_get_addr(udp_data.shim_data, dst);
+#ifdef BUILD_IPCP_UDP4
+ ip_addr = addr.ip4;
+#else
+ ip_addr = addr.ip6;
+#endif
+ if (__inet_ntop(&ip_addr, ipstr) == NULL) {
log_err("Could not convert IP address.");
return -1;
}
@@ -1010,9 +1053,15 @@ static int udp_ipcp_flow_alloc(int fd,
HASH_VAL32(dst), ipstr);
memset((char *) &r_saddr, 0, sizeof(r_saddr));
- r_saddr.sin_family = AF_INET;
- r_saddr.sin_addr.s_addr = ip_addr;
- r_saddr.sin_port = udp_data.s_saddr.sin_port;
+#ifdef BUILD_IPCP_UDP4
+ r_saddr.sin_family = AF_INET;
+ r_saddr.sin_addr = addr.ip4;
+ r_saddr.sin_port = udp_data.s_saddr.sin_port;
+#else
+ r_saddr.sin6_family = AF_INET6;
+ r_saddr.sin6_addr = addr.ip6;
+ r_saddr.sin6_port = udp_data.s_saddr.sin6_port;
+#endif
if (udp_ipcp_port_alloc(&r_saddr, fd, dst, qs, data) < 0) {
log_err("Could not allocate port.");
@@ -1035,8 +1084,8 @@ static int udp_ipcp_flow_alloc_resp(int fd,
int resp,
const buffer_t * data)
{
- struct sockaddr_in saddr;
- int d_eid;
+ struct __SOCKADDR saddr;
+ int d_eid;
if (ipcp_wait_flow_resp(fd) < 0) {
log_err("Failed to wait for flow response.");
diff --git a/src/ipcpd/udp/udp4.c b/src/ipcpd/udp/udp4.c
new file mode 100644
index 00000000..07d5f818
--- /dev/null
+++ b/src/ipcpd/udp/udp4.c
@@ -0,0 +1,42 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * IPC process over UDP/IPv4
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#else
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#include <ouroboros/ipcp-dev.h>
+
+#define BUILD_IPCP_UDP4
+#define THIS_TYPE IPCP_UDP4
+#define TYPE_STR "IPCP over UDP/IPv4"
+#define OUROBOROS_PREFIX "ipcpd/udp4"
+#define IPCP_UDP_MAX_PACKET_SIZE 8980
+#define __AF AF_INET
+#define __ADDRSTRLEN INET_ADDRSTRLEN
+#define __SOCKADDR sockaddr_in
+#define __ADDR in_addr
+#define __ADDR_ANY_INIT { .s_addr = INADDR_ANY }
+
+#include "udp.c"
diff --git a/src/ipcpd/udp/udp6.c b/src/ipcpd/udp/udp6.c
new file mode 100644
index 00000000..b7924a3f
--- /dev/null
+++ b/src/ipcpd/udp/udp6.c
@@ -0,0 +1,42 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * IPC process over UDP/IPv6
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#else
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#include <ouroboros/ipcp-dev.h>
+
+#define BUILD_IPCP_UDP6
+#define THIS_TYPE IPCP_UDP6
+#define TYPE_STR "IPCP over UDP/IPv6"
+#define OUROBOROS_PREFIX "ipcpd/udp6"
+#define IPCP_UDP_MAX_PACKET_SIZE 8952
+#define __AF AF_INET6
+#define __ADDRSTRLEN INET6_ADDRSTRLEN
+#define __SOCKADDR sockaddr_in6
+#define __ADDR in6_addr
+#define __ADDR_ANY_INIT IN6ADDR_ANY_INIT
+
+#include "udp.c"
diff --git a/src/ipcpd/unicast/CMakeLists.txt b/src/ipcpd/unicast/CMakeLists.txt
index 2df0bae0..ced045e6 100644
--- a/src/ipcpd/unicast/CMakeLists.txt
+++ b/src/ipcpd/unicast/CMakeLists.txt
@@ -73,7 +73,4 @@ install(TARGETS ipcpd-unicast RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
add_subdirectory(pff/tests)
add_subdirectory(routing/tests)
-
-if (NOT GNU)
- add_subdirectory(dir/tests)
-endif ()
+add_subdirectory(dir/tests)