From a621d4843592cdf3fe758fc06ab19af299278ca7 Mon Sep 17 00:00:00 2001 From: Angelo Mantellini Date: Fri, 12 Jul 2019 08:48:59 -0700 Subject: [HICN-245] Bind of the listener to the device Change-Id: I4d8cd95ba74c5d24d4c49975e7798440fe3e34d1 Signed-off-by: Angelo Mantellini --- .../src/hicn/config/configurationListeners.c | 119 ++++++++++++++++++++- hicn-light/src/hicn/config/controlAddListener.c | 46 +++++++- hicn-light/src/hicn/io/udpListener.c | 19 ++++ hicn-light/src/hicn/io/udpListener.h | 7 ++ hicn-light/src/hicn/utils/commands.h | 4 +- 5 files changed, 189 insertions(+), 6 deletions(-) (limited to 'hicn-light') 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 \n"); - printf(" add listener udp \n"); - printf(" add listener tcp \n"); +#ifdef __linux__ + printf(" add listener udp \n"); + printf(" add listener tcp \n"); +#else + printf(" add listener udp \n"); + printf(" add listener tcp \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; -- cgit 1.2.3-korg