aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hicn-light/src/hicn/config/configurationListeners.c119
-rw-r--r--hicn-light/src/hicn/config/controlAddListener.c46
-rw-r--r--hicn-light/src/hicn/io/udpListener.c19
-rw-r--r--hicn-light/src/hicn/io/udpListener.h7
-rw-r--r--hicn-light/src/hicn/utils/commands.h4
5 files changed, 189 insertions, 6 deletions
diff --git a/hicn-light/src/hicn/config/configurationListeners.c b/hicn-light/src/hicn/config/configurationListeners.c
index a16c434f5..97e7dbb87 100644
--- a/hicn-light/src/hicn/config/configurationListeners.c
+++ b/hicn-light/src/hicn/config/configurationListeners.c
@@ -211,6 +211,20 @@ static bool _addEther(Configuration *config, add_listener_command *control,
return false;
}
+#ifdef __linux__
+/*
+ * Create a new IPV4/TCP listener.
+ *
+ * @param [in,out] forwarder The hicn-light forwarder instance
+ * @param [in] addr4 The ipv4 address in network byte order
+ * @param [in] port The port number in network byte order
+ * @param [in] interfaceName The name of the interface to bind the socket
+ *
+ * return true if success, false otherwise
+ */
+static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
+ uint16_t *port, const char *interfaceName) {
+#else
/*
* Create a new IPV4/TCP listener.
*
@@ -222,6 +236,7 @@ static bool _addEther(Configuration *config, add_listener_command *control,
*/
static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
uint16_t *port) {
+#endif
bool success = false;
struct sockaddr_in addr;
@@ -239,6 +254,21 @@ static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
return success;
}
+
+#ifdef __linux__
+/*
+ * Create a new IPV4/UDP listener.
+ *
+ * @param [in,out] forwarder The hicn-light forwarder instance
+ * @param [in] addr4 The ipv4 address in network byte order
+ * @param [in] port The port number in network byte order
+ * @param [in] interfaceName The name of the interface to bind the socket
+ *
+ * return true if success, false otherwise
+ */
+static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
+ uint16_t *port, char *interfaceName) {
+#else
/*
* Create a new IPV4/UDP listener.
*
@@ -250,6 +280,7 @@ static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
*/
static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
uint16_t *port) {
+#endif
bool success = false;
struct sockaddr_in addr;
@@ -258,7 +289,11 @@ static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
addr.sin_port = *port;
addr.sin_addr.s_addr = *addr4;
+#ifdef __linux__
+ ListenerOps *ops = udpListener_CreateInet(forwarder, addr, interfaceName);
+#else
ListenerOps *ops = udpListener_CreateInet(forwarder, addr);
+#endif
if (ops) {
success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
parcAssertTrue(success, "Failed to add UDP listener on %s to ListenerSet",
@@ -267,6 +302,22 @@ static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
return success;
}
+
+#ifdef __linux__
+/*
+ * Create a new IPV6/TCP listener.
+ *
+ * @param [in,out] forwarder The hicn-light forwarder instance
+ * @param [in] addr6 The ipv6 address in network byte order
+ * @param [in] port The port number in network byte order
+ * @param [in] interfaceName The name of the interface to bind the socket
+ *
+ * return true if success, false otherwise
+ */
+static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder,
+ ipv6_addr_t *addr6, uint16_t *port, char *interfaceName,
+ uint32_t scopeId) {
+#else
/*
* Create a new IPV6/TCP listener.
*
@@ -279,6 +330,7 @@ static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder,
ipv6_addr_t *addr6, uint16_t *port,
uint32_t scopeId) {
+#endif
bool success = false;
struct sockaddr_in6 addr;
@@ -297,6 +349,21 @@ static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder,
return success;
}
+
+#ifdef __linux__
+/*
+ * Create a new IPV6/UDP listener.
+ *
+ * @param [in,out] forwarder The hicn-light forwarder instance
+ * @param [in] addr6 The ipv6 address in network byte order
+ * @param [in] port The port number in network byte order
+ * @param [in] interfaceName The name of the interface to bind the socket
+ *
+ * return true if success, false otherwise
+ */
+static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder,
+ ipv6_addr_t *addr6, uint16_t *port, char *interfaceName) {
+#else
/*
* Create a new IPV6/UDP listener.
*
@@ -308,6 +375,7 @@ static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder,
*/
static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder,
ipv6_addr_t *addr6, uint16_t *port) {
+#endif
bool success = false;
struct sockaddr_in6 addr;
@@ -317,7 +385,11 @@ static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder,
addr.sin6_addr = *addr6;
addr.sin6_scope_id = 0;
+#ifdef __linux__
+ ListenerOps *ops = udpListener_CreateInet6(forwarder, addr, interfaceName);
+#else
ListenerOps *ops = udpListener_CreateInet6(forwarder, addr);
+#endif
if (ops) {
success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
parcAssertTrue(success, "Failed to add UDP6 listener on %s to ListenerSet",
@@ -391,6 +463,18 @@ bool _addIP(Configuration *config, add_listener_command *control,
switch (control->addressType) {
case ADDR_INET: {
+
+#ifdef __linux__
+ if (control->connectionType == UDP_CONN) {
+ success =
+ _setupUdpListenerOnInet(configuration_GetForwarder(config),
+ &control->address.ipv4, &control->port, control->interfaceName);
+ } else if (control->connectionType == TCP_CONN) {
+ success =
+ _setupTcpListenerOnInet(configuration_GetForwarder(config),
+ &control->address.ipv4, &control->port, control->interfaceName);
+ }
+#else
if (control->connectionType == UDP_CONN) {
success =
_setupUdpListenerOnInet(configuration_GetForwarder(config),
@@ -400,10 +484,22 @@ bool _addIP(Configuration *config, add_listener_command *control,
_setupTcpListenerOnInet(configuration_GetForwarder(config),
&control->address.ipv4, &control->port);
}
+#endif
break;
}
case ADDR_INET6: {
+#ifdef __linux__
+ if (control->connectionType == UDP_CONN) {
+ success = _setupUdpListenerOnInet6Light(
+ configuration_GetForwarder(config), &control->address.ipv6,
+ &control->port, control->interfaceName);
+ } else if (control->connectionType == TCP_CONN) {
+ success = _setupTcpListenerOnInet6Light(
+ configuration_GetForwarder(config), &control->address.ipv6,
+ &control->port, control->interfaceName, 0);
+ }
+#else
if (control->connectionType == UDP_CONN) {
success = _setupUdpListenerOnInet6Light(
configuration_GetForwarder(config), &control->address.ipv6,
@@ -413,6 +509,7 @@ bool _addIP(Configuration *config, add_listener_command *control,
configuration_GetForwarder(config), &control->address.ipv6,
&control->port, 0);
}
+#endif
break;
}
@@ -524,21 +621,30 @@ struct iovec *configurationListeners_AddPunting(Configuration *config,
static void _setupListenersOnAddress(Forwarder *forwarder,
const Address *address, uint16_t port,
- const char *interfaceName) {
+ char *interfaceName) {
address_type type = addressGetType(address);
switch (type) {
case ADDR_INET: {
struct sockaddr_in tmp;
addressGetInet(address, &tmp);
+#ifdef __linux__
+ _setupTcpListenerOnInet(forwarder, &tmp.sin_addr.s_addr, &port, interfaceName);
+#else
_setupTcpListenerOnInet(forwarder, &tmp.sin_addr.s_addr, &port);
+#endif
break;
}
case ADDR_INET6: {
struct sockaddr_in6 tmp;
addressGetInet6(address, &tmp);
+#ifdef __linux__
+ _setupTcpListenerOnInet6Light(forwarder, &tmp.sin6_addr, &port, interfaceName,
+ tmp.sin6_scope_id);
+#else
_setupTcpListenerOnInet6Light(forwarder, &tmp.sin6_addr, &port,
tmp.sin6_scope_id);
+#endif
break;
}
@@ -570,7 +676,7 @@ void configurationListeners_SetupAll(const Configuration *config, uint16_t port,
// Do not start on link address
if (addressGetType(address) != ADDR_LINK) {
_setupListenersOnAddress(forwarder, address, port,
- interfaceGetName(iface));
+ (char *)interfaceGetName(iface));
}
}
}
@@ -583,9 +689,16 @@ void configurationListeners_SetutpLocalIPv4(const Configuration *config,
Forwarder *forwarder = configuration_GetForwarder(config);
in_addr_t addr = inet_addr("127.0.0.1");
uint16_t network_byte_order_port = htons(port);
-
+#ifdef __linux__
+ char *loopback_interface = "lo";
+ _setupUdpListenerOnInet(forwarder, (ipv4_addr_t *)&(addr),
+ &network_byte_order_port, loopback_interface);
+ _setupTcpListenerOnInet(forwarder, (ipv4_addr_t *)&(addr),
+ &network_byte_order_port, loopback_interface);
+#else
_setupUdpListenerOnInet(forwarder, (ipv4_addr_t *)&(addr),
&network_byte_order_port);
_setupTcpListenerOnInet(forwarder, (ipv4_addr_t *)&(addr),
&network_byte_order_port);
+#endif
}
diff --git a/hicn-light/src/hicn/config/controlAddListener.c b/hicn-light/src/hicn/config/controlAddListener.c
index 7fdf46228..d84b8049b 100644
--- a/hicn-light/src/hicn/config/controlAddListener.c
+++ b/hicn-light/src/hicn/config/controlAddListener.c
@@ -58,14 +58,22 @@ static const int _indexProtocol = 2;
static const int _indexSymbolic = 3;
static const int _indexAddress = 4;
static const int _indexPort = 5;
+#ifdef __linux__
+static const int _indexInterfaceName = 6;
+#endif
static CommandReturn _controlAddListener_HelpExecute(CommandParser *parser,
CommandOps *ops,
PARCList *args) {
printf("commands:\n");
printf(" add listener hicn <symbolic> <localAddress> \n");
- printf(" add listener udp <symbolic> <localAddress> <port> \n");
- printf(" add listener tcp <symbolic> <localAddress> <port> \n");
+#ifdef __linux__
+ printf(" add listener udp <symbolic> <localAddress> <port> <interface>\n");
+ printf(" add listener tcp <symbolic> <localAddress> <port> <interface>\n");
+#else
+ printf(" add listener udp <symbolic> <localAddress> <port>\n");
+ printf(" add listener tcp <symbolic> <localAddress> <port>\n");
+#endif
printf("\n");
printf(
" symbolic: User defined name for listener, must start with "
@@ -75,6 +83,8 @@ static CommandReturn _controlAddListener_HelpExecute(CommandParser *parser,
" localAddress: IPv4 or IPv6 address (or prefix protocol = hicn) "
"assigend to the local interface\n");
printf(" port: Udp port\n");
+
+ printf(" interface: interface\n");
printf("\n");
printf("Notes:\n");
printf(" The symblic name must be unique or the source will reject it.\n");
@@ -84,10 +94,17 @@ static CommandReturn _controlAddListener_HelpExecute(CommandParser *parser,
return CommandReturn_Success;
}
+#ifdef __linux__
+static CommandReturn _CreateListener(CommandParser *parser, CommandOps *ops,
+ const char *symbolic, const char *addr,
+ const char *port, const char *interfaceName, listener_mode mode,
+ connection_type type) {
+#else
static CommandReturn _CreateListener(CommandParser *parser, CommandOps *ops,
const char *symbolic, const char *addr,
const char *port, listener_mode mode,
connection_type type) {
+#endif
ControlState *state = ops->closure;
// allocate command payload
@@ -109,6 +126,9 @@ static CommandReturn _CreateListener(CommandParser *parser, CommandOps *ops,
}
// Fill remaining payload fields
+#ifdef __linux__
+ memcpy(addListenerCommand->interfaceName, interfaceName, 16);
+#endif
addListenerCommand->listenerMode = mode;
addListenerCommand->connectionType = type;
addListenerCommand->port = htons((uint16_t)atoi(port));
@@ -129,7 +149,11 @@ static CommandReturn _CreateListener(CommandParser *parser, CommandOps *ops,
static CommandReturn _controlAddListener_Execute(CommandParser *parser,
CommandOps *ops,
PARCList *args) {
+#ifdef __linux__
+ if (parcList_Size(args) != 5 && parcList_Size(args) != 7) {
+#else
if (parcList_Size(args) != 5 && parcList_Size(args) != 6) {
+#endif
_controlAddListener_HelpExecute(parser, ops, args);
return CommandReturn_Failure;
}
@@ -146,6 +170,9 @@ static CommandReturn _controlAddListener_Execute(CommandParser *parser,
}
const char *host = parcList_GetAtIndex(args, _indexAddress);
+#ifdef __linux__
+ const char *interfaceName = parcList_GetAtIndex(args, _indexInterfaceName);
+#endif
const char *protocol = parcList_GetAtIndex(args, _indexProtocol);
if ((strcasecmp("hicn", protocol) == 0)) {
@@ -154,18 +181,33 @@ static CommandReturn _controlAddListener_Execute(CommandParser *parser,
// here we discard the prefix len if it exists, since we don't use it in
// code but we let libhicn to find the right ip address.
+#ifdef __linux__
+ return _CreateListener(parser, ops, symbolic, host, port, interfaceName, HICN_MODE,
+ HICN_CONN);
+#else
return _CreateListener(parser, ops, symbolic, host, port, HICN_MODE,
HICN_CONN);
+#endif
}
const char *port = parcList_GetAtIndex(args, _indexPort);
if ((strcasecmp("udp", protocol) == 0)) {
+#ifdef __linux__
+ return _CreateListener(parser, ops, symbolic, host, port, interfaceName, IP_MODE,
+ UDP_CONN);
+#else
return _CreateListener(parser, ops, symbolic, host, port, IP_MODE,
UDP_CONN);
+#endif
} else if ((strcasecmp("tcp", protocol) == 0)) {
+#ifdef __linux__
+ return _CreateListener(parser, ops, symbolic, host, port, interfaceName, IP_MODE,
+ TCP_CONN);
+#else
return _CreateListener(parser, ops, symbolic, host, port, IP_MODE,
TCP_CONN);
+#endif
} else {
_controlAddListener_HelpExecute(parser, ops, args);
return CommandReturn_Failure;
diff --git a/hicn-light/src/hicn/io/udpListener.c b/hicn-light/src/hicn/io/udpListener.c
index 3d3455f41..3dd4b466c 100644
--- a/hicn-light/src/hicn/io/udpListener.c
+++ b/hicn-light/src/hicn/io/udpListener.c
@@ -70,8 +70,13 @@ static ListenerOps udpTemplate = {.context = NULL,
static void _readcb(int fd, PARCEventType what, void *udpVoid);
+#ifdef __linux__
+ListenerOps *udpListener_CreateInet6(Forwarder *forwarder,
+ struct sockaddr_in6 sin6, const char *interfaceName) {
+#else
ListenerOps *udpListener_CreateInet6(Forwarder *forwarder,
struct sockaddr_in6 sin6) {
+#endif
ListenerOps *ops = NULL;
UdpListener *udp = parcMemory_AllocateAndClear(sizeof(UdpListener));
@@ -112,7 +117,12 @@ ListenerOps *udpListener_CreateInet6(Forwarder *forwarder,
parcAssertFalse(failure, "failed to set REUSEADDR on socket(%d)", errno);
failure = bind(udp->udp_socket, (struct sockaddr *)&sin6, sizeof(sin6));
+
if (failure == 0) {
+#ifdef __linux__
+ setsockopt(udp->udp_socket, SOL_SOCKET, SO_BINDTODEVICE,
+ interfaceName, strlen(interfaceName) + 1);
+#endif
udp->udp_event =
dispatcher_CreateNetworkEvent(forwarder_GetDispatcher(forwarder), true,
_readcb, (void *)udp, udp->udp_socket);
@@ -153,8 +163,13 @@ ListenerOps *udpListener_CreateInet6(Forwarder *forwarder,
return ops;
}
+#ifdef __linux__
+ListenerOps *udpListener_CreateInet(Forwarder *forwarder,
+ struct sockaddr_in sin, const char *interfaceName) {
+#else
ListenerOps *udpListener_CreateInet(Forwarder *forwarder,
struct sockaddr_in sin) {
+#endif
ListenerOps *ops = NULL;
UdpListener *udp = parcMemory_AllocateAndClear(sizeof(UdpListener));
@@ -195,6 +210,10 @@ ListenerOps *udpListener_CreateInet(Forwarder *forwarder,
failure = bind(udp->udp_socket, (struct sockaddr *)&sin, sizeof(sin));
if (failure == 0) {
+#ifdef __linux__
+ setsockopt(udp->udp_socket, SOL_SOCKET, SO_BINDTODEVICE,
+ interfaceName, strlen(interfaceName) + 1);
+#endif
udp->udp_event =
dispatcher_CreateNetworkEvent(forwarder_GetDispatcher(forwarder), true,
_readcb, (void *)udp, udp->udp_socket);
diff --git a/hicn-light/src/hicn/io/udpListener.h b/hicn-light/src/hicn/io/udpListener.h
index 1ad3f77fe..81d191eab 100644
--- a/hicn-light/src/hicn/io/udpListener.h
+++ b/hicn-light/src/hicn/io/udpListener.h
@@ -27,9 +27,16 @@
struct udp_listener;
typedef struct udp_listener UdpListener;
+#ifdef __linux__
+ListenerOps *udpListener_CreateInet6(Forwarder *forwarder,
+ struct sockaddr_in6 sin6, const char *if_bind);
+ListenerOps *udpListener_CreateInet(Forwarder *forwarder,
+ struct sockaddr_in sin, const char *if_bind);
+#else
ListenerOps *udpListener_CreateInet6(Forwarder *forwarder,
struct sockaddr_in6 sin6);
ListenerOps *udpListener_CreateInet(Forwarder *forwarder,
struct sockaddr_in sin);
+#endif
// void udpListener_SetPacketType(ListenerOps *ops, MessagePacketType type);
#endif // udpListener_h
diff --git a/hicn-light/src/hicn/utils/commands.h b/hicn-light/src/hicn/utils/commands.h
index 236a75a33..96415d8da 100644
--- a/hicn-light/src/hicn/utils/commands.h
+++ b/hicn-light/src/hicn/utils/commands.h
@@ -105,7 +105,9 @@ typedef enum { ETHER_MODE, IP_MODE, HICN_MODE } listener_mode;
typedef struct {
char symbolic[16];
- // char interfaceName[16];
+#ifdef __linux__
+ char interfaceName[16];
+#endif
union commandAddr address;
uint16_t port;
// uint16_t etherType;