From eefc7ae95bbd680416163e5617bada1949b32afc Mon Sep 17 00:00:00 2001 From: Angelo Mantellini Date: Thu, 18 Jul 2019 18:31:46 +0200 Subject: [HICN-247] remove listener and bug fixing Change-Id: I4e5419a837131680fe0e21eb295462ccb2be8613 Signed-off-by: Angelo Mantellini --- .../controller/hicnLightControl_main.c | 1 + hicn-light/src/hicn/config/CMakeLists.txt | 2 + hicn-light/src/hicn/config/configuration.c | 82 ++++++++- .../src/hicn/config/configurationListeners.c | 4 +- hicn-light/src/hicn/config/controlAddConnection.c | 22 ++- hicn-light/src/hicn/config/controlAddListener.c | 55 ++---- .../src/hicn/config/controlListConnections.c | 2 + hicn-light/src/hicn/config/controlRemove.c | 7 + hicn-light/src/hicn/config/controlRemoveListener.c | 115 ++++++++++++ hicn-light/src/hicn/config/controlRemoveListener.h | 31 ++++ hicn-light/src/hicn/core/connection.c | 1 + hicn-light/src/hicn/io/hicnListener.c | 198 +++++++++++---------- hicn-light/src/hicn/io/ioOperations.c | 2 + hicn-light/src/hicn/io/listenerSet.c | 14 ++ hicn-light/src/hicn/io/listenerSet.h | 16 +- hicn-light/src/hicn/io/streamConnection.c | 1 + hicn-light/src/hicn/io/tcpListener.c | 11 +- hicn-light/src/hicn/io/udpListener.c | 3 +- hicn-light/src/hicn/utils/commands.h | 27 +-- hicn-light/src/hicn/utils/utils.c | 1 - 20 files changed, 433 insertions(+), 162 deletions(-) create mode 100644 hicn-light/src/hicn/config/controlRemoveListener.c create mode 100644 hicn-light/src/hicn/config/controlRemoveListener.h (limited to 'hicn-light') diff --git a/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c b/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c index f704d237e..ab0e0e6d8 100644 --- a/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c +++ b/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c @@ -63,6 +63,7 @@ static int payloadLengthController[LAST_COMMAND_VALUE] = { sizeof(add_route_command), sizeof(list_routes_command), // needed when get response from FWD sizeof(remove_connection_command), + sizeof(remove_listener_command), sizeof(remove_route_command), sizeof(cache_store_command), sizeof(cache_serve_command), diff --git a/hicn-light/src/hicn/config/CMakeLists.txt b/hicn-light/src/hicn/config/CMakeLists.txt index b1e475aee..45f36e8ff 100644 --- a/hicn-light/src/hicn/config/CMakeLists.txt +++ b/hicn-light/src/hicn/config/CMakeLists.txt @@ -35,6 +35,7 @@ list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/controlListPolicies.h ${CMAKE_CURRENT_SOURCE_DIR}/controlQuit.h ${CMAKE_CURRENT_SOURCE_DIR}/controlRemove.h + ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveListener.h ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveConnection.h ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveRoute.h ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePolicy.h @@ -78,6 +79,7 @@ list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/controlListPolicies.c ${CMAKE_CURRENT_SOURCE_DIR}/controlQuit.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRemove.c + ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveListener.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveConnection.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveRoute.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePolicy.c diff --git a/hicn-light/src/hicn/config/configuration.c b/hicn-light/src/hicn/config/configuration.c index b14ea551a..83fce748c 100644 --- a/hicn-light/src/hicn/config/configuration.c +++ b/hicn-light/src/hicn/config/configuration.c @@ -346,7 +346,6 @@ static void configuration_SendResponse(Configuration *config, struct iovec *msg, if (conn == NULL) { return; } - connection_SendIOVBuffer(conn, msg, 2); } @@ -450,6 +449,10 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, /* Hook: new connection created through the control protocol */ forwarder_onConnectionEvent(config->forwarder, conn, CONNECTION_EVENT_UPDATE); #endif /* WITH_MAPME */ + if (source) + addressDestroy(&source); + if (destination) + addressDestroy(&destination); success = true; #else @@ -472,6 +475,70 @@ ERR: return utils_CreateNack(header, control, sizeof(add_connection_command)); } +struct iovec *configuration_ProcessRemoveListener(Configuration *config, + struct iovec *request, + unsigned ingressId) { + header_control_message *header = request[0].iov_base; + remove_listener_command *control = request[1].iov_base; + + bool success = false; + + const char *symbolicOrListenerid = control->symbolicOrListenerid; + unsigned listenerId = -1; + ListenerSet *listenerSet = forwarder_GetListenerSet(config->forwarder); + if (utils_IsNumber(symbolicOrListenerid)) { + // case for connid as input + listenerId = (unsigned)strtold(symbolicOrListenerid, NULL); + } else { + listenerId = listenerSet_FindIdByListenerName(listenerSet, symbolicOrListenerid); + } + + if (listenerId >= 0) { + + ConnectionTable *connTable = forwarder_GetConnectionTable(config->forwarder); + ListenerOps *listenerOps = listenerSet_FindById(listenerSet, listenerId); + if (listenerOps) { + ConnectionList *connectionList =connectionTable_GetEntries(connTable); + for (size_t i =0; i < connectionList_Length(connectionList); i++) { + Connection *connection = connectionList_Get(connectionList, i); + const AddressPair *addressPair = connection_GetAddressPair(connection); + const Address *address = addressPair_GetLocal(addressPair); + if (addressEquals(listenerOps->getListenAddress(listenerOps),address)) { + // case for connid as input + unsigned connid = connection_GetConnectionId(connection); + // remove connection from the FIB + forwarder_RemoveConnectionIdFromRoutes(config->forwarder, connid); + // remove connection + connectionTable_RemoveById(connTable, connid); + const char *symbolicConnection = symbolicNameTable_GetNameByIndex(config->symbolicNameTable,connid); + symbolicNameTable_Remove(config->symbolicNameTable, symbolicConnection); + } + } + // remove listener + listenerSet_RemoveById(listenerSet, listenerId); + success = true; + } else { + logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO, + PARCLogLevel_Error, __func__, + "Listener Id not found, check list listeners"); + } + } + + // generate ACK/NACK + struct iovec *response; + + if (success) { // ACK + response = + utils_CreateAck(header, control, sizeof(remove_listener_command)); + } else { // NACK + response = + utils_CreateNack(header, control, sizeof(remove_connection_command)); + } + + return response; +} + + /** * Add an IP-based tunnel. * @@ -493,7 +560,6 @@ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, const char *symbolicOrConnid = control->symbolicOrConnid; ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder); - if (strcmp(symbolicOrConnid, "SELF") == 0) { forwarder_RemoveConnectionIdFromRoutes(config->forwarder, ingressId); connectionTable_RemoveById(table, ingressId); @@ -515,6 +581,9 @@ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, forwarder_RemoveConnectionIdFromRoutes(config->forwarder, connid); // remove connection connectionTable_RemoveById(table, connid); + // remove connection from symbolicNameTable + const char *symbolicConnection = symbolicNameTable_GetNameByIndex(config->symbolicNameTable,connid); + symbolicNameTable_Remove(config->symbolicNameTable, symbolicConnection); #ifdef WITH_MAPME /* Hook: new connection created through the control protocol */ @@ -568,6 +637,8 @@ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, } } + + // generate ACK/NACK struct iovec *response; @@ -612,8 +683,8 @@ struct iovec *configuration_ProcessConnectionList(Configuration *config, list_connections_command *listConnectionsCommand = (list_connections_command *)(payloadResponse + (i * sizeof(list_connections_command))); - // set structure fields + listConnectionsCommand->connid = connection_GetConnectionId(original); const char *connectionName = symbolicNameTable_GetNameByIndex(config->symbolicNameTable, connection_GetConnectionId(original)); @@ -1202,7 +1273,6 @@ struct iovec *configuration_DispatchCommand(Configuration *config, struct iovec *control, unsigned ingressId) { struct iovec *response = NULL; - switch (command) { case ADD_LISTENER: response = configurationListeners_Add(config, control, ingressId); @@ -1229,6 +1299,10 @@ struct iovec *configuration_DispatchCommand(Configuration *config, response = configuration_ProcessRemoveTunnel(config, control, ingressId); break; + case REMOVE_LISTENER: + response = configuration_ProcessRemoveListener(config, control, ingressId); + break; + case REMOVE_ROUTE: response = configuration_ProcessUnregisterHicnPrefix(config, control); break; diff --git a/hicn-light/src/hicn/config/configurationListeners.c b/hicn-light/src/hicn/config/configurationListeners.c index 86d8a215a..c321007e2 100644 --- a/hicn-light/src/hicn/config/configurationListeners.c +++ b/hicn-light/src/hicn/config/configurationListeners.c @@ -317,6 +317,7 @@ static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder, char *listenerNa * Create a new IPV6/UDP listener. * * @param [in,out] forwarder The hicn-light forwarder instance + * @param [in] listenerName The name of the listener * @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 @@ -615,7 +616,8 @@ 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); - char listenerNameUdp[16] = "lo_udp"; + + char listenerNameUdp[16] = "lo_udp"; char listenerNameTcp[16] = "lo_tcp"; char *loopback_interface = "lo"; _setupUdpListenerOnInet(forwarder, listenerNameUdp,(ipv4_addr_t *)&(addr), diff --git a/hicn-light/src/hicn/config/controlAddConnection.c b/hicn-light/src/hicn/config/controlAddConnection.c index e09b61b37..eaa680bde 100644 --- a/hicn-light/src/hicn/config/controlAddConnection.c +++ b/hicn-light/src/hicn/config/controlAddConnection.c @@ -42,11 +42,13 @@ static CommandReturn _controlAddConnection_Execute(CommandParser *parser, // =================================================== +#ifdef __linux__ static CommandReturn _controlAddConnection_HicnHelpExecute( CommandParser *parser, CommandOps *ops, PARCList *args); static CommandReturn _controlAddConnection_HicnExecute(CommandParser *parser, CommandOps *ops, PARCList *args); +#endif static CommandReturn _controlAddConnection_UdpHelpExecute(CommandParser *parser, CommandOps *ops, @@ -65,11 +67,15 @@ static CommandReturn _controlAddConnection_TcpExecute(CommandParser *parser, // =================================================== static const char *_commandAddConnection = "add connection"; +#ifdef __linux__ static const char *_commandAddConnectionHicn = "add connection hicn"; +#endif static const char *_commandAddConnectionUdp = "add connection udp"; static const char *_commandAddConnectionTcp = "add connection tcp"; static const char *_commandAddConnectionHelp = "help add connection"; +#ifdef __linux__ static const char *_commandAddConnectionHicnHelp = "help add connection hicn"; +#endif static const char *_commandAddConnectionUdpHelp = "help add connection udp"; static const char *_commandAddConnectionTcpHelp = "help add connection tcp"; @@ -89,11 +95,13 @@ CommandOps *controlAddConnection_HelpCreate(ControlState *state) { // =================================================== +#ifdef __linux__ static CommandOps *_controlAddConnection_HicnCreate(ControlState *state) { return commandOps_Create(state, _commandAddConnectionHicn, NULL, _controlAddConnection_HicnExecute, commandOps_Destroy); } +#endif static CommandOps *_controlAddConnection_UdpCreate(ControlState *state) { return commandOps_Create(state, _commandAddConnectionUdp, NULL, @@ -108,12 +116,13 @@ static CommandOps *_controlAddConnection_TcpCreate(ControlState *state) { } // =================================================== - +#ifdef __linux__ static CommandOps *_controlAddConnection_HicnHelpCreate(ControlState *state) { return commandOps_Create(state, _commandAddConnectionHicnHelp, NULL, _controlAddConnection_HicnHelpExecute, commandOps_Destroy); } +#endif static CommandOps *_controlAddConnection_UdpHelpCreate(ControlState *state) { return commandOps_Create(state, _commandAddConnectionUdpHelp, NULL, @@ -133,7 +142,9 @@ static CommandReturn _controlAddConnection_HelpExecute(CommandParser *parser, CommandOps *ops, PARCList *args) { printf("Available commands:\n"); +#ifdef __linux__ printf(" %s\n", _commandAddConnectionHicn); +#endif printf(" %s\n", _commandAddConnectionUdp); printf(" %s\n", _commandAddConnectionTcp); printf("\n"); @@ -142,14 +153,17 @@ static CommandReturn _controlAddConnection_HelpExecute(CommandParser *parser, static void _controlAddConnection_Init(CommandParser *parser, CommandOps *ops) { ControlState *state = ops->closure; +#ifdef __linux__ controlState_RegisterCommand(state, _controlAddConnection_HicnHelpCreate(state)); +#endif controlState_RegisterCommand(state, _controlAddConnection_UdpHelpCreate(state)); controlState_RegisterCommand(state, _controlAddConnection_TcpHelpCreate(state)); - +#ifdef __linux__ controlState_RegisterCommand(state, _controlAddConnection_HicnCreate(state)); +#endif controlState_RegisterCommand(state, _controlAddConnection_UdpCreate(state)); controlState_RegisterCommand(state, _controlAddConnection_TcpCreate(state)); } @@ -255,7 +269,9 @@ static CommandReturn _controlAddConnection_IpHelp(CommandParser *parser, CommandOps *ops, PARCList *args, const char *protocol) { +#ifdef __linux__ printf("add connection hicn \n"); +#endif printf( "add connection udp \n"); printf( @@ -268,6 +284,7 @@ static CommandReturn _controlAddConnection_IpHelp(CommandParser *parser, return CommandReturn_Success; } +#ifdef __linux__ static CommandReturn _controlAddConnection_HicnHelpExecute( CommandParser *parser, CommandOps *ops, PARCList *args) { _controlAddConnection_IpHelp(parser, ops, args, "hicn"); @@ -303,6 +320,7 @@ static CommandReturn _controlAddConnection_HicnExecute(CommandParser *parser, return _controlAddConnection_CreateTunnel( parser, ops, local_ip, port, remote_ip, port, HICN_CONN, symbolic); } +#endif static CommandReturn _controlAddConnection_UdpHelpExecute(CommandParser *parser, CommandOps *ops, diff --git a/hicn-light/src/hicn/config/controlAddListener.c b/hicn-light/src/hicn/config/controlAddListener.c index c9253425a..cfd061131 100644 --- a/hicn-light/src/hicn/config/controlAddListener.c +++ b/hicn-light/src/hicn/config/controlAddListener.c @@ -58,27 +58,26 @@ 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"); #ifdef __linux__ + printf(" add listener hicn \n"); +#endif 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 " "alpha and be alphanum\n"); +#ifdef __linux__ printf(" protocol: hicn | udp\n"); +#else + printf(" protocol: udp\n"); +#endif printf( " localAddress: IPv4 or IPv6 address (or prefix protocol = hicn) " "assigend to the local interface\n"); @@ -88,23 +87,18 @@ static CommandReturn _controlAddListener_HelpExecute(CommandParser *parser, printf("\n"); printf("Notes:\n"); printf(" The symblic name must be unique or the source will reject it.\n"); +#ifdef __linux__ printf( - " If protocol = hinc: the address 0::0 indicates the main listern, " + " If protocol = hicn: the address 0::0 indicates the main listern, " "for which we can set punting rules.\n"); +#endif 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, + const char *port, char *interfaceName, listener_mode mode, connection_type type) { -#endif ControlState *state = ops->closure; // allocate command payload @@ -126,9 +120,7 @@ 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)); @@ -149,11 +141,7 @@ 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; } @@ -169,45 +157,26 @@ static CommandReturn _controlAddListener_Execute(CommandParser *parser, return result; } - const char *host = parcList_GetAtIndex(args, _indexAddress); -#ifdef __linux__ - const char *interfaceName = parcList_GetAtIndex(args, _indexInterfaceName); -#endif const char *protocol = parcList_GetAtIndex(args, _indexProtocol); - + const char *host = parcList_GetAtIndex(args, _indexAddress); + char *interfaceName = parcList_GetAtIndex(args, _indexInterfaceName); if ((strcasecmp("hicn", protocol) == 0)) { const char *port = "1234"; // this is a random port number that will be ignored // 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, "hicn", 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/config/controlListConnections.c b/hicn-light/src/hicn/config/controlListConnections.c index dbd9707ca..c8a4c1b4b 100644 --- a/hicn-light/src/hicn/config/controlListConnections.c +++ b/hicn-light/src/hicn/config/controlListConnections.c @@ -120,6 +120,8 @@ static CommandReturn _controlListConnections_Execute(CommandParser *parser, #endif /* WITH_POLICY */ // Process/Print payload + + printf("%5s %10s %6s %40s %40s %5s\n", "id", "name", "state", "source", "destination", "type"); for (int i = 0; i < receivedHeader->length; i++) { list_connections_command *listConnectionsCommand = (list_connections_command *)(receivedPayload + diff --git a/hicn-light/src/hicn/config/controlRemove.c b/hicn-light/src/hicn/config/controlRemove.c index af833dc8b..ef0c15934 100644 --- a/hicn-light/src/hicn/config/controlRemove.c +++ b/hicn-light/src/hicn/config/controlRemove.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,7 @@ static CommandReturn _controlRemove_HelpExecute(CommandParser *parser, CommandOps *ops, PARCList *args) { CommandOps *ops_remove_connection = controlRemoveConnection_Create(NULL); + CommandOps *ops_remove_listener = controlRemoveListener_Create(NULL); CommandOps *ops_remove_route = controlRemoveRoute_Create(NULL); CommandOps *ops_remove_punting = controlRemovePunting_Create(NULL); #ifdef WITH_POLICY @@ -70,6 +72,7 @@ static CommandReturn _controlRemove_HelpExecute(CommandParser *parser, printf("Available commands:\n"); printf(" %s\n", ops_remove_connection->command); + printf(" %s\n", ops_remove_listener->command); printf(" %s\n", ops_remove_route->command); printf(" %s\n", ops_remove_punting->command); #ifdef WITH_POLICY @@ -78,6 +81,7 @@ static CommandReturn _controlRemove_HelpExecute(CommandParser *parser, printf("\n"); commandOps_Destroy(&ops_remove_connection); + commandOps_Destroy(&ops_remove_listener); commandOps_Destroy(&ops_remove_route); commandOps_Destroy(&ops_remove_punting); #ifdef WITH_POLICY @@ -90,8 +94,11 @@ static void _controlRemove_Init(CommandParser *parser, CommandOps *ops) { ControlState *state = ops->closure; controlState_RegisterCommand(state, controlRemoveConnection_HelpCreate(state)); + controlState_RegisterCommand(state, + controlRemoveListener_HelpCreate(state)); controlState_RegisterCommand(state, controlRemoveRoute_HelpCreate(state)); controlState_RegisterCommand(state, controlRemoveConnection_Create(state)); + controlState_RegisterCommand(state, controlRemoveListener_Create(state)); controlState_RegisterCommand(state, controlRemoveRoute_Create(state)); controlState_RegisterCommand(state, controlRemovePunting_Create(state)); controlState_RegisterCommand(state, controlRemovePunting_HelpCreate(state)); diff --git a/hicn-light/src/hicn/config/controlRemoveListener.c b/hicn-light/src/hicn/config/controlRemoveListener.c new file mode 100644 index 000000000..50581a8d9 --- /dev/null +++ b/hicn-light/src/hicn/config/controlRemoveListener.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +static CommandReturn _controlRemoveListener_Execute(CommandParser *parser, + CommandOps *ops, + PARCList *args); +static CommandReturn _controlRemoveListener_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args); + +// =================================================== + +static const char *_commandRemoveListener = "remove listener"; +static const char *_commandRemoveListenerHelp = "help remove listener"; + +// ==================================================== + +CommandOps *controlRemoveListener_Create(ControlState *state) { + return commandOps_Create(state, _commandRemoveListener, NULL, + _controlRemoveListener_Execute, + commandOps_Destroy); +} + +CommandOps *controlRemoveListener_HelpCreate(ControlState *state) { + return commandOps_Create(state, _commandRemoveListenerHelp, NULL, + _controlRemoveListener_HelpExecute, + commandOps_Destroy); +} + +// ==================================================== + +static CommandReturn _controlRemoveListener_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + printf("command:\n"); + printf(" remove listener \n"); + return CommandReturn_Success; +} + +static CommandReturn _controlRemoveListener_Execute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + ControlState *state = ops->closure; + + if (parcList_Size(args) != 3) { + _controlRemoveListener_HelpExecute(parser, ops, args); + return false; + } + + if ((strcmp(parcList_GetAtIndex(args, 0), "remove") != 0) || + (strcmp(parcList_GetAtIndex(args, 1), "listener") != 0)) { + _controlRemoveListener_HelpExecute(parser, ops, args); + return false; + } + + const char *listenerId = parcList_GetAtIndex(args, 2); + +if (!utils_ValidateSymbolicName(listenerId) && + !utils_IsNumber(listenerId)) { + printf( + "ERROR: Invalid symbolic or listenerId:\nsymbolic name must begin with an " + "alpha followed by alphanum;\nlistenerId must be an integer\n"); + return CommandReturn_Failure; + } + + // allocate command payload + remove_listener_command *removeListenerCommand = + parcMemory_AllocateAndClear(sizeof(remove_listener_command)); + // fill payload + //removeListenerCommand->listenerId = atoi(listenerId); + strncpy(removeListenerCommand->symbolicOrListenerid, listenerId, strlen(listenerId)); + + // send message and receive response + struct iovec *response = + utils_SendRequest(state, REMOVE_LISTENER, removeListenerCommand, + sizeof(remove_listener_command)); + + if (!response) { // get NULL pointer + return CommandReturn_Failure; + } + + parcMemory_Deallocate(&response); // free iovec pointer + return CommandReturn_Success; +} diff --git a/hicn-light/src/hicn/config/controlRemoveListener.h b/hicn-light/src/hicn/config/controlRemoveListener.h new file mode 100644 index 000000000..794d1e1a9 --- /dev/null +++ b/hicn-light/src/hicn/config/controlRemoveListener.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file control_RemoveConnection.h + * @brief Remove a connection from the connection table + * + * Implements the "remove connection" and "help remove connection" nodes of the + * CLI tree + * + */ + +#ifndef Control_RemoveListener_h +#define Control_RemoveListener_h + +#include +CommandOps *controlRemoveListener_Create(ControlState *state); +CommandOps *controlRemoveListener_HelpCreate(ControlState *state); +#endif // Control_RemoveListener_h diff --git a/hicn-light/src/hicn/core/connection.c b/hicn-light/src/hicn/core/connection.c index 821da884d..fb43d4a1e 100644 --- a/hicn-light/src/hicn/core/connection.c +++ b/hicn-light/src/hicn/core/connection.c @@ -32,6 +32,7 @@ #endif /* WITH_POLICY */ struct connection { + const AddressPair *addressPair; IoOperations *ops; diff --git a/hicn-light/src/hicn/io/hicnListener.c b/hicn-light/src/hicn/io/hicnListener.c index 995347d6a..8409db027 100644 --- a/hicn-light/src/hicn/io/hicnListener.c +++ b/hicn-light/src/hicn/io/hicnListener.c @@ -82,6 +82,12 @@ static EncapType _getEncapType(const ListenerOps *ops); static int _getSocket(const ListenerOps *ops); static unsigned _createNewConnection(ListenerOps *listener, int fd, const AddressPair *pair); static const Connection * _lookupConnection(ListenerOps * listener, const AddressPair *pair); +static Message *_readMessage(ListenerOps * listener, int fd, uint8_t *msgBuffer); +static void _hicnListener_readcb(int fd, PARCEventType what, void *listener_void); +static Address *_createAddressFromPacket(uint8_t *msgBuffer); +static void _handleProbeMessage(ListenerOps * listener, uint8_t *msgBuffer); +static void _handleWldrNotification(ListenerOps *listener, uint8_t *msgBuffer); +static void _readFrameToDiscard(HicnListener *hicn, int fd); static ListenerOps _hicnTemplate = { .context = NULL, @@ -96,8 +102,6 @@ static ListenerOps _hicnTemplate = { .lookupConnection = &_lookupConnection, }; -static void _hicnListener_readcb(int fd, PARCEventType what, void *hicnVoid); - static bool _isEmptyAddressIPv6(Address *address) { struct sockaddr_in6 *addr6 = parcMemory_AllocateAndClear(sizeof(struct sockaddr_in6)); @@ -118,6 +122,100 @@ static bool _isEmptyAddressIPv6(Address *address) { return res; } +static Message *_readMessage(ListenerOps * listener, int fd, uint8_t *msgBuffer) { + HicnListener * hicn = (HicnListener*)listener->context; + Message *message = NULL; + + ssize_t readLength = read(fd, msgBuffer, MTU_SIZE); + + if (readLength < 0) { + printf("read failed %d: (%d) %s\n", fd, errno, strerror(errno)); + return message; + } + + size_t packetLength = messageHandler_GetTotalPacketLength(msgBuffer); + + if (readLength != packetLength) { + parcMemory_Deallocate((void **)&msgBuffer); + return message; + } + + if (messageHandler_IsTCP(msgBuffer)) { + MessagePacketType pktType; + unsigned connid = 0; + if (messageHandler_IsData(msgBuffer)) { + pktType = MessagePacketType_ContentObject; + if (hicn->connection_id == -1) { + parcMemory_Deallocate((void **)&msgBuffer); + return message; + } else { + connid = hicn->connection_id; + } + } else if (messageHandler_IsInterest(msgBuffer)) { + // notice that the connections for the interest (the one that we create at + // run time) uses as a local address 0::0, so the main tun + pktType = MessagePacketType_Interest; + Address *packetAddr = _createAddressFromPacket(msgBuffer); + + AddressPair *pair_find = addressPair_Create(packetAddr, /* dummy */ hicn->localAddress); + const Connection *conn = _lookupConnection(listener, pair_find); + addressPair_Release(&pair_find); + if (conn == NULL) { + AddressPair *pair = addressPair_Create(hicn->localAddress, packetAddr); + connid = _createNewConnection(listener, fd, pair); + addressPair_Release(&pair); + } else { + connid = connection_GetConnectionId(conn); + } + addressDestroy(&packetAddr); + } else { + printf("Got a packet that is not a data nor an interest, drop it!\n"); + parcMemory_Deallocate((void **)&msgBuffer); + return message; + } + + message = message_CreateFromByteArray(connid, msgBuffer, pktType, + forwarder_GetTicks(hicn->forwarder), + forwarder_GetLogger(hicn->forwarder)); + if (message == NULL) { + parcMemory_Deallocate((void **)&msgBuffer); + } + } else if (messageHandler_IsWldrNotification(msgBuffer)) { + _handleWldrNotification(listener, msgBuffer); + } else if (messageHandler_IsLoadBalancerProbe(msgBuffer)) { + _handleProbeMessage(listener, msgBuffer); + } else { + messageHandler_handleHooks(hicn->forwarder, msgBuffer, listener, fd, NULL); + parcMemory_Deallocate((void **)&msgBuffer); + } + + return message; +} + +static void _receivePacket(ListenerOps * listener, int fd) { + HicnListener * hicn = (HicnListener*)listener->context; + Message *msg = NULL; + uint8_t *msgBuffer = parcMemory_AllocateAndClear(MTU_SIZE); + msg = _readMessage(listener, fd, msgBuffer); + + if (msg) { + forwarder_Receive(hicn->forwarder, msg); + } +} + +static void _hicnListener_readcb(int fd, PARCEventType what, void *listener_void) { + ListenerOps * listener = (ListenerOps *)listener_void; + HicnListener *hicn = (HicnListener *)listener->context; + + if (hicn->inetFamily == IPv4 || hicn->inetFamily == IPv6) { + if (what & PARCEventType_Read) { + _receivePacket(listener, fd); + } + } else { + _readFrameToDiscard(hicn, fd); + } +} + static bool _isEmptyAddressIPv4(Address *address) { bool res = false; @@ -133,13 +231,8 @@ ListenerOps *hicnListener_CreateInet(Forwarder *forwarder, char *symbolic, hicn->forwarder = forwarder; hicn->listenerName = parcMemory_StringDuplicate(symbolic, strlen(symbolic)); - hicn->logger = logger_Acquire(forwarder_GetLogger(forwarder)); - - hicn->logger = logger_Acquire(forwarder_GetLogger(forwarder)); hicn->conn_id = forwarder_GetNextConnectionId(forwarder); - hicn->localAddress = addressCopy(address); - hicn->inetFamily = IPv4; hicn->connection_id = -1; @@ -438,6 +531,7 @@ static const char *_getListenerName(const ListenerOps *ops) { HicnListener *hicn = (HicnListener *)ops->context; return hicn->listenerName; } + static const char *_getInterfaceName(const ListenerOps *ops) { const char *interfaceName = ""; return interfaceName; @@ -601,96 +695,6 @@ static void _handleWldrNotification(ListenerOps *listener, uint8_t *msgBuffer) { } -static Message *_readMessage(ListenerOps * listener, int fd, uint8_t *msgBuffer) { - HicnListener * hicn = (HicnListener*)listener->context; - Message *message = NULL; - - ssize_t readLength = read(fd, msgBuffer, MTU_SIZE); - - if (readLength < 0) { - printf("read failed %d: (%d) %s\n", fd, errno, strerror(errno)); - return message; - } - - size_t packetLength = messageHandler_GetTotalPacketLength(msgBuffer); - if (readLength != packetLength) { - parcMemory_Deallocate((void **)&msgBuffer); - return message; - } - if (messageHandler_IsTCP(msgBuffer)) { - MessagePacketType pktType; - unsigned connid = 0; - if (messageHandler_IsData(msgBuffer)) { - pktType = MessagePacketType_ContentObject; - if (hicn->connection_id == -1) { - parcMemory_Deallocate((void **)&msgBuffer); - return message; - } else { - connid = hicn->connection_id; - } - } else if (messageHandler_IsInterest(msgBuffer)) { - // notice that the connections for the interest (the one that we create at - // run time) uses as a local address 0::0, so the main tun - pktType = MessagePacketType_Interest; - Address *packetAddr = _createAddressFromPacket(msgBuffer); - AddressPair *pair_find = addressPair_Create(packetAddr, /* dummy */ hicn->localAddress); - const Connection *conn = _lookupConnection(listener, pair_find); - addressPair_Release(&pair_find); - if (conn == NULL) { - AddressPair *pair = addressPair_Create(hicn->localAddress, packetAddr); - connid = _createNewConnection(listener, fd, pair); - addressPair_Release(&pair); - } else { - connid = connection_GetConnectionId(conn); - } - addressDestroy(&packetAddr); - } else { - printf("Got a packet that is not a data nor an interest, drop it!\n"); - parcMemory_Deallocate((void **)&msgBuffer); - return message; - } - - message = message_CreateFromByteArray(connid, msgBuffer, pktType, - forwarder_GetTicks(hicn->forwarder), - forwarder_GetLogger(hicn->forwarder)); - if (message == NULL) { - parcMemory_Deallocate((void **)&msgBuffer); - } - } else if (messageHandler_IsWldrNotification(msgBuffer)) { - _handleWldrNotification(listener, msgBuffer); - } else if (messageHandler_IsLoadBalancerProbe(msgBuffer)) { - _handleProbeMessage(listener, msgBuffer); - } else { - messageHandler_handleHooks(hicn->forwarder, msgBuffer, listener, fd, NULL); - parcMemory_Deallocate((void **)&msgBuffer); - } - - return message; -} - -static void _receivePacket(ListenerOps * listener, int fd) { - HicnListener * hicn = (HicnListener*)listener->context; - Message *msg = NULL; - uint8_t *msgBuffer = parcMemory_AllocateAndClear(MTU_SIZE); - msg = _readMessage(listener, fd, msgBuffer); - - if (msg) { - forwarder_Receive(hicn->forwarder, msg); - } -} - -static void _hicnListener_readcb(int fd, PARCEventType what, void *listener_void) { - ListenerOps * listener = (ListenerOps *)listener_void; - HicnListener *hicn = (HicnListener *)listener->context; - - if (hicn->inetFamily == IPv4 || hicn->inetFamily == IPv6) { - if (what & PARCEventType_Read) { - _receivePacket(listener, fd); - } - } else { - _readFrameToDiscard(hicn, fd); - } -} diff --git a/hicn-light/src/hicn/io/ioOperations.c b/hicn-light/src/hicn/io/ioOperations.c index 31e37a461..b2d346ed8 100644 --- a/hicn-light/src/hicn/io/ioOperations.c +++ b/hicn-light/src/hicn/io/ioOperations.c @@ -41,6 +41,8 @@ const AddressPair *ioOperations_GetAddressPair(const IoOperations *ops) { return ops->getAddressPair(ops); } + + bool ioOperations_IsUp(const IoOperations *ops) { return ops->isUp(ops); } bool ioOperations_IsLocal(const IoOperations *ops) { return ops->isLocal(ops); } diff --git a/hicn-light/src/hicn/io/listenerSet.c b/hicn-light/src/hicn/io/listenerSet.c index 3e44973d7..45dbe887a 100644 --- a/hicn-light/src/hicn/io/listenerSet.c +++ b/hicn-light/src/hicn/io/listenerSet.c @@ -166,3 +166,17 @@ int listenerSet_FindIdByListenerName(const ListenerSet *set, const char *listene return index; } + +void listenerSet_RemoveById(const ListenerSet *set, unsigned id) { + parcAssertNotNull(set, "Parameter set must be non-null"); + + for (size_t i = 0; i < parcArrayList_Size(set->listOfListeners); + i++) { + ListenerOps *ops = parcArrayList_Get(set->listOfListeners, i); + parcAssertNotNull(ops, "Got null listener ops at index %zu", i); + if (ops->getInterfaceIndex(ops) == id) { + parcArrayList_RemoveAtIndex(set->listOfListeners, i); + break; + } + } +} diff --git a/hicn-light/src/hicn/io/listenerSet.h b/hicn-light/src/hicn/io/listenerSet.h index c8937fa02..5779d2af4 100644 --- a/hicn-light/src/hicn/io/listenerSet.h +++ b/hicn-light/src/hicn/io/listenerSet.h @@ -135,7 +135,6 @@ ListenerOps *listenerSet_Get(const ListenerSet *set, size_t index); ListenerOps *listenerSet_Find(const ListenerSet *set, EncapType encapType, const Address *localAddress); - /** * Looks up a listener by its id * @@ -153,6 +152,7 @@ ListenerOps *listenerSet_Find(const ListenerSet *set, EncapType encapType, * @endcode */ ListenerOps *listenerSet_FindById(const ListenerSet *set, unsigned id); + /** * Looks up a listener by its id * @@ -171,4 +171,18 @@ ListenerOps *listenerSet_FindById(const ListenerSet *set, unsigned id); */ int listenerSet_FindIdByListenerName(const ListenerSet *set, const char *listenerName); +/** + * Remove up a listener by its id + * + * <#Paragraphs Of Explanation#> + * + * @param [in] set An allocated listener set + * @param [in] id of the listener + * + * Example: + * @code + * + * @endcode + */ +void listenerSet_RemoveById(const ListenerSet *set, unsigned id); #endif diff --git a/hicn-light/src/hicn/io/streamConnection.c b/hicn-light/src/hicn/io/streamConnection.c index 224f129f7..08ff728d6 100644 --- a/hicn-light/src/hicn/io/streamConnection.c +++ b/hicn-light/src/hicn/io/streamConnection.c @@ -589,6 +589,7 @@ static void _conn_readcb(PARCEventQueue *event, PARCEventType type, // kind of packets while (parcEventBuffer_GetLength(input) >= sizeof(header_control_message) && parcEventBuffer_GetLength(input) >= stream->nextMessageLength) { + if ((command = _isACommand(input)) != LAST_COMMAND_VALUE) { struct iovec *rx; // Get message from the stream and set the stream->nextMessageLength diff --git a/hicn-light/src/hicn/io/tcpListener.c b/hicn-light/src/hicn/io/tcpListener.c index 4464edf28..e2b80c215 100644 --- a/hicn-light/src/hicn/io/tcpListener.c +++ b/hicn-light/src/hicn/io/tcpListener.c @@ -31,7 +31,6 @@ typedef struct tcp_listener { char *listenerName; - Forwarder *forwarder; Logger *logger; @@ -49,10 +48,15 @@ typedef struct tcp_listener { static void _tcpListener_Destroy(_TcpListener **listenerPtr); static void _tcpListener_OpsDestroy(ListenerOps **listenerOpsPtr); + static const char *_tcpListener_ListenerName(const ListenerOps *ops); + static unsigned _tcpListener_OpsGetInterfaceIndex(const ListenerOps *ops); + static const Address *_tcpListener_OpsGetListenAddress(const ListenerOps *ops); + static const char *_tcpListener_InterfaceName(const ListenerOps *ops); + static EncapType _tcpListener_OpsGetEncapType(const ListenerOps *ops); static ListenerOps _tcpTemplate = { @@ -71,6 +75,7 @@ static void _tcpListener_Listen(int, struct sockaddr *, int socklen, ListenerOps *tcpListener_CreateInet6(Forwarder *forwarder, char *listenerName, struct sockaddr_in6 sin6, char *interfaceName) { + _TcpListener *tcp = parcMemory_AllocateAndClear(sizeof(_TcpListener)); parcAssertNotNull(tcp, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(_TcpListener)); @@ -123,7 +128,10 @@ ListenerOps *tcpListener_CreateInet(Forwarder *forwarder, char *listenerName, sizeof(_TcpListener)); tcp->forwarder = forwarder; + tcp->listenerName = parcMemory_StringDuplicate(listenerName, strlen(listenerName)); tcp->logger = logger_Acquire(forwarder_GetLogger(forwarder)); + tcp->interfaceName = parcMemory_StringDuplicate(interfaceName, strlen(interfaceName)); + tcp->listener = dispatcher_CreateListener( forwarder_GetDispatcher(forwarder), _tcpListener_Listen, (void *)tcp, -1, (struct sockaddr *)&sin, sizeof(sin)); @@ -175,7 +183,6 @@ static void _tcpListener_Destroy(_TcpListener **listenerPtr) { parcMemory_Deallocate((void **)&tcp->listenerName); parcMemory_Deallocate((void **)&tcp->interfaceName); - logger_Release(&tcp->logger); dispatcher_DestroyListener(forwarder_GetDispatcher(tcp->forwarder), &tcp->listener); diff --git a/hicn-light/src/hicn/io/udpListener.c b/hicn-light/src/hicn/io/udpListener.c index 050ca104c..f43756a11 100644 --- a/hicn-light/src/hicn/io/udpListener.c +++ b/hicn-light/src/hicn/io/udpListener.c @@ -40,8 +40,8 @@ #define IPv6 6 struct udp_listener { - Forwarder *forwarder; char *listenerName; + Forwarder *forwarder; Logger *logger; PARCEvent *udp_event; @@ -76,6 +76,7 @@ static ListenerOps udpTemplate = { .getInterfaceName = &_getInterfaceName, }; + static void _readcb(int fd, PARCEventType what, void * listener_void); #ifdef __ANDROID__ diff --git a/hicn-light/src/hicn/utils/commands.h b/hicn-light/src/hicn/utils/commands.h index 834da6259..a48dacf48 100644 --- a/hicn-light/src/hicn/utils/commands.h +++ b/hicn-light/src/hicn/utils/commands.h @@ -58,6 +58,7 @@ typedef enum { ADD_ROUTE, LIST_ROUTES, REMOVE_CONNECTION, + REMOVE_LISTENER, REMOVE_ROUTE, CACHE_STORE, CACHE_SERVE, @@ -124,7 +125,7 @@ typedef struct { uint8_t connectionType; } add_listener_command; -// SIZE=40 +// SIZE=56 //========== [01] ADD CONNECTION ========== @@ -167,11 +168,11 @@ typedef struct { uint32_t connid; uint8_t state; uint8_t admin_state; - char connectionName[16]; char interfaceName[16]; + char connectionName[16]; } list_connections_command; -// SIZE=64 +// SIZE=80 //========== [03] ADD ROUTE ========== @@ -198,14 +199,18 @@ typedef struct { // SIZE=24 //========== [05] REMOVE CONNECTION ========== - typedef struct { char symbolicOrConnid[16]; } remove_connection_command; +//========== [06] REMOVE LISTENER ========== +typedef struct { + char symbolicOrListenerid[16]; +} remove_listener_command; + // SIZE=16 -//========== [06] REMOVE ROUTE ========== +//========== [07] REMOVE ROUTE ========== typedef struct { char symbolicOrConnid[16]; @@ -216,7 +221,7 @@ typedef struct { // SIZE=36 -//========== [07] CACHE STORE ========== +//========== [08] CACHE STORE ========== typedef struct { uint8_t activate; @@ -224,7 +229,7 @@ typedef struct { // SIZE=1 -//========== [08] CACHE SERVE ========== +//========== [09] CACHE SERVE ========== typedef struct { uint8_t activate; @@ -232,7 +237,7 @@ typedef struct { // SIZE=1 -//========== [09] SET STRATEGY ========== +//========== [10] SET STRATEGY ========== typedef enum { SET_STRATEGY_LOADBALANCER, @@ -285,7 +290,7 @@ typedef struct { uint8_t encapType; } list_listeners_command; -// SIZE=24 +// SIZE=56 //========== [14] MAPME ========== @@ -353,9 +358,11 @@ static inline int payloadLengthDaemon(command_id id) { case ADD_ROUTE: return sizeof(add_route_command); case LIST_ROUTES: - return 0; // list routes: payload always 0 + return 0; // list rout`es: payload always 0 case REMOVE_CONNECTION: return sizeof(remove_connection_command); + case REMOVE_LISTENER: + return sizeof(remove_listener_command); case REMOVE_ROUTE: return sizeof(remove_route_command); case CACHE_STORE: diff --git a/hicn-light/src/hicn/utils/utils.c b/hicn-light/src/hicn/utils/utils.c index 61ff9a904..93a3efd81 100644 --- a/hicn-light/src/hicn/utils/utils.c +++ b/hicn-light/src/hicn/utils/utils.c @@ -90,7 +90,6 @@ struct iovec *utils_CreateNack(header_control_message *header, void *payload, parcMemory_AllocateAndClear(sizeof(struct iovec) * 2); header->messageType = NACK_LIGHT; - response[0].iov_base = header; response[0].iov_len = sizeof(header_control_message); response[1].iov_base = payload; -- cgit 1.2.3-korg