From 6b84ec54083da9911f5ad4816d0eb4f4745afad4 Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Mon, 7 Oct 2019 09:52:33 +0200 Subject: [HICN-298] Release new hICN app for Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I43adc62fadf00690b687078d739788dffdc5e566 Signed-off-by: Jordan Augé --- hicn-light/src/hicn/config/configuration.c | 77 +++++--- .../src/hicn/config/configurationListeners.c | 197 ++++++--------------- .../src/hicn/config/controlListConnections.c | 14 +- hicn-light/src/hicn/config/controlListListeners.c | 21 ++- .../src/hicn/config/controlUpdateConnection.c | 2 +- 5 files changed, 140 insertions(+), 171 deletions(-) (limited to 'hicn-light/src/hicn/config') diff --git a/hicn-light/src/hicn/config/configuration.c b/hicn-light/src/hicn/config/configuration.c index 182c2fdc1..b14ea551a 100644 --- a/hicn-light/src/hicn/config/configuration.c +++ b/hicn-light/src/hicn/config/configuration.c @@ -363,30 +363,32 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, Address *source = NULL; Address *destination = NULL; - if (!symbolicNameTable_Exists(config->symbolicNameTable, symbolicName)) { - if (control->ipType == ADDR_INET) { - source = - addressFromInaddr4Port(&control->localIp.ipv4, &control->localPort); - destination = - addressFromInaddr4Port(&control->remoteIp.ipv4, &control->remotePort); - } else if (control->ipType == ADDR_INET6) { - source = - addressFromInaddr6Port(&control->localIp.ipv6, &control->localPort); - destination = - addressFromInaddr6Port(&control->remoteIp.ipv6, &control->remotePort); - } else { - printf("Invalid IP type.\n"); // will generate a Nack - } - - AddressPair *pair = addressPair_Create(source, destination); - conn = (Connection *)connectionTable_FindByAddressPair( - forwarder_GetConnectionTable(config->forwarder), pair); + if (symbolicNameTable_Exists(config->symbolicNameTable, symbolicName)) { + logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error, + __func__, "Listener symbolic name already exists"); + goto ERR; + } - addressPair_Release(&pair); + if (control->ipType == ADDR_INET) { + source = + addressFromInaddr4Port(&control->localIp.ipv4, &control->localPort); + destination = + addressFromInaddr4Port(&control->remoteIp.ipv4, &control->remotePort); + } else if (control->ipType == ADDR_INET6) { + source = + addressFromInaddr6Port(&control->localIp.ipv6, &control->localPort); + destination = + addressFromInaddr6Port(&control->remoteIp.ipv6, &control->remotePort); } else { - conn = NULL; + printf("Invalid IP type.\n"); // will generate a Nack } + AddressPair *pair = addressPair_Create(source, destination); + conn = (Connection *)connectionTable_FindByAddressPair( + forwarder_GetConnectionTable(config->forwarder), pair); + + addressPair_Release(&pair); + if (!conn) { IoOperations *ops = NULL; switch (control->connectionType) { @@ -460,11 +462,14 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, if (destination) addressDestroy(&destination); - if (success) { // ACK - return utils_CreateAck(header, control, sizeof(add_connection_command)); - } else { // NACK + if (!success) + goto ERR; + + // ACK + return utils_CreateAck(header, control, sizeof(add_connection_command)); + +ERR: return utils_CreateNack(header, control, sizeof(add_connection_command)); - } } /** @@ -577,6 +582,13 @@ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, return response; } +void _strlwr(char *string) { + char *p = string; + while ((*p = tolower(*p))) { + p++; + } +} + struct iovec *configuration_ProcessConnectionList(Configuration *config, struct iovec *request) { ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder); @@ -603,8 +615,17 @@ struct iovec *configuration_ProcessConnectionList(Configuration *config, // set structure fields listConnectionsCommand->connid = connection_GetConnectionId(original); + + const char *connectionName = symbolicNameTable_GetNameByIndex(config->symbolicNameTable, connection_GetConnectionId(original)); + snprintf(listConnectionsCommand->connectionName, 16, "%s", connectionName); + _strlwr(listConnectionsCommand->connectionName); + + snprintf(listConnectionsCommand->interfaceName, 16, "%s", ioOperations_GetInterfaceName(connection_GetIoOperations(original))); + listConnectionsCommand->state = connection_IsUp(original) ? IFACE_UP : IFACE_DOWN; + listConnectionsCommand->admin_state = + (connection_GetAdminState(original) == CONNECTION_STATE_UP) ? IFACE_UP : IFACE_DOWN; listConnectionsCommand->connectionData.connectionType = ioOperations_GetConnectionType(connection_GetIoOperations(original)); @@ -707,6 +728,14 @@ struct iovec *configuration_ProcessListenersList(Configuration *config, listListenersCommand->address.ipv6 = tmpAddr6.sin6_addr; listListenersCommand->port = tmpAddr6.sin6_port; } + + const char * listenerName = listenerEntry->getListenerName(listenerEntry); + snprintf(listListenersCommand->listenerName, 16, "%s", listenerName); + if (listenerEntry->getEncapType(listenerEntry) == ENCAP_TCP || + listenerEntry->getEncapType(listenerEntry) == ENCAP_UDP) { + const char * interfaceName = listenerEntry->getInterfaceName(listenerEntry); + snprintf(listListenersCommand->interfaceName, 16, "%s", interfaceName); + } } // send response diff --git a/hicn-light/src/hicn/config/configurationListeners.c b/hicn-light/src/hicn/config/configurationListeners.c index 97e7dbb87..86d8a215a 100644 --- a/hicn-light/src/hicn/config/configurationListeners.c +++ b/hicn-light/src/hicn/config/configurationListeners.c @@ -211,32 +211,21 @@ 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] listenerName The name of the listener * @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. - * - * @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 - * - * return true if success, false otherwise - */ -static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4, - uint16_t *port) { -#endif +static bool _setupTcpListenerOnInet(Forwarder *forwarder, char *listenerName, ipv4_addr_t *addr4, + uint16_t *port, char *interfaceName) { + parcAssertNotNull(listenerName, "Parameter listenerName must be non-null"); + bool success = false; struct sockaddr_in addr; @@ -245,42 +234,31 @@ static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4, addr.sin_port = *port; addr.sin_addr.s_addr = *addr4; - ListenerOps *ops = tcpListener_CreateInet(forwarder, addr); + ListenerOps *ops = tcpListener_CreateInet(forwarder, listenerName, addr, interfaceName); if (ops) { success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops); +#if 0 parcAssertTrue(success, "Failed to add TCP listener on %s to ListenerSet", addressToString(ops->getListenAddress(ops))); +#endif } return success; } -#ifdef __linux__ /* * Create a new IPV4/UDP listener. * * @param [in,out] forwarder The hicn-light forwarder instance + * @param [in] listenerName The name of the listener * @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, +static bool _setupUdpListenerOnInet(Forwarder *forwarder, char *listenerName, ipv4_addr_t *addr4, uint16_t *port, char *interfaceName) { -#else -/* - * 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 - * - * return true if success, false otherwise - */ -static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4, - uint16_t *port) { -#endif bool success = false; struct sockaddr_in addr; @@ -289,21 +267,18 @@ 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 + ListenerOps *ops = udpListener_CreateInet(forwarder, listenerName, addr, interfaceName); if (ops) { success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops); +#if 0 parcAssertTrue(success, "Failed to add UDP listener on %s to ListenerSet", addressToString(ops->getListenAddress(ops))); +#endif } return success; } -#ifdef __linux__ /* * Create a new IPV6/TCP listener. * @@ -314,23 +289,9 @@ static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4, * * return true if success, false otherwise */ -static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder, +static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder, char *listenerName, ipv6_addr_t *addr6, uint16_t *port, char *interfaceName, uint32_t scopeId) { -#else -/* - * 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 - * - * return true if success, false otherwise - */ -static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder, - ipv6_addr_t *addr6, uint16_t *port, - uint32_t scopeId) { -#endif bool success = false; struct sockaddr_in6 addr; @@ -340,17 +301,18 @@ static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder, addr.sin6_addr = *addr6; addr.sin6_scope_id = scopeId; - ListenerOps *ops = tcpListener_CreateInet6(forwarder, addr); + ListenerOps *ops = tcpListener_CreateInet6(forwarder, listenerName, addr, interfaceName); if (ops) { success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops); +#if 0 parcAssertTrue(success, "Failed to add TCP6 listener on %s to ListenerSet", addressToString(ops->getListenAddress(ops))); +#endif } return success; } -#ifdef __linux__ /* * Create a new IPV6/UDP listener. * @@ -361,21 +323,8 @@ static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder, * * return true if success, false otherwise */ -static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder, +static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder, char *listenerName, ipv6_addr_t *addr6, uint16_t *port, char *interfaceName) { -#else -/* - * 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 - * - * return true if success, false otherwise - */ -static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder, - ipv6_addr_t *addr6, uint16_t *port) { -#endif bool success = false; struct sockaddr_in6 addr; @@ -385,15 +334,13 @@ 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 + ListenerOps *ops = udpListener_CreateInet6(forwarder, listenerName, addr, interfaceName); if (ops) { success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops); +#if 0 parcAssertTrue(success, "Failed to add UDP6 listener on %s to ListenerSet", addressToString(ops->getListenAddress(ops))); +#endif } return success; } @@ -460,56 +407,33 @@ bool _addHicn(Configuration *config, add_listener_command *control, bool _addIP(Configuration *config, add_listener_command *control, unsigned ingressId) { bool success = false; + char *symbolic = control->symbolic; switch (control->addressType) { case ADDR_INET: { -#ifdef __linux__ if (control->connectionType == UDP_CONN) { success = - _setupUdpListenerOnInet(configuration_GetForwarder(config), + _setupUdpListenerOnInet(configuration_GetForwarder(config), symbolic, &control->address.ipv4, &control->port, control->interfaceName); } else if (control->connectionType == TCP_CONN) { success = - _setupTcpListenerOnInet(configuration_GetForwarder(config), + _setupTcpListenerOnInet(configuration_GetForwarder(config), symbolic, &control->address.ipv4, &control->port, control->interfaceName); } -#else - if (control->connectionType == UDP_CONN) { - success = - _setupUdpListenerOnInet(configuration_GetForwarder(config), - &control->address.ipv4, &control->port); - } else if (control->connectionType == TCP_CONN) { - success = - _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, + configuration_GetForwarder(config), symbolic, &control->address.ipv6, &control->port, control->interfaceName); } else if (control->connectionType == TCP_CONN) { success = _setupTcpListenerOnInet6Light( - configuration_GetForwarder(config), &control->address.ipv6, + configuration_GetForwarder(config), symbolic, &control->address.ipv6, &control->port, control->interfaceName, 0); } -#else - if (control->connectionType == UDP_CONN) { - success = _setupUdpListenerOnInet6Light( - configuration_GetForwarder(config), &control->address.ipv6, - &control->port); - } else if (control->connectionType == TCP_CONN) { - success = _setupTcpListenerOnInet6Light( - configuration_GetForwarder(config), &control->address.ipv6, - &control->port, 0); - } -#endif break; } @@ -551,20 +475,25 @@ struct iovec *configurationListeners_Add(Configuration *config, bool success = false; - if (control->listenerMode == ETHER_MODE) { - parcTrapNotImplemented("Add Ethernet Listener is not supported"); - success = _addEther(config, control, ingressId); - // it is a failure - } else if (control->listenerMode == IP_MODE) { - success = _addIP(config, control, ingressId); - } else if (control->listenerMode == HICN_MODE) { - success = _addHicn(config, control, ingressId); - } else { - Logger *logger = configuration_GetLogger(config); - if (logger_IsLoggable(logger, LoggerFacility_Config, - PARCLogLevel_Warning)) { - logger_Log(logger, LoggerFacility_Config, PARCLogLevel_Warning, __func__, - "Unsupported encapsulation mode (ingress id %u)", ingressId); + ListenerSet *listenerSet = forwarder_GetListenerSet(configuration_GetForwarder(config)); + int listenerId = listenerSet_FindIdByListenerName(listenerSet, control->symbolic); + + if (listenerId < 0) { + if (control->listenerMode == ETHER_MODE) { + parcTrapNotImplemented("Add Ethernet Listener is not supported"); + success = _addEther(config, control, ingressId); + // it is a failure + } else if (control->listenerMode == IP_MODE) { + success = _addIP(config, control, ingressId); + } else if (control->listenerMode == HICN_MODE) { + success = _addHicn(config, control, ingressId); + } else { + Logger *logger = configuration_GetLogger(config); + if (logger_IsLoggable(logger, LoggerFacility_Config, + PARCLogLevel_Warning)) { + logger_Log(logger, LoggerFacility_Config, PARCLogLevel_Warning, __func__, + "Unsupported encapsulation mode (ingress id %u)", ingressId); + } } } @@ -619,7 +548,7 @@ struct iovec *configurationListeners_AddPunting(Configuration *config, //=========================== INITIAL LISTENERS ==================== -static void _setupListenersOnAddress(Forwarder *forwarder, +static void _setupListenersOnAddress(Forwarder *forwarder, char *listenerName, const Address *address, uint16_t port, char *interfaceName) { address_type type = addressGetType(address); @@ -627,24 +556,15 @@ static void _setupListenersOnAddress(Forwarder *forwarder, 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 + _setupTcpListenerOnInet(forwarder, listenerName, &tmp.sin_addr.s_addr, &port, interfaceName); 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, + _setupTcpListenerOnInet6Light(forwarder, listenerName, &tmp.sin6_addr, &port, interfaceName, tmp.sin6_scope_id); -#endif break; } @@ -674,8 +594,14 @@ void configurationListeners_SetupAll(const Configuration *config, uint16_t port, const Address *address = addressListGetItem(addresses, j); // Do not start on link address + char listenerName[16]; +#ifdef __ANDROID__ + snprintf(listenerName, 16, "local_%zu", i); +#else + snprintf(listenerName, 16, "local_%ld", i); +#endif if (addressGetType(address) != ADDR_LINK) { - _setupListenersOnAddress(forwarder, address, port, + _setupListenersOnAddress(forwarder, listenerName, address, port, (char *)interfaceGetName(iface)); } } @@ -689,16 +615,11 @@ 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 listenerNameUdp[16] = "lo_udp"; + char listenerNameTcp[16] = "lo_tcp"; char *loopback_interface = "lo"; - _setupUdpListenerOnInet(forwarder, (ipv4_addr_t *)&(addr), + _setupUdpListenerOnInet(forwarder, listenerNameUdp,(ipv4_addr_t *)&(addr), &network_byte_order_port, loopback_interface); - _setupTcpListenerOnInet(forwarder, (ipv4_addr_t *)&(addr), + _setupTcpListenerOnInet(forwarder, listenerNameTcp, (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/controlListConnections.c b/hicn-light/src/hicn/config/controlListConnections.c index 0eb6392ea..dbd9707ca 100644 --- a/hicn-light/src/hicn/config/controlListConnections.c +++ b/hicn-light/src/hicn/config/controlListConnections.c @@ -83,7 +83,7 @@ static CommandReturn _controlListConnections_Execute(CommandParser *parser, return CommandReturn_Failure; } #ifdef WITH_POLICY - char flags_str[POLICY_TAG_N]; + char flags_str[POLICY_TAG_N+1]; char *s; #endif /* WITH_POLICY */ @@ -113,6 +113,12 @@ static CommandReturn _controlListConnections_Execute(CommandParser *parser, } } +#ifdef WITH_POLICY + printf("%5s %10s %12s %6s %40s %40s %5s %s\n", "id", "name", "admin_state", "state", "source", "destination", "type", "flags"); +#else + printf("%5s %10s %12s %6s %40s %40s %5s\n", "id", "name", "admin_state", "state", "source", "destination", "type"); +#endif /* WITH_POLICY */ + // Process/Print payload for (int i = 0; i < receivedHeader->length; i++) { list_connections_command *listConnectionsCommand = @@ -140,7 +146,8 @@ foreach_policy_tag *s = '\0'; parcBufferComposer_Format( - composer, "%5d %4s %s %s %s [%s]", listConnectionsCommand->connid, + composer, "%5d %10s %12s %6s %40s %40s %5s [%s]", listConnectionsCommand->connid, listConnectionsCommand->connectionName, + stateString[listConnectionsCommand->admin_state], stateString[listConnectionsCommand->state], sourceString, destinationString, connTypeString[listConnectionsCommand->connectionData.connectionType], @@ -148,7 +155,8 @@ foreach_policy_tag #else parcBufferComposer_Format( - composer, "%5d %4s %s %s %s", listConnectionsCommand->connid, + composer, "%5d %10s %12s %6s %40s %40s %5s", listConnectionsCommand->connid, listConnectionsCommand->connectionName, + stateString[listConnectionsCommand->admin_state], stateString[listConnectionsCommand->state], sourceString, destinationString, connTypeString[listConnectionsCommand->connectionData.connectionType]); diff --git a/hicn-light/src/hicn/config/controlListListeners.c b/hicn-light/src/hicn/config/controlListListeners.c index 1f4ad7f2c..5be7b0a9b 100644 --- a/hicn-light/src/hicn/config/controlListListeners.c +++ b/hicn-light/src/hicn/config/controlListListeners.c @@ -95,7 +95,8 @@ static CommandReturn _controlListListeners_Execute(CommandParser *parser, char *addrString = NULL; if (receivedHeader->length > 0) { - printf("%6.6s %50.70s %s\n", "iface", "address", "type"); + printf("%6.6s %16s %50.70s %6s %10s\n", "iface", "name", "address", "type", "interface"); + } else { printf(" --- No entry in the list \n"); } @@ -111,16 +112,26 @@ static CommandReturn _controlListListeners_Execute(CommandParser *parser, PARCBufferComposer *composer = parcBufferComposer_Create(); - parcBufferComposer_Format(composer, "%6u %50.70s %3s", - listListenersCommand->connid, addrString, - listenerType[listListenersCommand->encapType]); + if (strcmp(listenerType[listListenersCommand->encapType], "UDP") == 0 || + strcmp(listenerType[listListenersCommand->encapType], "TCP") == 0) { + parcBufferComposer_Format(composer, "%6u %16s %50.70s %6s %10s", + listListenersCommand->connid, + listListenersCommand->listenerName,addrString, + listenerType[listListenersCommand->encapType], + listListenersCommand->interfaceName); + } else { + parcBufferComposer_Format(composer, "%6u %16s %50.70s %6s", + listListenersCommand->connid, + listListenersCommand->listenerName,addrString, + listenerType[listListenersCommand->encapType]); + } PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer); char *result = parcBuffer_ToString(tempBuffer); parcBuffer_Release(&tempBuffer); if (!controlState_IsInteractive(state)) { - strcpy(commandOutputMain[i], result); + strncpy(commandOutputMain[i], result, 128); } puts(result); diff --git a/hicn-light/src/hicn/config/controlUpdateConnection.c b/hicn-light/src/hicn/config/controlUpdateConnection.c index 3e573d41d..ff834522e 100644 --- a/hicn-light/src/hicn/config/controlUpdateConnection.c +++ b/hicn-light/src/hicn/config/controlUpdateConnection.c @@ -31,9 +31,9 @@ #include +#include #include #include -#include static CommandReturn _controlUpdateConnection_Execute(CommandParser *parser, CommandOps *ops, -- cgit 1.2.3-korg