From 3e2cd52a6ae2345a44f39761beb5315a45832d95 Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Thu, 9 May 2019 11:26:31 +0200 Subject: [HICN-192] Add interface to administratively set a connection up and down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8d00262fd8601328a50d0e2a6bef952031246818 Signed-off-by: Jordan Augé --- hicn-light/src/hicn/api/api.c | 39 ++++++++----------- hicn-light/src/hicn/api/api.h | 5 +-- hicn-light/src/hicn/api/commands.h | 30 ++++----------- hicn-light/src/hicn/config/configuration.c | 60 ++++++++++++++++++++++++++++++ hicn-light/src/hicn/core/CMakeLists.txt | 3 +- hicn-light/src/hicn/core/connection.c | 38 ++++++++++++++++++- hicn-light/src/hicn/core/connection.h | 9 +++++ hicn-light/src/hicn/core/connectionState.h | 37 ++++++++++++++++++ hicn-light/src/hicn/io/hicnConnection.c | 41 ++++++++++++++++++++ hicn-light/src/hicn/io/ioOperations.c | 17 +++++++++ hicn-light/src/hicn/io/ioOperations.h | 48 ++++++++++++++++++++++++ hicn-light/src/hicn/io/streamConnection.c | 41 ++++++++++++++++++++ hicn-light/src/hicn/io/udpConnection.c | 41 ++++++++++++++++++++ hicn-light/src/hicn/utils/commands.h | 9 +++++ 14 files changed, 365 insertions(+), 53 deletions(-) create mode 100644 hicn-light/src/hicn/core/connectionState.h (limited to 'hicn-light') diff --git a/hicn-light/src/hicn/api/api.c b/hicn-light/src/hicn/api/api.c index 291f3e6a3..9b3882379 100644 --- a/hicn-light/src/hicn/api/api.c +++ b/hicn-light/src/hicn/api/api.c @@ -806,10 +806,7 @@ int hc_parse_connection(void *in, hc_connection_t *connection) { .local_port = ntohs(cmd->connectionData.localPort), .remote_addr = UNION_CAST(cmd->connectionData.remoteIp, ip_address_t), .remote_port = ntohs(cmd->connectionData.remotePort), -#ifdef WITH_POLICY - .desired_state = cmd->connectionData.desired_state, - .tags = cmd->connectionData.tags, -#endif /* WITH_POLICY */ + .admin_state = cmd->connectionData.admin_state, .state = state, }; strncpy(connection->name, cmd->connectionData.symbolic, NAME_LEN); @@ -843,10 +840,7 @@ int hc_connection_create(hc_sock_t *s, hc_connection_t *connection) { .remotePort = htons(connection->remote_port), .localPort = htons(connection->local_port), .ipType = (u8)map_to_addr_type[connection->family], -#ifdef WITH_POLICY - .desired_state = connection->desired_state, - .tags = connection->tags, -#endif /* WITH_POLICY */ + .admin_state = connection->admin_state, .connectionType = (u8)map_to_connection_type[connection->type], }}; strncpy(msg.payload.symbolic, connection->name, NAME_LEN); @@ -890,40 +884,38 @@ int hc_connection_delete(hc_sock_t *s, hc_connection_t *connection) { return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), ¶ms, NULL); } -#ifdef WITH_POLICY typedef struct { header_control_message hdr; - connection_set_state_command payload; -} hc_msg_connection_set_state_t; + connection_set_admin_state_command payload; +} hc_msg_connection_set_admin_state_t; -int hc_connection_set_state(hc_sock_t *s, const char *conn_id_or_name, - face_state_t state) { - hc_msg_connection_set_state_t msg = { +int hc_connection_set_admin_state(hc_sock_t *s, const char *conn_id_or_name, + hc_connection_state_t admin_state) { + hc_msg_connection_set_admin_state_t msg = { .hdr = { .messageType = REQUEST_LIGHT, - .commandID = CONNECTION_SET_STATE, + .commandID = CONNECTION_SET_ADMIN_STATE, .length = 1, .seqNum = s->send_seq, }, .payload = { - .state = state, + .admin_state = admin_state, }, }; strncpy(msg.payload.symbolicOrConnid, conn_id_or_name, NAME_LEN); hc_command_params_t params = { .cmd = ACTION_SET, - .cmd_id = CONNECTION_SET_STATE, - .size_in = sizeof(connection_set_state_command), + .cmd_id = CONNECTION_SET_ADMIN_STATE, + .size_in = sizeof(connection_set_admin_state_command), .size_out = 0, .parse = NULL, }; return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), ¶ms, NULL); } -#endif /* WITH_POLICY */ typedef struct { header_control_message hdr; @@ -1321,12 +1313,11 @@ ERR: return LIBHICNCTRL_FAILURE; } -#ifdef WITH_POLICY -int hc_face_set_state(hc_sock_t *s, const char *conn_id_or_name, - face_state_t state) { - return hc_connection_set_state(s, conn_id_or_name, state); +int hc_face_set_admin_state(hc_sock_t *s, const char *conn_id_or_name, + hc_connection_state_t admin_state) { + return hc_connection_set_admin_state(s, conn_id_or_name, admin_state); } -#endif /* WITH_POLICY */ + /* /!\ Please update constants in header file upon changes */ size_t hc_face_snprintf(char *s, size_t size, hc_face_t *face) { return LIBHICNCTRL_SUCCESS; diff --git a/hicn-light/src/hicn/api/api.h b/hicn-light/src/hicn/api/api.h index e2358167c..ba07fa7ed 100644 --- a/hicn-light/src/hicn/api/api.h +++ b/hicn-light/src/hicn/api/api.h @@ -448,10 +448,7 @@ typedef struct { u16 local_port; /* .rw */ ip_address_t remote_addr; /* .rw */ u16 remote_port; /* .rw */ -#ifdef WITH_POLICY - face_state_t desired_state; /* .rw */ - face_tags_t tags; /* .rw */ -#endif /* WITH_POLICY */ + hc_connection_state_t admin_state; /* .rw */ hc_connection_state_t state; /* .r. */ } hc_connection_t; diff --git a/hicn-light/src/hicn/api/commands.h b/hicn-light/src/hicn/api/commands.h index c26ac0172..236a75a33 100644 --- a/hicn-light/src/hicn/api/commands.h +++ b/hicn-light/src/hicn/api/commands.h @@ -31,10 +31,6 @@ #include #include -#ifdef WITH_POLICY -#include -#endif /* WITH_POLICY */ - typedef struct in6_addr ipv6_addr_t; typedef uint32_t ipv4_addr_t; @@ -44,7 +40,7 @@ union commandAddr { }; typedef enum { - REQUEST_LIGHT = 0xc0, // this is a command + REQUEST_LIGHT = 0xc0, // this is a command RESPONSE_LIGHT, ACK_LIGHT, NACK_LIGHT, @@ -70,9 +66,7 @@ typedef enum { MAPME_DISCOVERY, MAPME_TIMESCALE, MAPME_RETX, -#ifdef WITH_POLICY - CONNECTION_SET_STATE, -#endif /* WITH_POLICY */ + CONNECTION_SET_ADMIN_STATE, LAST_COMMAND_VALUE } command_id; @@ -132,11 +126,7 @@ typedef struct { uint16_t localPort; uint8_t ipType; uint8_t connectionType; -#ifdef WITH_POLICY - face_state_t - desired_state; /* This is the desired state, not the actual state */ - face_tags_t tags; -#endif /* WITH_POLICY */ + uint8_t admin_state; } add_connection_command; // SIZE=56 @@ -294,14 +284,10 @@ typedef struct { // SIZE=1 -//========== POLICY-RELATED FUNCTIONS ========== - -#ifdef WITH_POLICY typedef struct { char symbolicOrConnid[16]; - face_state_t state; -} connection_set_state_command; -#endif /* WITH_POLICY */ + uint8_t admin_state; +} connection_set_admin_state_command; //===== size of commands ====== // REMINDER: when a new_command is added, the following switch has to be @@ -344,10 +330,8 @@ static inline int payloadLengthDaemon(command_id id) { return sizeof(mapme_timing_command); case MAPME_RETX: return sizeof(mapme_timing_command); -#ifdef WITH_POLICY - case CONNECTION_SET_STATE: - return sizeof(connection_set_state_command); -#endif /* WITH_POLICY */ + case CONNECTION_SET_ADMIN_STATE: + return sizeof(connection_set_admin_state_command); case LAST_COMMAND_VALUE: return 0; default: diff --git a/hicn-light/src/hicn/config/configuration.c b/hicn-light/src/hicn/config/configuration.c index 851e0a9a8..fa3a858c2 100644 --- a/hicn-light/src/hicn/config/configuration.c +++ b/hicn-light/src/hicn/config/configuration.c @@ -78,6 +78,44 @@ struct configuration { // ======================================================================================== +Connection * +getConnectionBySymbolicOrId(Configuration * config, const char * symbolicOrConnid) +{ + ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder); + unsigned connid; + Connection *conn = NULL; + + /* Try to resolve an eventual symbolic name as input */ + if (utils_IsNumber(symbolicOrConnid)) { + connid = strtold(symbolicOrConnid, NULL); + + } else { + connid = symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid); + if (connid == UINT32_MAX) { + if (logger_IsLoggable(config->logger, LoggerFacility_Config, + PARCLogLevel_Warning)) { + logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error, + __func__, "Symbolic name '%s' could not be resolved", + symbolicOrConnid); + } + } + } + + /* Get connection by ID */ + conn = (Connection *)connectionTable_FindById( table, connid); + if (!conn) { + if (logger_IsLoggable(config->logger, LoggerFacility_Config, + PARCLogLevel_Warning)) { + logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error, + __func__, "ConnID not found, check list connections"); + } + } + + return conn; +} + +// ======================================================================================== + Configuration *configuration_Create(Forwarder *forwarder) { parcAssertNotNull(forwarder, "Parameter hicn-fwd must be non-null"); Configuration *config = parcMemory_AllocateAndClear(sizeof(Configuration)); @@ -383,6 +421,8 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, if (ops != NULL) { Connection *conn = connection_Create(ops); + connection_SetAdminState(conn, control->admin_state); + connectionTable_Add(forwarder_GetConnectionTable(config->forwarder), conn); symbolicNameTable_Add(config->symbolicNameTable, symbolicName, @@ -538,6 +578,8 @@ struct iovec *configuration_ProcessConnectionList(Configuration *config, listConnectionsCommand->connectionData.connectionType = ioOperations_GetConnectionType(connection_GetIoOperations(original)); + listConnectionsCommand->connectionData.admin_state = connection_GetAdminState(original); + if (addressGetType(localAddress) == ADDR_INET && addressGetType(remoteAddress) == ADDR_INET) { listConnectionsCommand->connectionData.ipType = ADDR_INET; @@ -970,6 +1012,20 @@ struct iovec *configuration_MapMeRetx(Configuration *config, return response; } +struct iovec *configuration_ConnectionSetAdminState(Configuration *config, + struct iovec *request) { + header_control_message *header = request[0].iov_base; + connection_set_admin_state_command *control = request[1].iov_base; + + Connection * conn = getConnectionBySymbolicOrId(config, control->symbolicOrConnid); + if (!conn) + return utils_CreateNack(header, control, sizeof(connection_set_admin_state_command)); + + connection_SetAdminState(conn, control->admin_state); + + return utils_CreateAck(header, control, sizeof(connection_set_admin_state_command)); +} + // =========================== // Main functions that deal with receiving commands, executing them, and sending // ACK/NACK @@ -1054,6 +1110,10 @@ struct iovec *configuration_DispatchCommand(Configuration *config, response = configuration_MapMeRetx(config, control); break; + case CONNECTION_SET_ADMIN_STATE: + response = configuration_ConnectionSetAdminState(config, control); + break; + default: break; } diff --git a/hicn-light/src/hicn/core/CMakeLists.txt b/hicn-light/src/hicn/core/CMakeLists.txt index 1d7dc03e9..a29409af6 100644 --- a/hicn-light/src/hicn/core/CMakeLists.txt +++ b/hicn-light/src/hicn/core/CMakeLists.txt @@ -15,6 +15,7 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/connectionManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/connectionState.h ${CMAKE_CURRENT_SOURCE_DIR}/ticks.h ${CMAKE_CURRENT_SOURCE_DIR}/connectionList.h ${CMAKE_CURRENT_SOURCE_DIR}/connectionTable.h @@ -52,4 +53,4 @@ list(APPEND SOURCE_FILES ) set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE) -set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file +set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) diff --git a/hicn-light/src/hicn/core/connection.c b/hicn-light/src/hicn/core/connection.c index 61db61ba7..a5d5fb5b9 100644 --- a/hicn-light/src/hicn/core/connection.c +++ b/hicn-light/src/hicn/core/connection.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,6 @@ struct connection { // file/hicnLightControl) this value is set to false so // that a base station can not disable wldr at the client Wldr *wldr; - }; Connection *connection_Create(IoOperations *ops) { @@ -64,6 +64,10 @@ Connection *connection_Create(IoOperations *ops) { conn->counter = 0; conn->last_sent = 0; conn->delay = INT_MAX; + + /* By default, a connection will aim at the UP state */ + connection_SetAdminState(conn, CONNECTION_STATE_UP); + return conn; } @@ -280,3 +284,35 @@ void connection_HandleWldrNotification(Connection *conn, Message *message) { if (conn->wldr != NULL) wldr_HandleWldrNotification(conn->wldr, conn, message); } + +connection_state_t connection_GetState(const Connection *conn) +{ + parcAssertNotNull(conn, "Parameter conn must be non-null"); + if (!conn->ops) + return CONNECTION_STATE_UNDEFINED; + return ioOperations_GetState(conn->ops); +} + +void connection_SetState(Connection *conn, connection_state_t state) +{ + parcAssertNotNull(conn, "Parameter conn must be non-null"); + if (!conn->ops) + return; + ioOperations_SetState(conn->ops, state); +} + +connection_state_t connection_GetAdminState(const Connection *conn) +{ + parcAssertNotNull(conn, "Parameter conn must be non-null"); + if (!conn->ops) + return CONNECTION_STATE_UNDEFINED; + return ioOperations_GetAdminState(conn->ops); +} + +void connection_SetAdminState(Connection *conn, connection_state_t admin_state) +{ + parcAssertNotNull(conn, "Parameter conn must be non-null"); + if (!conn->ops) + return; + ioOperations_SetAdminState(conn->ops, admin_state); +} diff --git a/hicn-light/src/hicn/core/connection.h b/hicn-light/src/hicn/core/connection.h index 9d7cd7c93..204c4668f 100644 --- a/hicn-light/src/hicn/core/connection.h +++ b/hicn-light/src/hicn/core/connection.h @@ -25,6 +25,7 @@ #ifndef connection_h #define connection_h #include +#include #include #include @@ -159,4 +160,12 @@ void connection_DetectLosses(Connection *conn, Message *message); void connection_HandleWldrNotification(Connection *conn, Message *message); +connection_state_t connection_GetState(const Connection *conn); + +void connection_SetState(Connection *conn, connection_state_t state); + +connection_state_t connection_GetAdminState(const Connection *conn); + +void connection_SetAdminState(Connection *conn, connection_state_t admin_state); + #endif // connection_h diff --git a/hicn-light/src/hicn/core/connectionState.h b/hicn-light/src/hicn/core/connectionState.h new file mode 100644 index 000000000..9daa15c9c --- /dev/null +++ b/hicn-light/src/hicn/core/connectionState.h @@ -0,0 +1,37 @@ +/* + * 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 connection_state.h + * @brief Represents the state of a connection + * + */ + +#ifndef connection_state_h +#define connection_state_h + +#define foreach_connection_state \ + _(UNDEFINED) \ + _(DOWN) \ + _(UP) \ + _(N) + +typedef enum { +#define _(x) CONNECTION_STATE_ ## x, +foreach_connection_state +#undef _ +} connection_state_t; + +#endif /* connection_state_h */ diff --git a/hicn-light/src/hicn/io/hicnConnection.c b/hicn-light/src/hicn/io/hicnConnection.c index 3c6f0612c..c6831df57 100644 --- a/hicn-light/src/hicn/io/hicnConnection.c +++ b/hicn-light/src/hicn/io/hicnConnection.c @@ -72,6 +72,11 @@ typedef struct hicn_state { unsigned id; unsigned delay; + + /* This information would better be stored in the connection data structure + * but it is currently not reachable from within the implementation. */ + connection_state_t state; + connection_state_t admin_state; } _HicnState; // Prototypes @@ -87,6 +92,10 @@ static void _destroy(IoOperations **opsPtr); static list_connections_type _getConnectionType(const IoOperations *ops); static Ticks _sendProbe(IoOperations *ops, unsigned probeType, uint8_t *message); +static connection_state_t _getState(const IoOperations *ops); +static void _setState(IoOperations *ops, connection_state_t state); +static connection_state_t _getAdminState(const IoOperations *ops); +static void _setAdminState(IoOperations *ops, connection_state_t admin_state); /* * This assigns a unique pointer to the void * which we use @@ -114,6 +123,10 @@ static IoOperations _template = { .class = &_streamConnection_Class, .getConnectionType = &_getConnectionType, .sendProbe = &_sendProbe, + .getState = &_getState, + .setState = &_setState, + .getAdminState = &_getAdminState, + .setAdminState = &_setAdminState, }; // ================================================================= @@ -546,3 +559,31 @@ static void _setConnectionState(_HicnState *hicnConnState, bool isUp) { return; } } + +static connection_state_t _getState(const IoOperations *ops) { + parcAssertNotNull(ops, "Parameter must be non-null"); + const _HicnState *hicnConnState = + (const _HicnState *)ioOperations_GetClosure(ops); + return hicnConnState->state; +} + +static void _setState(IoOperations *ops, connection_state_t state) { + parcAssertNotNull(ops, "Parameter must be non-null"); + _HicnState *hicnConnState = + (_HicnState *)ioOperations_GetClosure(ops); + hicnConnState->state = state; +} + +static connection_state_t _getAdminState(const IoOperations *ops) { + parcAssertNotNull(ops, "Parameter must be non-null"); + const _HicnState *hicnConnState = + (const _HicnState *)ioOperations_GetClosure(ops); + return hicnConnState->admin_state; +} + +static void _setAdminState(IoOperations *ops, connection_state_t admin_state) { + parcAssertNotNull(ops, "Parameter must be non-null"); + _HicnState *hicnConnState = + (_HicnState *)ioOperations_GetClosure(ops); + hicnConnState->admin_state = admin_state; +} diff --git a/hicn-light/src/hicn/io/ioOperations.c b/hicn-light/src/hicn/io/ioOperations.c index a9b763448..5693f86c5 100644 --- a/hicn-light/src/hicn/io/ioOperations.c +++ b/hicn-light/src/hicn/io/ioOperations.c @@ -66,3 +66,20 @@ Ticks ioOperations_SendProbe(IoOperations *ops, unsigned probeType, uint8_t *message) { return ops->sendProbe(ops, probeType, message); } + + +connection_state_t ioOperations_GetState(const IoOperations *ops) { + return ops->getState(ops); +} + +void ioOperations_SetState(IoOperations *ops, connection_state_t state) { + ops->setState(ops, state); +} + +connection_state_t ioOperations_GetAdminState(const IoOperations *ops) { + return ops->getAdminState(ops); +} + +void ioOperations_SetAdminState(IoOperations *ops, connection_state_t admin_state) { + ops->setAdminState(ops, admin_state); +} diff --git a/hicn-light/src/hicn/io/ioOperations.h b/hicn-light/src/hicn/io/ioOperations.h index c5e58d8b2..7a48b7e3e 100644 --- a/hicn-light/src/hicn/io/ioOperations.h +++ b/hicn-light/src/hicn/io/ioOperations.h @@ -26,6 +26,7 @@ #ifndef io_h #define io_h +#include #include #include #include @@ -58,6 +59,14 @@ typedef struct io_ops IoOperations; * IoOperations. * @constant getConnectionType Returns the type of connection (TCP, UDP, L2, * etc.) of the underlying connection. + * @constant getState Returns the current state of the connection (redundant + * with isUp for added for completeness of the API). + * @constant setState Allows to mark the current state of a connection. + * @constant getAdminState Returns the administrative state of a connection (as + * requested by the user, which might occasionally differ from the current + * state). + * @constant setAdminState Allows to set the administrative state of a + * connection. * @discussion <#Discussion#> */ struct io_ops { @@ -74,6 +83,10 @@ struct io_ops { const void *(*class)(const IoOperations *ops); list_connections_type (*getConnectionType)(const IoOperations *ops); Ticks (*sendProbe)(IoOperations *ops, unsigned probeType, uint8_t *message); + connection_state_t (*getState)(const IoOperations *ops); + void (*setState)(IoOperations *ops, connection_state_t state); + connection_state_t (*getAdminState)(const IoOperations *ops); + void (*setAdminState)(IoOperations *ops, connection_state_t admin_state); }; /** @@ -365,4 +378,39 @@ list_connections_type ioOperations_GetConnectionType(const IoOperations *ops); Ticks ioOperations_SendProbe(IoOperations *ops, unsigned probeType, uint8_t *message); + +/** + * Returns the current state of the connection + * + * @param [in] ops The connection implementation. + * + * @return Connection state (connection_state_t). + */ +connection_state_t ioOperations_GetState(const IoOperations *ops); + +/** + * Sets the current state of the connection + * + * @param [in] ops The connection implementation. + * @param [in] state New state to set (connection_state_t). + */ +void ioOperations_SetState(IoOperations *ops, connection_state_t state); + +/** + * Returns the administrative state of the connection + * + * @param [in] ops The connection implementation. + * + * @return Connection state (connection_state_t). + */ +connection_state_t ioOperations_GetAdminState(const IoOperations *ops); + +/** + * Sets the administrative state of the connection + * + * @param [in] ops The connection implementation. + * @param [in] state New state to set (connection_state_t). + */ +void ioOperations_SetAdminState(IoOperations *ops, connection_state_t admin_state); + #endif // io_h diff --git a/hicn-light/src/hicn/io/streamConnection.c b/hicn-light/src/hicn/io/streamConnection.c index 465e0c326..1c868c611 100644 --- a/hicn-light/src/hicn/io/streamConnection.c +++ b/hicn-light/src/hicn/io/streamConnection.c @@ -60,6 +60,11 @@ typedef struct stream_state { unsigned id; size_t nextMessageLength; + + /* This information would better be stored in the connection data structure + * but it is currently not reachable from within the implementation. */ + connection_state_t state; + connection_state_t admin_state; } _StreamState; // Prototypes @@ -81,6 +86,10 @@ static list_connections_type _streamConnection_GetConnectionType( const IoOperations *ops); static Ticks _sendProbe(IoOperations *ops, unsigned probeType, uint8_t *message); +static connection_state_t _streamConnection_getState(const IoOperations *ops); +static void _streamConnection_setState(IoOperations *ops, connection_state_t state); +static connection_state_t _streamConnection_getAdminState(const IoOperations *ops); +static void _streamConnection_setAdminState(IoOperations *ops, connection_state_t admin_state); /* * This assigns a unique pointer to the void * which we use @@ -108,6 +117,10 @@ static IoOperations _template = { .class = &_streamConnection_Class, .getConnectionType = &_streamConnection_GetConnectionType, .sendProbe = &_sendProbe, + .getState = &_streamConnection_getState, + .setState = &_streamConnection_setState, + .getAdminState = &_streamConnection_getAdminState, + .setAdminState = &_streamConnection_setAdminState, }; IoOperations *streamConnection_AcceptConnection(Forwarder *forwarder, int fd, @@ -687,3 +700,31 @@ static void _conn_eventcb(PARCEventQueue *event, PARCEventQueueEventType events, /* None of the other events can happen here, since we haven't enabled * timeouts */ } + +static connection_state_t _streamConnection_getState(const IoOperations *ops) { + parcAssertNotNull(ops, "Parameter must be non-null"); + const _StreamState *stream = + (const _StreamState *)ioOperations_GetClosure(ops); + return stream->state; +} + +static void _streamConnection_setState(IoOperations *ops, connection_state_t state) { + parcAssertNotNull(ops, "Parameter must be non-null"); + _StreamState *stream = + (_StreamState *)ioOperations_GetClosure(ops); + stream->state = state; +} + +static connection_state_t _streamConnection_getAdminState(const IoOperations *ops) { + parcAssertNotNull(ops, "Parameter must be non-null"); + const _StreamState *stream = + (const _StreamState *)ioOperations_GetClosure(ops); + return stream->admin_state; +} + +static void _streamConnection_setAdminState(IoOperations *ops, connection_state_t admin_state) { + parcAssertNotNull(ops, "Parameter must be non-null"); + _StreamState *stream = + (_StreamState *)ioOperations_GetClosure(ops); + stream->admin_state = admin_state; +} diff --git a/hicn-light/src/hicn/io/udpConnection.c b/hicn-light/src/hicn/io/udpConnection.c index 69cbea0e1..fb1865df3 100644 --- a/hicn-light/src/hicn/io/udpConnection.c +++ b/hicn-light/src/hicn/io/udpConnection.c @@ -57,6 +57,11 @@ typedef struct udp_state { unsigned id; unsigned delay; + + /* This information would better be stored in the connection data structure + * but it is currently not reachable from within the implementation. */ + connection_state_t state; + connection_state_t admin_state; } _UdpState; // Prototypes @@ -72,6 +77,10 @@ static void _destroy(IoOperations **opsPtr); static list_connections_type _getConnectionType(const IoOperations *ops); static Ticks _sendProbe(IoOperations *ops, unsigned probeType, uint8_t *message); +static connection_state_t _getState(const IoOperations *ops); +static void _setState(IoOperations *ops, connection_state_t state); +static connection_state_t _getAdminState(const IoOperations *ops); +static void _setAdminState(IoOperations *ops, connection_state_t admin_state); /* * This assigns a unique pointer to the void * which we use @@ -99,6 +108,10 @@ static IoOperations _template = { .class = &_streamConnection_Class, .getConnectionType = &_getConnectionType, .sendProbe = &_sendProbe, + .getState = &_getState, + .setState = &_setState, + .getAdminState = &_getAdminState, + .setAdminState = &_setAdminState, }; // ================================================================= @@ -394,3 +407,31 @@ static void _setConnectionState(_UdpState *udpConnState, bool isUp) { return; } } + +static connection_state_t _getState(const IoOperations *ops) { + parcAssertNotNull(ops, "Parameter must be non-null"); + const _UdpState *udpConnState = + (const _UdpState *)ioOperations_GetClosure(ops); + return udpConnState->state; +} + +static void _setState(IoOperations *ops, connection_state_t state) { + parcAssertNotNull(ops, "Parameter must be non-null"); + _UdpState *udpConnState = + (_UdpState *)ioOperations_GetClosure(ops); + udpConnState->state = state; +} + +static connection_state_t _getAdminState(const IoOperations *ops) { + parcAssertNotNull(ops, "Parameter must be non-null"); + const _UdpState *udpConnState = + (const _UdpState *)ioOperations_GetClosure(ops); + return udpConnState->admin_state; +} + +static void _setAdminState(IoOperations *ops, connection_state_t admin_state) { + parcAssertNotNull(ops, "Parameter must be non-null"); + _UdpState *udpConnState = + (_UdpState *)ioOperations_GetClosure(ops); + udpConnState->admin_state = admin_state; +} diff --git a/hicn-light/src/hicn/utils/commands.h b/hicn-light/src/hicn/utils/commands.h index 802e6bfa6..236a75a33 100644 --- a/hicn-light/src/hicn/utils/commands.h +++ b/hicn-light/src/hicn/utils/commands.h @@ -66,6 +66,7 @@ typedef enum { MAPME_DISCOVERY, MAPME_TIMESCALE, MAPME_RETX, + CONNECTION_SET_ADMIN_STATE, LAST_COMMAND_VALUE } command_id; @@ -125,6 +126,7 @@ typedef struct { uint16_t localPort; uint8_t ipType; uint8_t connectionType; + uint8_t admin_state; } add_connection_command; // SIZE=56 @@ -282,6 +284,11 @@ typedef struct { // SIZE=1 +typedef struct { + char symbolicOrConnid[16]; + uint8_t admin_state; +} connection_set_admin_state_command; + //===== size of commands ====== // REMINDER: when a new_command is added, the following switch has to be // updated. @@ -323,6 +330,8 @@ static inline int payloadLengthDaemon(command_id id) { return sizeof(mapme_timing_command); case MAPME_RETX: return sizeof(mapme_timing_command); + case CONNECTION_SET_ADMIN_STATE: + return sizeof(connection_set_admin_state_command); case LAST_COMMAND_VALUE: return 0; default: -- cgit 1.2.3-korg