summaryrefslogtreecommitdiffstats
path: root/hicn-light
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-05-09 11:26:31 +0200
committerJordan Augé <jordan.auge+fdio@cisco.com>2019-05-09 11:26:31 +0200
commit3e2cd52a6ae2345a44f39761beb5315a45832d95 (patch)
tree14f55c9fd58003faed83a3d47756a46d97c09322 /hicn-light
parentc8e6bdf4282c34fd3199cdeec42895cbbc05d9c1 (diff)
[HICN-192] Add interface to administratively set a connection up and down
Change-Id: I8d00262fd8601328a50d0e2a6bef952031246818 Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Diffstat (limited to 'hicn-light')
-rw-r--r--hicn-light/src/hicn/api/api.c39
-rw-r--r--hicn-light/src/hicn/api/api.h5
-rw-r--r--hicn-light/src/hicn/api/commands.h30
-rw-r--r--hicn-light/src/hicn/config/configuration.c60
-rw-r--r--hicn-light/src/hicn/core/CMakeLists.txt3
-rw-r--r--hicn-light/src/hicn/core/connection.c38
-rw-r--r--hicn-light/src/hicn/core/connection.h9
-rw-r--r--hicn-light/src/hicn/core/connectionState.h37
-rw-r--r--hicn-light/src/hicn/io/hicnConnection.c41
-rw-r--r--hicn-light/src/hicn/io/ioOperations.c17
-rw-r--r--hicn-light/src/hicn/io/ioOperations.h48
-rw-r--r--hicn-light/src/hicn/io/streamConnection.c41
-rw-r--r--hicn-light/src/hicn/io/udpConnection.c41
-rw-r--r--hicn-light/src/hicn/utils/commands.h9
14 files changed, 365 insertions, 53 deletions
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), &params, 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), &params, 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 <stdint.h>
#include <stdlib.h>
-#ifdef WITH_POLICY
-#include <hicn/api/face.h>
-#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 <stdio.h>
#include <hicn/core/connection.h>
+#include <hicn/core/connectionState.h>
#include <hicn/core/messageHandler.h>
#include <hicn/core/ticks.h>
#include <hicn/core/wldr.h>
@@ -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 <src/hicn/config.h>
+#include <hicn/core/connectionState.h>
#include <hicn/io/ioOperations.h>
#include <hicn/utils/address.h>
@@ -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 <hicn/core/connectionState.h>
#include <hicn/core/message.h>
#include <hicn/core/ticks.h>
#include <hicn/io/addressPair.h>
@@ -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: