summaryrefslogtreecommitdiff
path: root/src/ipcpd/shim-udp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/shim-udp')
-rw-r--r--src/ipcpd/shim-udp/CMakeLists.txt52
-rw-r--r--src/ipcpd/shim-udp/main.c208
-rw-r--r--src/ipcpd/shim-udp/shim_udp_config.h.in29
3 files changed, 235 insertions, 54 deletions
diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt
index c71fa00b..e10a8ca6 100644
--- a/src/ipcpd/shim-udp/CMakeLists.txt
+++ b/src/ipcpd/shim-udp/CMakeLists.txt
@@ -1,5 +1,7 @@
-get_filename_component(CURRENT_SOURCE_PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(CURRENT_BINARY_PARENT_DIR ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+get_filename_component(CURRENT_SOURCE_PARENT_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
+get_filename_component(CURRENT_BINARY_PARENT_DIR
+ ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
@@ -18,33 +20,59 @@ IF(NOT CMAKE_HAVE_GETHOSTBYNAME)
IF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lnsl)
ELSE (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
- CHECK_LIBRARY_EXISTS("bsd" "gethostbyname" "" CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
+ CHECK_LIBRARY_EXISTS("bsd" "gethostbyname" ""
+ CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
IF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lbsd)
ENDIF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
ENDIF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
ENDIF(NOT CMAKE_HAVE_GETHOSTBYNAME)
-# Find the nsupdate executable
-find_program(NSUPDATE_EXECUTABLE
- NAMES nsupdate
- DOC "The nsupdate tool that enables DDNS")
+# Enable DNS by default
+if (NOT DISABLE_DNS MATCHES True)
+ # Find the nsupdate executable
+ find_program(NSUPDATE_EXECUTABLE
+ NAMES nsupdate
+ DOC "The nsupdate tool that enables DDNS")
-if (${NSUPDATE_EXECUTABLE} STREQUAL "NSUPDATE_EXECUTABLE-NOTFOUND")
- message(FATAL_ERROR "Could not find nsupdate, which is needed for DDNS")
-else()
- message("-- Found nsupdate: ${NSUPDATE_EXECUTABLE}")
+ if (${NSUPDATE_EXECUTABLE} STREQUAL "NSUPDATE_EXECUTABLE-NOTFOUND")
+ message(FATAL_ERROR "Could not find nsupdate, which is needed for DDNS")
+ else()
+ message("-- Found nsupdate: ${NSUPDATE_EXECUTABLE}")
+ endif()
+
+ # Find the nslookup executable
+ find_program(NSLOOKUP_EXECUTABLE
+ NAMES nslookup
+ DOC "The nslookup tool that resolves DNS names")
+
+ if (${NSLOOKUP_EXECUTABLE} STREQUAL "NSLOOKUP_EXECUTABLE-NOTFOUND")
+ message(FATAL_ERROR
+ "Could not find nslookup, which is needed for DNS resolution")
+ else()
+ message("-- Found nslookup: ${NSLOOKUP_EXECUTABLE}")
+ endif()
endif()
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/shim_udp_config.h.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h")
+
SET(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET")
set(SHIM_UDP_SOURCES
# Add source files here
${CMAKE_CURRENT_SOURCE_DIR}/main.c)
-add_executable (ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES})
+add_executable (ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES}
+ "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h")
target_link_libraries (ipcpd-shim-udp LINK_PUBLIC ouroboros)
+# Enable DNS by default
+if (NOT DISABLE_DNS MATCHES True)
+ MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_ENABLE_DNS)
+endif()
+
include(MacroAddCompileFlags)
if (CMAKE_BUILD_TYPE MATCHES Debug)
MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG)
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index e213f019..bb5c233f 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -23,6 +23,7 @@
#include <ouroboros/config.h>
#include "ipcp.h"
#include "flow.h"
+#include "shim_udp_config.h"
#include <ouroboros/shm_du_map.h>
#include <ouroboros/shm_ap_rbuff.h>
#include <ouroboros/list.h>
@@ -31,6 +32,7 @@
#include <ouroboros/dif_config.h>
#include <ouroboros/sockets.h>
#include <ouroboros/bitmap.h>
+#include <ouroboros/dev.h>
#define OUROBOROS_PREFIX "ipcpd/shim-udp"
@@ -74,19 +76,6 @@ struct ipcp * _ipcp;
* the info
*/
-#define UNKNOWN_AP "__UNKNOWN_AP__"
-#define UNKNOWN_AE "__UNKNOWN_AE__"
-
-#define AP_MAX_FLOWS 256
-
-#ifndef DU_BUFF_HEADSPACE
- #define DU_BUFF_HEADSPACE 128
-#endif
-
-#ifndef DU_BUFF_TAILSPACE
- #define DU_BUFF_TAILSPACE 0
-#endif
-
/* the shim needs access to these internals */
struct shim_ap_data {
instance_name_t * api;
@@ -332,8 +321,11 @@ static void * ipcp_udp_listener()
}
/* echo back the packet */
- while(send(fd, buf, strlen(buf), 0) < 0)
- ;
+ if (send(fd, buf, strlen(buf), 0) < 0) {
+ LOG_ERR("Failed to echo back the packet.");
+ close(fd);
+ continue;
+ }
/* reply to IRM */
@@ -408,17 +400,27 @@ int ipcp_udp_bootstrap(struct dif_config * conf)
return -1;
}
- inet_ntop(AF_INET,
- &conf->ip_addr,
- ipstr,
- INET_ADDRSTRLEN);
+ if (inet_ntop(AF_INET,
+ &conf->ip_addr,
+ ipstr,
+ INET_ADDRSTRLEN) == NULL) {
+ LOG_ERR("Failed to convert IP address");
+ return -1;
+ }
- if (conf->dns_addr != 0)
- inet_ntop(AF_INET,
- &conf->dns_addr,
- dnsstr,
- INET_ADDRSTRLEN);
- else
+ if (conf->dns_addr != 0) {
+ if (inet_ntop(AF_INET,
+ &conf->dns_addr,
+ dnsstr,
+ INET_ADDRSTRLEN) == NULL) {
+ LOG_ERR("Failed to convert DNS address");
+ return -1;
+ }
+#ifndef CONFIG_OUROBOROS_ENABLE_DNS
+ LOG_WARN("DNS address ignored since shim-udp was "
+ "compiled without DNS support.");
+#endif
+ } else
strcpy(dnsstr, "not set");
shim_data(_ipcp)->ip_addr = conf->ip_addr;
@@ -480,7 +482,9 @@ int ipcp_udp_bootstrap(struct dif_config * conf)
return 0;
}
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
/* FIXME: Dependency on nsupdate to be removed in the end */
+/* NOTE: Disgusted with this crap */
static int ddns_send(char * cmd)
{
pid_t pid = 0;
@@ -509,7 +513,7 @@ static int ddns_send(char * cmd)
close(pipe_fd[0]);
if (write(pipe_fd[1], cmd, strlen(cmd)) == -1) {
- LOG_ERR("Failed to register with DNS server.");
+ LOG_ERR("Failed to communicate with nsupdate.");
close(pipe_fd[1]);
return -1;
}
@@ -525,14 +529,94 @@ static int ddns_send(char * cmd)
return 0;
}
+
+static uint32_t ddns_resolve(char * name, uint32_t dns_addr)
+{
+ pid_t pid = 0;
+ int wstatus;
+ int pipe_fd[2];
+ char dnsstr[INET_ADDRSTRLEN];
+ char buf[SHIM_UDP_BUF_SIZE];
+ ssize_t count = 0;
+ char * substr;
+ char * substr2;
+ char * addr_str = "Address:";
+ uint32_t ip_addr = 0;
+
+ if (inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN) == NULL) {
+ return 0;
+ }
+
+
+ if (pipe(pipe_fd)) {
+ LOG_ERR("Failed to create pipe.");
+ return 0;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ LOG_ERR("Failed to fork.");
+ return 0;
+ }
+
+ if (pid == 0) {
+ char * argv[] = {NSLOOKUP_EXEC, name, dnsstr, 0};
+ char * envp[] = {0};
+
+ close(pipe_fd[0]);
+ dup2(pipe_fd[1], 1);
+ execve(argv[0], &argv[0], envp);
+ }
+
+ close(pipe_fd[1]);
+
+ count = read(pipe_fd[0], buf, SHIM_UDP_BUF_SIZE);
+ if (count <= 0) {
+ LOG_ERR("Failed to communicate with nslookup.");
+ close(pipe_fd[0]);
+ return 0;
+ }
+
+ close(pipe_fd[0]);
+
+ waitpid(pid, &wstatus, 0);
+ if (WIFEXITED(wstatus) == true &&
+ WEXITSTATUS(wstatus) == 0)
+ LOG_DBGF("Succesfully communicated with nslookup.");
+ else
+ LOG_ERR("Failed to resolve DNS address.");
+
+ buf[count] = '\0';
+ substr = strtok(buf, "\n");
+ while (substr != NULL) {
+ substr2 = substr;
+ substr = strtok(NULL, "\n");
+ }
+
+ if (strstr(substr2, addr_str) == NULL) {
+ LOG_ERR("Failed to resolve DNS address.");
+ return 0;
+ }
+
+ if (inet_pton(AF_INET, substr2 + strlen(addr_str) + 1, &ip_addr) != 1) {
+ LOG_ERR("Failed to resolve DNS address.");
+ return 0;
+ }
+
+ return ip_addr;
+}
+#endif
+
int ipcp_udp_name_reg(char * name)
{
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
char ipstr[INET_ADDRSTRLEN];
char dnsstr[INET_ADDRSTRLEN];
/* max DNS name length + max IP length + command length */
char cmd[100];
uint32_t dns_addr;
uint32_t ip_addr;
+#endif
if (_ipcp->state != IPCP_ENROLLED) {
LOG_DBGF("Won't register with non-enrolled IPCP.");
@@ -549,14 +633,23 @@ int ipcp_udp_name_reg(char * name)
return -1;
}
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
/* register application with DNS server */
dns_addr = shim_data(_ipcp)->dns_addr;
if (dns_addr != 0) {
ip_addr = shim_data(_ipcp)->ip_addr;
- inet_ntop(AF_INET, &ip_addr, ipstr, INET_ADDRSTRLEN);
- inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN);
+ if (inet_ntop(AF_INET, &ip_addr,
+ ipstr, INET_ADDRSTRLEN) == NULL) {
+ return -1;
+ }
+
+ if (inet_ntop(AF_INET, &dns_addr,
+ dnsstr, INET_ADDRSTRLEN) == NULL) {
+ return -1;
+ }
+
sprintf(cmd, "server %s\nupdate add %s %d A %s\nsend\nquit\n",
dnsstr, name, DNS_TTL, ipstr);
@@ -565,6 +658,7 @@ int ipcp_udp_name_reg(char * name)
return -1;
}
}
+#endif
LOG_DBG("Registered %s.", name);
@@ -573,26 +667,33 @@ int ipcp_udp_name_reg(char * name)
int ipcp_udp_name_unreg(char * name)
{
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
char dnsstr[INET_ADDRSTRLEN];
/* max DNS name length + max IP length + max command length */
char cmd[100];
uint32_t dns_addr;
+#endif
if (strlen(name) > 24) {
LOG_ERR("DNS names cannot be longer than 24 chars.");
return -1;
}
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
/* unregister application with DNS server */
dns_addr = shim_data(_ipcp)->dns_addr;
if (dns_addr != 0) {
- inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN);
+ if (inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN)
+ == NULL) {
+ return -1;
+ }
sprintf(cmd, "server %s\nupdate delete %s A\nsend\nquit\n",
dnsstr, name);
ddns_send(cmd);
}
+#endif
ipcp_data_del_reg_entry(_ipcp->data, name);
@@ -612,11 +713,13 @@ int ipcp_udp_flow_alloc(int port_id,
struct sockaddr_in r_saddr;
struct sockaddr_in rf_saddr;
int fd;
- int n;
-
- char * recv_buf = NULL;
-
- struct hostent * h;
+ int n;
+ char * recv_buf = NULL;
+ struct hostent * h;
+ uint32_t ip_addr = 0;
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
+ uint32_t dns_addr = 0;
+#endif
if (dst_name == NULL || src_ap_name == NULL || src_ae_name == NULL)
return -1;
@@ -644,22 +747,41 @@ int ipcp_udp_flow_alloc(int port_id,
return -1;
}
- h = gethostbyname(dst_name);
- if (h == NULL) {
- LOG_DBGF("Could not resolve %s.", dst_name);
- close(fd);
- return -1;
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
+ dns_addr = shim_data(_ipcp)->dns_addr;
+ if (dns_addr != 0) {
+ ip_addr = ddns_resolve(dst_name, dns_addr);
+ if (ip_addr == 0) {
+ LOG_DBGF("Could not resolve %s.", dst_name);
+ close(fd);
+ return -1;
+ }
+ } else {
+#endif
+ h = gethostbyname(dst_name);
+ if (h == NULL) {
+ LOG_DBGF("Could not resolve %s.", dst_name);
+ close(fd);
+ return -1;
+ }
+
+ ip_addr = *((uint32_t *) (h->h_addr_list[0]));
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
}
+#endif
memset((char *) &r_saddr, 0, sizeof r_saddr);
r_saddr.sin_family = AF_INET;
- r_saddr.sin_addr.s_addr = *((uint32_t *) (h->h_addr_list[0]));
+ r_saddr.sin_addr.s_addr = ip_addr;
r_saddr.sin_port = LISTEN_PORT;
/* at least try to get the packet on the wire */
- while (sendto(fd, dst_name, strlen(dst_name), 0,
+ if (sendto(fd, dst_name, strlen(dst_name), 0,
(struct sockaddr *) &r_saddr, sizeof r_saddr) < 0) {
+ LOG_ERR("Failed to send packet");
+ close(fd);
+ return -1;
}
/* wait for the other shim IPCP to respond */
@@ -677,11 +799,12 @@ int ipcp_udp_flow_alloc(int port_id,
(struct sockaddr *) &rf_saddr,
sizeof rf_saddr)
< 0) {
+ close(fd);
free(recv_buf);
return -1;
}
- if (!strcmp(recv_buf, dst_name))
+ if (strcmp(recv_buf, dst_name))
LOG_WARN("Incorrect echo from server");
free(recv_buf);
@@ -692,6 +815,7 @@ int ipcp_udp_flow_alloc(int port_id,
if (_ap_instance->flows[fd].rb == NULL) {
LOG_ERR("Could not open N + 1 ringbuffer.");
close(fd);
+ return -1;
}
/* tell IRMd that flow allocation "worked" */
diff --git a/src/ipcpd/shim-udp/shim_udp_config.h.in b/src/ipcpd/shim-udp/shim_udp_config.h.in
new file mode 100644
index 00000000..71d269d8
--- /dev/null
+++ b/src/ipcpd/shim-udp/shim_udp_config.h.in
@@ -0,0 +1,29 @@
+/*
+ * Ouroboros - Copyright (C) 2016
+ *
+ * Configuration information specific for the shim UDP
+ *
+ * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef OUROBOROS_SHIM_UDP_CONFIG
+#define OUROBOROS_SHIM_UDP_CONFIG
+
+#define NSUPDATE_EXEC "@NSUPDATE_EXECUTABLE@"
+#define NSLOOKUP_EXEC "@NSLOOKUP_EXECUTABLE@"
+
+#endif