aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/core/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-light/src/hicn/core/connection.c')
-rw-r--r--hicn-light/src/hicn/core/connection.c720
1 files changed, 478 insertions, 242 deletions
diff --git a/hicn-light/src/hicn/core/connection.c b/hicn-light/src/hicn/core/connection.c
index c2ac71a5f..582e2f56f 100644
--- a/hicn-light/src/hicn/core/connection.c
+++ b/hicn-light/src/hicn/core/connection.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -13,347 +13,583 @@
* limitations under the License.
*/
-#include <limits.h>
-#include <hicn/hicn-light/config.h>
-#include <stdio.h>
+/**
+ * @file connection.c
+ * @brief Implementation of hICN connections
+ */
-#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>
-#include <hicn/io/addressPair.h>
-#include <hicn/io/ioOperations.h>
+#include <assert.h>
-#include <parc/algol/parc_Memory.h>
-#include <parc/assert/parc_Assert.h>
-#ifdef WITH_POLICY
-#include <hicn/policy.h>
-#endif /* WITH_POLICY */
+#include <hicn/core/forwarder.h>
+#include <hicn/util/log.h>
+#include <hicn/core/wldr.h>
-struct connection {
+#include "connection.h"
+#include "connection_vft.h"
- const AddressPair *addressPair;
- IoOperations *ops;
+#define _conn_var(x) _connection_ ## x
- unsigned refCount;
+#if 0
- unsigned counter;
+/* Accessors */
- bool wldrAutoStart; // if true, wldr can be set automatically
- // by default this value is set to true.
- // if wldr is activated using a command (config
- // file/hicnLightControl) this value is set to false so
- // that a base station can not disable wldr at the client
- Wldr *wldr;
+static inline
+unsigned
+connection_get_id(const connection_t * connection)
+{
+ return connection->id;
+}
-#ifdef WITH_POLICY
- policy_tags_t tags;
-#endif /* WITH_POLICY */
+static inline
+char *
+connection_get_name(const connection_t * connection)
+{
+ return connection->name;
+}
-};
+static inline
+face_type_t
+connection_get_type(const connection_t * connection)
+{
+ return connection->type;
+}
-Connection *connection_Create(IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- Connection *conn = parcMemory_AllocateAndClear(sizeof(Connection));
- parcAssertNotNull(conn, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(Connection));
- conn->addressPair = ioOperations_GetAddressPair(ops);
- conn->ops = ops;
- conn->refCount = 1;
- conn->wldr = NULL;
+static inline
+address_pair_t *
+connection_get_pair(const connection_t * connection)
+{
+ return connection->pair;
+}
- conn->wldrAutoStart = true;
- conn->counter = 0;
+static inline
+bool
+connection_is_up(const connection_t * connection)
+{
+ return connection->up;
+}
- /* By default, a connection will aim at the UP state */
- connection_SetAdminState(conn, CONNECTION_STATE_UP);
+static inline
+bool
+connection_is_local(const connection_t * connection)
+{
+ return connection->local;
+}
-#ifdef WITH_POLICY
- conn->tags = POLICY_TAGS_EMPTY;
-#endif /* WITH_POLICY */
+static inline
+face_state_t
+connection_get_state(const connection_t * connection)
+{
+ return connection->state;
+}
- return conn;
+static inline
+void
+connection_set_state(connection_t * connection, face_state_t state)
+{
+ connection->state = state;
}
-Connection *connection_Acquire(Connection *connection) {
- parcAssertNotNull(connection, "Parameter conn must be non-null");
- connection->refCount++;
- return connection;
+static inline
+face_state_t
+connection_get_admin_state(const connection_t * connection)
+{
+ return connection->admin_state;
}
-void connection_Release(Connection **connectionPtr) {
- parcAssertNotNull(connectionPtr, "Parameter must be non-null double pointer");
- parcAssertNotNull(*connectionPtr,
- "Parameter must dereference to non-null pointer");
- Connection *conn = *connectionPtr;
+static inline
+void
+connection_set_admin_state(connection_t * connection, face_state_t state)
+{
+ connection->admin_state = state;
+}
- parcAssertTrue(
- conn->refCount > 0,
- "Invalid state, connection reference count should be positive, got 0.");
- conn->refCount--;
- if (conn->refCount == 0) {
- // don't destroy addressPair, its part of ops.
- ioOperations_Release(&conn->ops);
- if (conn->wldr != NULL) {
- wldr_Destroy(&(conn->wldr));
- }
- parcMemory_Deallocate((void **)&conn);
- }
- *connectionPtr = NULL;
+static inline
+const char *
+connection_get_interface_name(const connection_t * connection)
+{
+ return connection->interface_name;
}
-bool connection_Send(const Connection *conn, Message *message) {
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
+#ifdef WITH_POLICY
- if (ioOperations_IsUp(conn->ops)) {
- if (message_GetType(message) == MessagePacketType_ContentObject) {
- uint8_t connectionId = (uint8_t)connection_GetConnectionId(conn);
- message_UpdatePathLabel(message, connectionId);
- }
- if (conn->wldr != NULL) {
- wldr_SetLabel(conn->wldr, message);
- } else {
- message_ResetWldrLabel(message);
- }
- return ioOperations_Send(conn->ops, NULL, message);
- }
- return false;
+static inline
+uint32_t
+connection_get_priority(const connection_t * connection)
+{
+ connection->priority = priority;
}
-bool connection_SendIOVBuffer(const Connection *conn, struct iovec *msg,
- size_t size) {
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- parcAssertNotNull(msg, "Parameter message must be non-null");
-
- return ioOperations_SendIOVBuffer(conn->ops, msg, size);
+static inline
+void
+connection_set_priority(connection_t * connection, uint32_t priority)
+{
+ connection->priority = priority;
}
-bool connection_SendBuffer(const Connection *conn, u8 * buffer, size_t length)
+static inline
+policy_tags_t
+connection_get_tags(const connection_t * connection)
{
- struct iovec iov[1];
- iov[0].iov_base = buffer;
- iov[0].iov_len = length;
- return connection_SendIOVBuffer(conn, iov, 1);
+ return connection->tags;
}
-void connection_Probe(Connection *conn, uint8_t * probe) {
- ioOperations_SendProbe(conn->ops, probe);
+static inline
+void
+connection_set_tags(connection_t * connection, policy_tags_t tags)
+{
+ connection->tags = tags;
}
-void connection_HandleProbe(Connection *conn, uint8_t *probe){
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- parcAssertNotNull(probe, "Parameter pkt must be non-null");
+#endif /* WITH_POLICY */
- if(messageHandler_IsInterest(probe)){
- messageHandler_CreateProbeReply(probe, HF_INET6_TCP);
- ioOperations_SendProbe(conn->ops, probe);
- }
-}
+/* API */
-IoOperations *connection_GetIoOperations(const Connection *conn) {
- return conn->ops;
-}
+#endif
-unsigned connection_GetConnectionId(const Connection *conn) {
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- return ioOperations_GetConnectionId(conn->ops);
-}
+connection_t *
+connection_create_on_listener(const listener_t * listener, const char * name,
+ const address_pair_t * pair, forwarder_t * forwarder)
+{
+ const connection_table_t * table = forwarder_get_connection_table(forwarder);
-const AddressPair *connection_GetAddressPair(const Connection *conn) {
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- return ioOperations_GetAddressPair(conn->ops);
-}
+ connection_t * connection;
+ connection_table_allocate(table, connection, pair, name);
-bool connection_IsUp(const Connection *conn) {
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- if (!conn->ops) return false;
- return ioOperations_IsUp(conn->ops);
+ unsigned connection_id = connection_table_get_connection_id(table, connection);
+
+ const char * interface_name = listener_get_interface_name(listener);
+ // XXX This should not be there !
+ int fd = listener_get_socket(listener, address_pair_get_local(pair),
+ address_pair_get_remote(pair), NULL);
+ bool local = address_is_local(&pair->local);
+
+ if (connection_initialize(connection, listener->type, name, interface_name, fd, pair, local,
+ connection_id, forwarder) < 0) {
+ connection_table_deallocate(table, connection);
+ return NULL;
+ }
+
+ return connection;
}
-bool connection_IsLocal(const Connection *conn) {
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- return ioOperations_IsLocal(conn->ops);
+
+// This is called by configuration
+// XXX different wit create on listener : when listener receives a new
+// connection
+// !
+connection_t *
+connection_create(face_type_t type, const char * name,
+ const address_pair_t * pair, forwarder_t * forwarder)
+{
+ assert(face_type_is_valid(type));
+ assert(pair);
+ assert(forwarder);
+
+ listener_table_t * table = forwarder_get_listener_table(forwarder);
+ listener_t *listener = listener_table_get_by_address(table, type, &pair->local);
+ if (!listener) {
+ // XXX TODO
+ //char *str = addressToString(localAddress);
+ ERROR("Could not find listener to match address N/A");
+ //parcMemory_Deallocate((void **)&str);
+ return NULL;
+ }
+
+ return connection_create_on_listener(listener, name, pair, forwarder);
}
-const void *connection_Class(const Connection *conn) {
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- return ioOperations_Class(conn->ops);
+#if 0
+
+ const char * interface_name = listener->getInterfaceName(listener);
+ int fd = listener->getSocket(listener, pair);
+ bool is_local = address_is_local(&pair->local);
+
+
+ return udpConnection_Create(forwarder, interface_name, fd, pair, is_local, connid);
+
+ // alternatively
+ //
}
+#endif
-bool connection_ReSend(const Connection *conn, Message *message,
- bool notification) {
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
- bool res = false;
+/**
+ * @brief Initializes a connection
+ *
+ * @param [out] connection - Allocated connection buffer (eg. from pool) to be
+ * initialized.
+ * @param [in] forwarder - forwarder_t to which the connection is associated. This
+ * parameter needs to be non-NULL for connections receiving packets, such
+ * as TCP connections which are very close to UDP listeners, and unlike
+ * bound UDP connections).
+ * @return 0 if no error, -1 otherwise
+ */
+int
+connection_initialize(connection_t * connection, face_type_t type, const char * name,
+ const char * interface_name, int fd, const address_pair_t * pair,
+ bool local, unsigned connection_id, forwarder_t * forwarder)
+{
+ int rc;
+
+ assert(connection);
+ /* Interface name can be NULL eg always for TCP connnections */
+ assert(pair);
+ assert(address_pair_valid(pair));
+
+ *connection = (connection_t) {
+ .id = connection_id,
+ .name = strdup(name),
+ .type = type,
+ .interface_name = strdup(interface_name),
+ .pair = *pair,
+ .fd = fd,
+// .up = true,
+ .local = local,
+ // XXX UDP should start UP, TCP DOWN until remove side answer ?
+ .state = FACE_STATE_UNDEFINED,
+ .admin_state = FACE_STATE_UP,
+#ifdef WITH_POLICY
+ .priority = 0,
+#endif /* WITH_POLICY */
- if (connection_IsUp(conn)) {
- // here the wldr header is alreay set: this message is a retransmission or a
- // notification
+ .forwarder = forwarder,
+ .closed = false,
- // we need to recompiute the path lable since we always store a pointer to
- // the same message if this message will be sent again to someonelse, the
- // new path label must be computed starting from the orignal labelorignal
- // label. Notice that we heve the same problem in case of PIT aggregation.
- // That case is handled insied the MessageProcessor. This is specific to
- // WLDR retransmittions. This is done only for data packets
+ /* WLDR */
+ .wldr = NULL,
+ .wldr_autostart = true,
+ };
- if (message_GetType(message) == MessagePacketType_ContentObject) {
- uint8_t connectionId = (uint8_t)connection_GetConnectionId(conn);
- uint32_t old_path_label = message_GetPathLabel(message);
- message_UpdatePathLabel(message, connectionId);
+ connection->data = malloc(connection_vft[connection->type]->data_size);
+ if (!connection->data)
+ goto ERR_DATA;
- res = ioOperations_Send(conn->ops, NULL, message);
+ assert(connection_has_valid_type(connection));
- message_SetPathLabel(message, old_path_label);
- } else {
- res = ioOperations_Send(conn->ops, NULL, message);
+ rc = connection_vft[connection->type]->initialize(connection);
+ if (rc < 0) {
+ goto ERR_VFT;
}
- }
- if (notification) {
- // the notification is never destroyed
- message_Release(&message);
- }
+ // XXX uncertain as fd is created by the listener !!
+ // XXX check whether it is registered !
+#if 0
+ connection->fd = connection_vft[connection->type]->get_socket(connection, address, NULL, interface_name);
+ if (connection->fd < 0) {
+ ERROR("Error creating connection fd: (%d) %s", errno, strerror(errno));
+ goto ERR_FD;
+ }
+
+ // XXX data should be pre-allocated here
+
+ if (loop_register_fd(MAIN_LOOP, connection->fd, connection,
+ connection_vft[connection->type]->read_callback, NULL) < 0)
+ goto ERR_REGISTER_FD;
+#endif
+
+ // XXX TODO
+ //char *str = pair_ToString(udp->pair);
+ DEBUG("%s connection %p created for address %s (local=%s)",
+ face_type_str(connection->type), connection, "N/A",
+ connection_is_local(connection) ? "true" : "false");
+ //free(str);
+ //
+ return 0;
+
+#if 0
+ERR_REGISTER_FD:
+#ifndef _WIN32
+ close(connection->fd);
+#else
+ closesocket(connection->fd);
+#endif
+ERR_FD:
+#endif
+ERR_VFT:
+ free(connection->data);
+ERR_DATA:
+ free(connection->interface_name);
+ free(connection->name);
+ return -1;
+}
+
+int
+connection_finalize(connection_t * connection)
+{
+ assert(connection);
- return res;
+ if (connection->wldr)
+ wldr_free(connection->wldr);
+
+ connection_vft[connection->type]->finalize(connection);
+
+ free(connection->interface_name);
+ free(connection);
+
+ DEBUG("%s connection %p destroyed", face_type_str(connection->type),
+ connection);
+
+ return 0;
}
-void connection_AllowWldrAutoStart(Connection *conn, bool allow) {
- conn->wldrAutoStart = allow;
+#if 0
+// XXX put in common the validation and processing of commands with UDP and hICN
+// listeners !
+command_type_t
+_isACommand(PARCEventBuffer *input)
+{
+ size_t bytesAvailable = parcEventBuffer_GetLength(input);
+ parcAssertTrue(bytesAvailable >= sizeof(header_control_message),
+ "Called with too short an input: %zu", bytesAvailable);
+
+ uint8_t *msg = parcEventBuffer_Pullup(input, bytesAvailable);
+
+ message_type_t message_type = message_type_from_uchar(msg[0]);
+ //if (!message_type_is_valid(message_type))
+ if (message_type != REQUEST_LIGHT)
+ return COMMAND_TYPE_N;
+
+ return command_type_from_uchar(msg[1]);
}
-void connection_EnableWldr(Connection *conn) {
- if (!connection_IsLocal(conn)) {
- if (conn->wldr == NULL) {
- printf("----------------- enable wldr\n");
- conn->wldr = wldr_Init();
+// XXX new function to process all incoming bytes
+// result : consumed, discard/invalid, wait for more
+// PRE: buffer has at least 8 bytes (to get the length of all packets)
+// This function is only used to make decisions
+/**
+ * \return the number of consumed bytes, or a negative value in case of error
+ */
+// XXX mutualize with listener_process_buffer
+size_t
+connection_process_buffer(connection_t * connection, const uint8_t * buffer, size_t size)
+{
+ size_t expected;
+
+ /* Too small a packet is not useful to decide between a control message and
+ * an hICN packet, the size of a control message is enough to test for both
+ * pakcet types */
+ if (size < sizeof(header_control_message))
+ return 0;
+
+ /* We expect complete packets most of the time, so don't bother with state */
+ message_type_t message_type = message_type_from_uchar(msg[0]);
+ if (message_type == REQUEST_LIGHT) {
+ command_type_t command_type = command_type_from_uchar(msg[1]);
+ if (!command_type_is_valid(command_type))
+ break;
+ expected = sizeof(header_control_message) +
+ command_get_payload_len(command_type);
+ if (size < expected)
+ return 0;
+ forwarder_receive_command(connection->forwarder, command_type, packet,
+ connection->id);
+ return expected;
+ }
+
+ if (!messageHandler_IsValidHicnPacket(packet)) {
+ WARN("Connection #%u: Malformed packet received",
+ connection_get_id(connection));
+ return -1;
}
- }
-}
-void connection_DisableWldr(Connection *conn) {
- if (!connection_IsLocal(conn)) {
- if (conn->wldr != NULL) {
- printf("----------------- disable wldr\n");
- wldr_Destroy(&(conn->wldr));
- conn->wldr = NULL;
+ /* Check that we have a full packet */
+ expected = messageHandler_GetTotalPacketLength(packet),
+ if (size < expected)
+ return 0;
+
+ msgbuf_t msgbuf;
+ MessagePacketType packet_type;
+ if (messageHandler_IsInterest(message->messageHead)) {
+ packet_type = MESSAGE_TYPE_INTEREST;
+ } else if (messageHandler_IsData(message->messageHead)) {
+ packet_type = MESSAGE_TYPE_DATA;
+ } else {
+ ERROR("Dropped packet that is not interest nor data");
+ return -1;
}
- }
-}
-bool connection_HasWldr(const Connection *conn) {
- if (conn->wldr == NULL) {
- return false;
- } else {
- return true;
- }
-}
+ // this is an Hicn packet (here we should distinguish between IPv4 and
+ // IPv6 tryReadMessage may set nextMessageLength
+ msgbuf_from_packet(&msgbuf, packet, expected, packet_type,
+ connection_get_id(connection), ticks_now());
+ forwarder_receive(connection->forwarder, &msgbuf, 1);
-bool connection_WldrAutoStartAllowed(const Connection *conn) {
- return conn->wldrAutoStart;
+ return size;
}
-void connection_DetectLosses(Connection *conn, Message *message) {
- if (conn->wldr != NULL) wldr_DetectLosses(conn->wldr, conn, message);
-}
+int
+connection_read_message(connection_t * connection, msgbuf_t * msgbuf)
+{
+ assert(connection);
+ assert(face_type_is_valid(connection->type));
+ assert(msgbuf);
-void connection_HandleWldrNotification(Connection *conn, Message *message) {
- if (conn->wldr != NULL)
- wldr_HandleWldrNotification(conn->wldr, conn, message);
+ return connection_vft[connection->type]->read_message(connection, msgbuf);
}
-connection_state_t connection_GetState(const Connection *conn)
+uint8_t *
+connection_read_packet(connection_t * connection)
{
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- if (!conn->ops)
- return CONNECTION_STATE_UNDEFINED;
- return ioOperations_GetState(conn->ops);
+ assert(connection);
+ assert(face_type_is_valid(connection->type));
+
+ return connection_vft[connection->type]->read_packet(connection);
}
+#endif
-void connection_SetState(Connection *conn, connection_state_t state)
+int
+connection_send_packet(const connection_t * connection, const uint8_t * packet,
+ size_t size)
{
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- if (!conn->ops)
- return;
- ioOperations_SetState(conn->ops, state);
+ assert(connection);
+ assert(face_type_is_valid(connection->type));
+ assert(packet);
+
+ return connection_vft[connection->type]->send_packet(connection, packet, size);
}
-connection_state_t connection_GetAdminState(const Connection *conn)
+// ALL DEPRECATED CODE HERE TO BE UPDATED
+
+// XXX nexthops null ?? to be removed ???
+bool
+_connection_send(const connection_t * connection, msgbuf_t * msgbuf, bool queue)
{
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- if (!conn->ops)
- return CONNECTION_STATE_UNDEFINED;
- return ioOperations_GetAdminState(conn->ops);
+ return connection_vft[connection->type]->send(connection, msgbuf, queue);
}
-void connection_SetAdminState(Connection *conn, connection_state_t admin_state)
+bool
+connection_send(const connection_t * connection, msgbuf_t * msgbuf, bool queue)
{
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- if (!conn->ops)
- return;
- if ((admin_state != CONNECTION_STATE_UP) && (admin_state != CONNECTION_STATE_DOWN))
- return;
- ioOperations_SetAdminState(conn->ops, admin_state);
+ assert(connection);
+
+ /* NULL message means flush */
+ if (!msgbuf)
+ return _connection_send(connection, NULL, false);
+
+ if (!connection_is_up(connection))
+ return false;
+
+ if (msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA) {
+ uint8_t conn_id = (uint8_t)connection_get_id(connection);
+ msgbuf_update_pathlabel(msgbuf, conn_id);
+ }
+
+ if (connection->wldr)
+ wldr_set_label(connection->wldr, msgbuf);
+ else
+ msgbuf_reset_wldr_label(msgbuf);
+
+ return _connection_send(connection, msgbuf, queue);
}
-#ifdef WITH_POLICY
-uint32_t connection_GetPriority(const Connection *conn)
+/*
+ * here the wldr header is alreay set: this message is a retransmission or a
+ * notification
+ *
+ * we need to recompute the path label since we always store a pointer to
+ * the same message if this message will be sent again to someone else, the
+ * new path label must be computed starting from the orignal label. Note
+ * that we heve the same problem in case of PIT aggregation. That case is
+ * handled inside the MessageProcessor. This is specific to WLDR
+ * retransmittions. This is done only for data packets
+ */
+bool
+connection_resend(const connection_t * connection, msgbuf_t * msgbuf, bool
+ notification)
{
- parcAssertNotNull(conn, "Parameter conn must be non-null");
- if (!conn->ops)
- return 0;
- return ioOperations_GetPriority(conn->ops);
+ assert(connection);
+ assert(msgbuf);
+
+ bool ret = false;
+
+ if (!connection_is_up(connection))
+ return ret;
+
+ if (msgbuf_get_type(msgbuf) == MESSAGE_TYPE_DATA) {
+ uint8_t conn_id = (uint8_t)connection_get_id(connection);
+ uint32_t old_path_label = msgbuf_get_pathlabel(msgbuf);
+ msgbuf_update_pathlabel(msgbuf, conn_id);
+ ret = _connection_send(connection, msgbuf, false); /* no queueing */
+ msgbuf_set_pathlabel(msgbuf, old_path_label);
+ } else {
+ ret = _connection_send(connection, msgbuf, false); /* no queueing */
+ }
+
+ return ret;
}
-void connection_SetPriority(Connection *conn, uint32_t priority)
-{
+#if 0
+bool connection_sendv(const connection_t * conn, struct iovec *msg,
+ size_t size) {
parcAssertNotNull(conn, "Parameter conn must be non-null");
- if (!conn->ops)
- return;
- ioOperations_SetPriority(conn->ops, priority);
+ parcAssertNotNull(msg, "Parameter message must be non-null");
+
+ return ioOperations_SendIOVBuffer(conn->ops, msg, size);
}
-#endif /* WITH_POLICY */
-const char * connection_GetInterfaceName(const Connection * conn)
-{
+void connection_probe(connection_t * conn, uint8_t * probe) {
+ ioOperations_SendProbe(conn->ops, probe);
+}
+
+void connection_hangle_probe(connection_t * conn, uint8_t *probe){
parcAssertNotNull(conn, "Parameter conn must be non-null");
- if (!conn->ops)
- return NULL;
- return ioOperations_GetInterfaceName(conn->ops);
+ parcAssertNotNull(probe, "Parameter pkt must be non-null");
+
+ if(messageHandler_IsInterest(probe)){
+ messageHandler_CreateProbeReply(probe, HF_INET6_TCP);
+ ioOperations_SendProbe(conn->ops, probe);
+ }
}
+#endif
-#ifdef WITH_POLICY
-void connection_AddTag(Connection *conn, policy_tag_t tag)
+/* WLDR */
+
+void
+connection_wldr_allow_autostart(connection_t * connection, bool value)
{
- policy_tags_add(&conn->tags, tag);
+ connection->wldr_autostart = value;
}
-void connection_RemoveTag(Connection *conn, policy_tag_t tag)
+bool
+connection_wldr_autostart_is_allowed(connection_t * connection)
{
- policy_tags_remove(&conn->tags, tag);
+ return connection->wldr_autostart;
}
-policy_tags_t connection_GetTags(const Connection *conn)
+void
+connection_wldr_enable(connection_t * connection, bool value)
{
- return conn->tags;
+ if (connection_is_local(connection))
+ return;
+ if (value) {
+ if (connection->wldr)
+ return;
+ connection->wldr = wldr_create();
+ } else {
+ if (!connection->wldr)
+ return;
+ wldr_free(connection->wldr);
+ }
}
-void connection_SetTags(Connection *conn, policy_tags_t tags)
+bool
+connection_has_wldr(const connection_t * connection)
{
- conn->tags = tags;
+ return !!connection->wldr;
}
-void connection_ClearTags(Connection *conn)
+void
+connection_wldr_detect_losses(const connection_t * connection, msgbuf_t * msgbuf)
{
- conn->tags = POLICY_TAGS_EMPTY;
+ if (!connection->wldr)
+ return;
+ wldr_detect_losses(connection->wldr, connection, msgbuf);
}
-int connection_HasTag(const Connection *conn, policy_tag_t tag)
+void
+connection_wldr_handle_notification(const connection_t * connection, msgbuf_t * msgbuf)
{
- return policy_tags_has(conn->tags, tag);
+ if (!connection->wldr)
+ return;
+ wldr_handle_notification(connection->wldr, connection, msgbuf);
}
-
-#endif /* WITH_POLICY */