aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/io
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-light/src/hicn/io')
-rw-r--r--hicn-light/src/hicn/io/CMakeLists.txt41
-rw-r--r--hicn-light/src/hicn/io/addressPair.c129
-rw-r--r--hicn-light/src/hicn/io/addressPair.h128
-rw-r--r--hicn-light/src/hicn/io/hicn.c522
-rw-r--r--hicn-light/src/hicn/io/hicnConnection.c541
-rw-r--r--hicn-light/src/hicn/io/hicnConnection.h53
-rw-r--r--hicn-light/src/hicn/io/hicnListener.c669
-rw-r--r--hicn-light/src/hicn/io/hicnListener.h42
-rw-r--r--hicn-light/src/hicn/io/hicnTunnel.c106
-rw-r--r--hicn-light/src/hicn/io/hicnTunnel.h65
-rw-r--r--hicn-light/src/hicn/io/ioOperations.c100
-rw-r--r--hicn-light/src/hicn/io/ioOperations.h449
-rw-r--r--hicn-light/src/hicn/io/listener.h128
-rw-r--r--hicn-light/src/hicn/io/listenerSet.c182
-rw-r--r--hicn-light/src/hicn/io/listenerSet.h188
-rw-r--r--hicn-light/src/hicn/io/streamConnection.c773
-rw-r--r--hicn-light/src/hicn/io/streamConnection.h76
-rw-r--r--hicn-light/src/hicn/io/tcp.c563
-rw-r--r--hicn-light/src/hicn/io/tcpListener.c262
-rw-r--r--hicn-light/src/hicn/io/tcpListener.h40
-rw-r--r--hicn-light/src/hicn/io/tcpTunnel.c43
-rw-r--r--hicn-light/src/hicn/io/tcpTunnel.h42
-rw-r--r--hicn-light/src/hicn/io/udp.c483
-rw-r--r--hicn-light/src/hicn/io/udpConnection.c495
-rw-r--r--hicn-light/src/hicn/io/udpConnection.h53
-rw-r--r--hicn-light/src/hicn/io/udpListener.c649
-rw-r--r--hicn-light/src/hicn/io/udpListener.h35
-rw-r--r--hicn-light/src/hicn/io/udpTunnel.c105
-rw-r--r--hicn-light/src/hicn/io/udpTunnel.h42
29 files changed, 1579 insertions, 5425 deletions
diff --git a/hicn-light/src/hicn/io/CMakeLists.txt b/hicn-light/src/hicn/io/CMakeLists.txt
index eb69485a5..d7e6977d6 100644
--- a/hicn-light/src/hicn/io/CMakeLists.txt
+++ b/hicn-light/src/hicn/io/CMakeLists.txt
@@ -14,40 +14,21 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
list(APPEND HEADER_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/addressPair.h
- ${CMAKE_CURRENT_SOURCE_DIR}/ioOperations.h
- ${CMAKE_CURRENT_SOURCE_DIR}/listener.h
- ${CMAKE_CURRENT_SOURCE_DIR}/listenerSet.h
- ${CMAKE_CURRENT_SOURCE_DIR}/tcpListener.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicnListener.h
- ${CMAKE_CURRENT_SOURCE_DIR}/udpTunnel.h
- ${CMAKE_CURRENT_SOURCE_DIR}/tcpTunnel.h
- ${CMAKE_CURRENT_SOURCE_DIR}/udpConnection.h
- ${CMAKE_CURRENT_SOURCE_DIR}/udpListener.h
- ${CMAKE_CURRENT_SOURCE_DIR}/streamConnection.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicnTunnel.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicnConnection.h
)
list(APPEND SOURCE_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/addressPair.c
- ${CMAKE_CURRENT_SOURCE_DIR}/ioOperations.c
- ${CMAKE_CURRENT_SOURCE_DIR}/listenerSet.c
- ${CMAKE_CURRENT_SOURCE_DIR}/streamConnection.c
- ${CMAKE_CURRENT_SOURCE_DIR}/tcpListener.c
- ${CMAKE_CURRENT_SOURCE_DIR}/tcpTunnel.c
- ${CMAKE_CURRENT_SOURCE_DIR}/udpConnection.c
- ${CMAKE_CURRENT_SOURCE_DIR}/udpListener.c
- ${CMAKE_CURRENT_SOURCE_DIR}/udpTunnel.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/tcp.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp.c
)
-if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
- list(APPEND SOURCE_FILES
- io/hicnTunnel.c
- io/hicnConnection.c
- io/hicnListener.c
- )
-endif()
+#if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+# list(APPEND SOURCE_FILES
+# io/hicnTunnel.c
+# io/hicnConnection.c
+# io/hicnListener.c
+# )
+#endif()
set(TO_INSTALL_HEADER_FILES
${TO_INSTALL_HEADER_FILES}
@@ -56,4 +37,4 @@ set(TO_INSTALL_HEADER_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/io/addressPair.c b/hicn-light/src/hicn/io/addressPair.c
deleted file mode 100644
index f9451f900..000000000
--- a/hicn-light/src/hicn/io/addressPair.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <hicn/hicn-light/config.h>
-#include <stdio.h>
-
-#include <parc/algol/parc_Hash.h>
-#include <parc/algol/parc_Memory.h>
-#include <parc/algol/parc_Object.h>
-#include <parc/assert/parc_Assert.h>
-#include <hicn/io/addressPair.h>
-
-struct address_pair {
- Address *local;
- Address *remote;
-};
-
-static void _addressPair_Destroy(AddressPair **addressPairPtr) {
- AddressPair *pair = *addressPairPtr;
-
- addressDestroy(&pair->local);
- addressDestroy(&pair->remote);
-}
-
-parcObject_ExtendPARCObject(AddressPair, _addressPair_Destroy, NULL,
- addressPair_ToString, addressPair_Equals, NULL,
- addressPair_HashCode, NULL);
-
-parcObject_ImplementAcquire(addressPair, AddressPair);
-
-parcObject_ImplementRelease(addressPair, AddressPair);
-
-AddressPair *addressPair_Create(const Address *local, const Address *remote) {
- parcAssertNotNull(local, "Parameter local must be non-null");
- parcAssertNotNull(remote, "Parameter remote must be non-null");
-
- AddressPair *pair = parcObject_CreateInstance(AddressPair);
- parcAssertNotNull(pair, "Got null from parcObject_Create()");
-
- pair->local = addressCopy(local);
- pair->remote = addressCopy(remote);
-
- return pair;
-}
-
-bool addressPair_Equals(const AddressPair *a, const AddressPair *b) {
- if (a == b) {
- return true;
- }
- if (a == NULL || b == NULL) {
- return false;
- }
-
- if (addressEquals(a->local, b->local)) {
- if (addressEquals(a->remote, b->remote)) {
- return true;
- }
- }
-
- return false;
-}
-
-bool addressPair_EqualsAddresses(const AddressPair *a, const Address *local,
- const Address *remote) {
- if (a == NULL || local == NULL || remote == NULL) {
- return false;
- }
-
- if (addressEquals(a->local, local)) {
- if (addressEquals(a->remote, remote)) {
- return true;
- }
- }
-
- return false;
-}
-
-char *addressPair_ToString(const AddressPair *pair) {
- parcAssertNotNull(pair, "Parameter pair must be non-null");
-
- char *local = addressToString(pair->local);
- char *remote = addressToString(pair->remote);
-
- char *output;
- int failure = asprintf(&output, "{ .local=%s, .remote=%s }", local, remote);
- parcAssertTrue(failure > -1, "Error on asprintf");
-
- parcMemory_Deallocate((void **)&local);
- parcMemory_Deallocate((void **)&remote);
-
- return output;
-}
-
-const Address *addressPair_GetLocal(const AddressPair *pair) {
- parcAssertNotNull(pair, "Parameter pair must be non-null");
- return pair->local;
-}
-
-const Address *addressPair_GetRemote(const AddressPair *pair) {
- parcAssertNotNull(pair, "Parameter pair must be non-null");
- return pair->remote;
-}
-
-/**
- * @function addressPair_HashCode
- * @abstract Hash useful for tables. Consistent with Equals.
- * @discussion
- * Returns a non-cryptographic hash that is consistent with equals. That is,
- * if a == b, then hash(a) == hash(b).
- *
- */
-PARCHashCode addressPair_HashCode(const AddressPair *pair) {
- PARCHashCode hashpair[2];
- hashpair[0] = addressHashCode(pair->local);
- hashpair[1] = addressHashCode(pair->remote);
- return parcHashCode_Hash((const uint8_t *)hashpair, sizeof(hashpair));
-}
diff --git a/hicn-light/src/hicn/io/addressPair.h b/hicn-light/src/hicn/io/addressPair.h
deleted file mode 100644
index f1b72e0dc..000000000
--- a/hicn-light/src/hicn/io/addressPair.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Used to identify a connection between a specific local address and
- * a specific remote address.
- */
-
-#ifndef address_Pair_h
-#define address_Pair_h
-
-#include <hicn/utils/address.h>
-
-struct address_pair;
-typedef struct address_pair AddressPair;
-
-/**
- * @function addressPair_Create
- * @abstract Creates and address pair. There is no restriction on the address
- * types.
- * @discussion
- * Creates an ordered pair of addresses, where the first is considered the
- * "local" address and the second is the "remote" address. Those designations
- * are purely a convention used to name them, and does not imply any specifici
- * types of operations.
- *
- * The two addresses may be of any address types (e.g. IPv4, IPv6, Local,
- * Ethernet). However, some functions that use an AddressPair may require that
- * the local and remote addresses be the same type.
- *
- */
-AddressPair *addressPair_Create(const Address *local, const Address *remote);
-
-/**
- * Returns a reference counted copy of the address pair
- *
- * Increments the reference count and returns the same address pair
- *
- * @param [in] addressPair An allocated address pair
- *
- * @retval non-null A reference counted copy
- * @retval null An error
- */
-AddressPair *addressPair_Acquire(const AddressPair *addressPair);
-
-/**
- * Releases a reference count to the object
- *
- * Decrements the reference count and destroys the object when it reaches 0.
- */
-void addressPair_Release(AddressPair **pairPtr);
-
-/**
- * Determine if two AddressPair instances are equal.
- *
- * Two AddressPair instances are equal if, and only if, the local and remote
- * addresses are identical. Equality is determined by addressEquals(a->local,
- * b->local) and Adress_Equals(a->remote, b->remote).
- *
- * The following equivalence relations on non-null `AddressPair` instances are
- * maintained:
- *
- * * It is reflexive: for any non-null reference value x,
- * `AddressPair_Equals(x, x)` must return true.
- *
- * * It is symmetric: for any non-null reference values x and y,
- * `addressPair_Equals(x, y)` must return true if and only if
- * `addressPair_Equals(y, x)` returns true.
- *
- * * It is transitive: for any non-null reference values x, y, and z, if
- * `addressPair_Equals(x, y)` returns true and
- * `addressPair_Equals(y, z)` returns true,
- * then `addressPair_Equals(x, z)` must return true.
- *
- * * It is consistent: for any non-null reference values x and y, multiple
- * invocations of `addressPair_Equals(x, y)` consistently return true or
- * consistently return false.
- *
- * * For any non-null reference value x, `addressPair_Equals(x, NULL)` must
- * return false.
- *
- * @param a A pointer to a `AddressPair` instance.
- * @param b A pointer to a `AddressPair` instance.
- * @return true if the two `AddressPair` instances are equal.
- */
-bool addressPair_Equals(const AddressPair *a, const AddressPair *b);
-
-/**
- * @function addressPair_EqualsAddresses
- * @abstract As AddressEquals, but "b" is broken out
- * @discussion
- * Equality is determined by addressEquals(a->local, local) and
- * Adress_Equals(a->remote, remote).
- */
-bool addressPair_EqualsAddresses(const AddressPair *a, const Address *local,
- const Address *remote);
-
-const Address *addressPair_GetLocal(const AddressPair *pair);
-
-const Address *addressPair_GetRemote(const AddressPair *pair);
-
-/**
- * @function addressPair_HashCode
- * @abstract Hash useful for tables. Consistent with Equals.
- * @discussion
- * Returns a non-cryptographic hash that is consistent with equals. That is,
- * if a == b, then hash(a) == hash(b).
- */
-PARCHashCode addressPair_HashCode(const AddressPair *pair);
-
-/**
- * @function addressPair_ToString
- * @abstract Human readable string representation. Caller must use free(3).
- */
-char *addressPair_ToString(const AddressPair *pair);
-#endif // address_Pair_h
diff --git a/hicn-light/src/hicn/io/hicn.c b/hicn-light/src/hicn/io/hicn.c
new file mode 100644
index 000000000..a239dc781
--- /dev/null
+++ b/hicn-light/src/hicn/io/hicn.c
@@ -0,0 +1,522 @@
+/*
+ * 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 hicn.c
+ * @brief Implementation of hicn face
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <hicn/hicn-light/config.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <hicn/core/listener.h>
+#include <hicn/core/listener_vft.h>
+#include <hicn/core/connection.h>
+#include <hicn/core/connection_vft.h>
+#include <hicn/core/connection_table.h>
+#include <hicn/core/forwarder.h>
+#include <hicn/core/mapme.h>
+#include <hicn/core/messagePacketType.h>
+#include <hicn/socket/api.h>
+#include <hicn/util/log.h>
+
+#define IPv6 6
+#define IPv4 4
+#define MTU_SIZE 1500 // bytes
+#define MAX_HICN_RETRY 5
+#define DEFAULT_PORT 1234
+
+// XXX #if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(_WIN32) && defined(PUNTING)
+
+// XXX the socket helper should be moved here as we can have a single hicn
+// listener
+
+#if 0
+static
+const
+address_pair_t *
+_createRecvAddressPairFromPacket(const uint8_t *msgBuffer) {
+ address_t * packetSrcAddr = NULL; /* This one is in the packet */
+ address_t * localAddr = NULL; /* This one is to be determined */
+
+ if (messageHandler_GetIPPacketType(msgBuffer) == IPv6_TYPE) {
+ struct sockaddr_in6 addr_in6;
+ addr_in6.sin6_family = AF_INET6;
+ addr_in6.sin6_port = htons(DEFAULT_PORT);
+ addr_in6.sin6_flowinfo = 0;
+ addr_in6.sin6_scope_id = 0;
+ memcpy(&addr_in6.sin6_addr,
+ (struct in6_addr *)messageHandler_GetSource(msgBuffer), 16);
+ packetSrcAddr = addressCreateFromInet6(&addr_in6);
+
+ /* We now determine the local address used to reach the packet src address */
+#ifndef _WIN32
+ int sock = socket (AF_INET6, SOCK_DGRAM, 0);
+#else
+ int sock = (int)socket (AF_INET6, SOCK_DGRAM, 0);
+#endif /* _WIN32 */
+ if (sock < 0)
+ goto ERR;
+
+ struct sockaddr_in6 remote, local;
+ memset(&remote, 0, sizeof(remote));
+ remote.sin6_family = AF_INET6;
+ remote.sin6_addr = addr_in6.sin6_addr;
+ remote.sin6_port = htons(DEFAULT_PORT);
+
+ socklen_t locallen = sizeof(local);
+ if (connect(sock, (const struct sockaddr*)&remote, sizeof(remote)) == -1)
+ goto ERR;
+ if (getsockname(sock, (struct sockaddr*) &local, &locallen) == -1)
+ goto ERR;
+
+ local.sin6_port = htons(DEFAULT_PORT);
+ localAddr = addressCreateFromInet6(&local);
+
+ close(sock);
+
+ } else if (messageHandler_GetIPPacketType(msgBuffer) == IPv4_TYPE) {
+ struct sockaddr_in addr_in;
+ addr_in.sin_family = AF_INET;
+ addr_in.sin_port = htons(DEFAULT_PORT);
+ memcpy(&addr_in.sin_addr,
+ (struct in_addr *)messageHandler_GetSource(msgBuffer), 4);
+ packetSrcAddr = addressCreateFromInet(&addr_in);
+
+ /* We now determine the local address used to reach the packet src address */
+
+#ifndef _WIN32
+ int sock = socket (AF_INET, SOCK_DGRAM, 0);
+#else
+ int sock = (int)socket (AF_INET, SOCK_DGRAM, 0);
+#endif /* _WIN32 */
+ if (sock < 0) {
+ perror("Socket error");
+ goto ERR;
+ }
+
+ struct sockaddr_in remote, local;
+ memset(&remote, 0, sizeof(remote));
+ remote.sin_family = AF_INET;
+ remote.sin_addr = addr_in.sin_addr;
+ remote.sin_port = htons(DEFAULT_PORT);
+
+ socklen_t locallen = sizeof(local);
+ if (connect(sock, (const struct sockaddr*)&remote, sizeof(remote)) == -1)
+ goto ERR;
+ if (getsockname(sock, (struct sockaddr*) &local, &locallen) == -1)
+ goto ERR;
+
+ local.sin_port = htons(DEFAULT_PORT);
+ localAddr = addressCreateFromInet(&local);
+
+ close(sock);
+ }
+ /* As this is a receive pair, we swap src and dst */
+ return addressPair_Create(localAddr, packetSrcAddr);
+
+ERR:
+ perror("Socket error");
+ return NULL;
+}
+
+static
+bool _isEmptyAddressIPv6(address_t * address) {
+ struct sockaddr_in6 *addr6 =
+ parcMemory_AllocateAndClear(sizeof(struct sockaddr_in6));
+ parcAssertNotNull(addr6, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(addr6));
+
+ addressGetInet6(address, addr6);
+
+ bool res = true;
+ for (int i = 0; i < 16; ++i) {
+ if (addr6->sin6_addr.s6_addr[i] != 0) {
+ res = false;
+ }
+ }
+
+ parcMemory_Deallocate((void **)&addr6);
+
+ return res;
+}
+
+}
+
+static
+const Connection *
+_lookupConnection(ListenerOps * listener, const address_pair_t *pair)
+{
+ HicnListener * hicn = (HicnListener*)listener->context;
+ const connection_table_t * table = forwarder_GetConnectionTable(hicn->forwarder);
+ const address_t * packetSourceAddress = address_pair_local(pair);
+
+ if (hicn->connection_id != -1)
+ return connection_table_get_by_id(table, hicn->connection_id);
+
+ if (!packetSourceAddress)
+ return NULL;
+
+ // in this first check we try to retrieve the standard connection
+ // generated by the hicn-light
+ const address_pair_t new_pair = {
+ .local = hicn->localAddress,
+ .remote = *packetSourceAddress,
+ };
+ return *connection_table_lookup(table, &new_pair);
+}
+
+
+// XXX TODO : rely on libhicn
+int
+_createAddressFromPacket(const uint8_t *packet, address_t * address)
+{
+ if (messageHandler_GetIPPacketType(packet) == IPv6_TYPE) {
+ struct sockaddr_in6 * sin6 = address6(address);
+ *sin6 = (struct sockaddr_in6) {
+ .sin6_family = AF_INET6,
+ .sin6_port = htons(DEFAULT_PORT),
+ .sin6_flowinfo = 0,
+ .sin6_scope_id = 0,
+ };
+ memcpy(&sin6->sin6_addr,
+ (struct in6_addr *)messageHandler_GetSource(packet), 16);
+ return 0;
+ } else if (messageHandler_GetIPPacketType(packet) == IPv4_TYPE) {
+ struct sockaddr_in * sin = address4(address);
+ *sin = (struct sockaddr_in) {
+ .sin_family = AF_INET,
+ .sin_port = htons(DEFAULT_PORT),
+ };
+ memcpy(&sin->sin_addr,
+ (struct in_addr *)messageHandler_GetSource(packet), 4);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+#endif
+
+/******************************************************************************
+ * Listener
+ ******************************************************************************/
+
+typedef struct {
+ //address_t localAddress; // this is the local address or 0::0 in case of the
+ // main listener this is the address used inside
+ // forwarder to identify the listener. Notice that this
+ // address is the same as the fisical interfaces on
+ // which we create the TUN. it is NOT the TUN address
+ // which is given by libhicn after the bind operation
+ // However the user alway uses this address since is
+ // the only one available at configuration time
+
+ // XXX why do we need the id of the associated connection ?
+ int connection_id; // this is used only if the listener is used to receive
+ // data packets we assume that 1 connection is associated
+ // to one listener in this case so we set the
+ // connection_id we the connection is create. if this id
+ // is not set and a data packet is received, the packet is
+ // dropped
+
+ hicn_socket_t * hicn_socket;
+ hicn_socket_helper_t * hicn_socket_helper;
+
+} listener_hicn_data_t;
+
+static
+void
+listener_hicn_read_callback(listener_t * listener, int fd, void * data)
+{
+ assert(listener);
+ assert(!data); /* No user data */
+ uint8_t packet[MTU_SIZE];
+
+ int family = address_family(&listener->address);
+ if ((family != AF_INET) && (family != AF_INET6)) {
+ /*
+ * We need to discard the frame. Read 1 byte. This will clear it off
+ * the stack.
+ */
+ int nread = read(fd, packet, 1);
+
+ if (nread > 0) {
+ DEBUG("Discarded frame from fd %d", fd);
+ } else if (nread < 0) {
+ ERROR("Error trying to discard frame from fd %d: (%d) %s", fd, errno,
+ strerror(errno));
+ }
+ return;
+ }
+
+#if 0
+ if (!(what & PARCEventType_Read))
+ return;
+#endif
+
+ ssize_t n = read(fd, packet, MTU_SIZE);
+ if (n < 0) {
+ ERROR("read failed %d: (%d) %s", fd, errno, strerror(errno));
+ return;
+ }
+
+#if 0
+ address_t packet_addr;
+ if (_createAddressFromPacket(packet, &packet_addr) < 0)
+ return;
+
+ address_pair_t pair_find = {
+ .local = packet_addr,
+ .remote = /* dummy */ hicn->localAddress,
+ };
+ const Connection *conn = _lookupConnection(listener, &pair_find);
+ if (!conn) {
+ address_pair_t pair = {
+ .local = hicn->localAddress,
+ .remote = packet_addr,
+ };
+ connid = _createNewConnection(listener, fd, &pair);
+ } else {
+ connid = connection_GetConnectionId(conn);
+ }
+#endif
+
+ listener_read_callback(listener->forwarder, listener, fd, &listener->address, packet, n);
+}
+
+bool
+listener_hicn_bind(listener_t * listener, const address_t * address)
+{
+ assert(listener);
+ assert(address);
+
+ listener_hicn_data_t * data = listener->data;
+ assert(data);
+
+ char *address_str = malloc(/* max */ INET6_ADDRSTRLEN);
+ inet_ntop(address_family(address), address, address_str, /* max */ INET6_ADDRSTRLEN);
+ int rc = hicn_bind(data->hicn_socket_helper, listener->fd, address_str);
+ if (rc < 0) {
+ ERROR("hicn_bind failed %d %s", rc, hicn_socket_strerror(rc));
+ free(address_str);
+ return false;
+ }
+
+ free(address_str);
+ return true;
+}
+
+static
+int
+listener_hicn_initialize(listener_t * listener)
+{
+ assert(listener);
+
+ listener_hicn_data_t * data = listener->data;
+ assert(data);
+
+ /* This is the id of the connection associated to this listener (unique in
+ * the case of hICN */
+ data->connection_id = -1;
+
+ data->hicn_socket_helper = hicn_create();
+ if (!data->hicn_socket)
+ goto ERR_HELPER;
+
+ if (address_empty(&listener->address)) {
+ listener->fd = hicn_socket(data->hicn_socket_helper, listener->name, NULL);
+ } else {
+ char *local_addr = malloc(/* max */ INET6_ADDRSTRLEN);
+ inet_ntop(address_family(&listener->address), &listener->address,
+ local_addr, /* max */ INET6_ADDRSTRLEN);
+ listener->fd = hicn_socket(data->hicn_socket_helper, listener->name, local_addr);
+ free(local_addr);
+ }
+
+ if (listener->fd < 0) {
+ ERROR("HicnListener %s: error creating hICN listener", listener->name);
+ goto ERR_FD;
+ }
+
+ // Set non-blocking flag
+ int flags = fcntl(listener->fd, F_GETFL, NULL);
+ if (flags != -1) {
+ ERROR("fcntl failed to obtain file descriptor flags (%d)", errno);
+ goto ERR_FLAGS;
+ }
+
+ if (fcntl(listener->fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ ERROR("fcntl failed to set file descriptor flags (%d)", errno);
+ goto ERR_FLAGS;
+ }
+
+ return 0;
+
+ERR_FLAGS:
+ close(listener->fd);
+ERR_FD:
+ hicn_free(data->hicn_socket_helper);
+ERR_HELPER:
+ return -1;
+}
+
+static
+void
+listener_hicn_finalize(listener_t * listener)
+{
+ assert(listener);
+ assert(listener_get_type(listener) == FACE_TYPE_HICN);
+
+ listener_hicn_data_t * data = listener->data;
+ assert(data);
+
+ // TODO destroy hicn_socket
+ // TODO free(data) (like in other classes)
+
+ hicn_free(data->hicn_socket_helper);
+ // XXX
+ //hicn_socket_free(data->hicn_socket);
+
+ return;
+}
+
+static
+int
+listener_hicn_punt(const listener_t * listener, const char * prefix_s)
+{
+ assert(listener);
+ assert(listener_get_type(listener) == FACE_TYPE_HICN);
+ assert(prefix_s);
+
+ listener_hicn_data_t * data = listener->data;
+ assert(data);
+
+ int rc;
+ for (int retry = 0; retry < MAX_HICN_RETRY; retry++) {
+ if ((rc = hicn_listen(data->hicn_socket_helper, listener->fd, prefix_s)) >= 0)
+ return 0;
+ sleep(1);
+ }
+ ERROR("hicn_listen failed %d %s", rc, hicn_socket_strerror(rc));
+ return -1;
+}
+
+static
+int
+listener_hicn_get_socket(const listener_t * listener, const address_t * local,
+ const address_t * remote, const char * interface_name)
+{
+ assert(listener);
+ assert(listener_get_type(listener) == FACE_TYPE_HICN);
+ assert(pair);
+
+ /* ... */
+
+ return -1;
+
+}
+
+DECLARE_LISTENER(hicn);
+
+/******************************************************************************
+ * Connection
+ ******************************************************************************/
+
+typedef struct {
+ /* ... */
+} connection_hicn_data_t;
+
+static
+int
+connection_hicn_initialize(connection_t * connection)
+{
+
+ assert(connection);
+ assert(connection_get_type(connection) == FACE_TYPE_HICN);
+
+ /* ... */
+
+ return 0;
+}
+
+static
+void
+connection_hicn_finalize(connection_t * connection)
+{
+ /* ... */
+
+ return;
+}
+
+static
+int
+connection_hicn_send(const connection_t * connection, msgbuf_t * msgbuf,
+ bool queue)
+{
+ assert(connection);
+ /* msgbuf can be NULL */
+
+// connection_hicn_data_t * data = connection->data;
+// assert(data);
+
+ /* ... */
+
+ return true;
+}
+
+//static
+//int
+//connection_hicn_sendv(const connection_t * connection, struct iovec * iov,
+// size_t size)
+//{
+//
+// assert(connetion);
+// assert(iov);
+//
+//// connection_hicn_data_t * data = connection->data;
+//// assert(data);
+//
+// /* ... */
+//
+// return 0;
+//}
+//
+static
+int
+connection_hicn_send_packet(const connection_t * connection, const uint8_t * packet, size_t size)
+{
+ assert(ops);
+ assert(packet);
+
+ /* ... */
+
+ return 0;
+}
+
+static
+void
+connection_hicn_read_callback(connection_t * connection, int fd, void * data)
+{
+ ERROR("Unexpected read callback for hicn connection");
+ return;
+}
+
+DECLARE_CONNECTION(hicn);
diff --git a/hicn-light/src/hicn/io/hicnConnection.c b/hicn-light/src/hicn/io/hicnConnection.c
deleted file mode 100644
index 646cea990..000000000
--- a/hicn-light/src/hicn/io/hicnConnection.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Embodies the reader/writer for a Hicn connection
- *
- * NB The Send() function may overflow the output buffer
- *
- */
-
-#include <errno.h>
-#include <hicn/hicn-light/config.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#include <hicn/core/message.h>
-#include <hicn/io/hicnConnection.h>
-
-#include <hicn/core/messageHandler.h>
-
-#include <parc/algol/parc_Hash.h>
-#include <parc/algol/parc_Memory.h>
-#include <parc/assert/parc_Assert.h>
-#include <hicn/core/connection.h>
-#include <hicn/core/forwarder.h>
-
-typedef struct hicn_state {
- Forwarder *forwarder;
- char * interfaceName;
- Logger *logger;
-
- // the hicn listener socket we receive packets on
- int hicnListenerSocket;
-
- AddressPair *addressPair;
-
- // We need to access this all the time, so grab it out
- // of the addressPair;
- struct sockaddr *peerAddress;
- socklen_t peerAddressLength;
-
- struct sockaddr *localAddress;
- socklen_t localAddressLength;
-
- bool isLocal;
- bool isUp;
- 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;
-#ifdef WITH_POLICY
- uint32_t priority;
-#endif /* WITH_POLICY */
-} _HicnState;
-
-// Prototypes
-static bool _send(IoOperations *ops, const Address *nexthop, Message *message);
-static bool _sendIOVBuffer(IoOperations *ops, struct iovec *message,
- size_t size);
-static const Address *_getRemoteAddress(const IoOperations *ops);
-static const AddressPair *_getAddressPair(const IoOperations *ops);
-static unsigned _getConnectionId(const IoOperations *ops);
-static bool _isUp(const IoOperations *ops);
-static bool _isLocal(const IoOperations *ops);
-static void _destroy(IoOperations **opsPtr);
-static list_connections_type _getConnectionType(const IoOperations *ops);
-static void _sendProbe(IoOperations *ops, 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);
-#ifdef WITH_POLICY
-static uint32_t _getPriority(const IoOperations *ops);
-static void _setPriority(IoOperations *ops, uint32_t priority);
-#endif /* WITH_POLICY */
-static const char * _getInterfaceName(const IoOperations *ops);
-
-/*
- * This assigns a unique pointer to the void * which we use
- * as a GUID for this class.
- */
-static const void *_ioOperationsGuid = __FILE__;
-
-/*
- * Return our GUID
- */
-static const void *_streamConnection_Class(const IoOperations *ops) {
- return _ioOperationsGuid;
-}
-
-static IoOperations _template = {
- .closure = NULL,
- .send = &_send,
- .sendIOVBuffer = &_sendIOVBuffer,
- .getRemoteAddress = &_getRemoteAddress,
- .getAddressPair = &_getAddressPair,
- .getConnectionId = &_getConnectionId,
- .isUp = &_isUp,
- .isLocal = &_isLocal,
- .destroy = &_destroy,
- .class = &_streamConnection_Class,
- .getConnectionType = &_getConnectionType,
- .sendProbe = &_sendProbe,
- .getState = &_getState,
- .setState = &_setState,
- .getAdminState = &_getAdminState,
- .setAdminState = &_setAdminState,
-#ifdef WITH_POLICY
- .getPriority = &_getPriority,
- .setPriority = &_setPriority,
-#endif /* WITH_POLICY */
- .getInterfaceName = &_getInterfaceName,
-};
-
-// =================================================================
-
-static void _setConnectionState(_HicnState *Hicn, bool isUp);
-static bool _saveSockaddr(_HicnState *hicnConnState, const AddressPair *pair);
-
-IoOperations *hicnConnection_Create(Forwarder *forwarder, const char * interfaceName, int fd,
- const AddressPair *pair, bool isLocal) {
- IoOperations *io_ops = NULL;
-
- _HicnState *hicnConnState = parcMemory_AllocateAndClear(sizeof(_HicnState));
- parcAssertNotNull(hicnConnState,
- "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(_HicnState));
-
- hicnConnState->forwarder = forwarder;
- hicnConnState->interfaceName = strdup(interfaceName);
- hicnConnState->logger = logger_Acquire(forwarder_GetLogger(forwarder));
-
- bool saved = _saveSockaddr(hicnConnState, pair);
- if (saved) {
- hicnConnState->hicnListenerSocket = fd;
- hicnConnState->id = forwarder_GetNextConnectionId(forwarder);
- hicnConnState->addressPair = addressPair_Acquire(pair);
- hicnConnState->isLocal = isLocal;
-
- // allocate a connection
- io_ops = parcMemory_AllocateAndClear(sizeof(IoOperations));
- parcAssertNotNull(io_ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(IoOperations));
- memcpy(io_ops, &_template, sizeof(IoOperations));
- io_ops->closure = hicnConnState;
-
- _setConnectionState(hicnConnState, true);
-
-#ifdef WITH_POLICY
- hicnConnState->priority = 0;
-#endif /* WITH_POLICY */
-
- if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO,
- PARCLogLevel_Info)) {
- char *str = addressPair_ToString(hicnConnState->addressPair);
- logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Info,
- __func__,
- "HicnConnection %p created for address %s (isLocal %d)",
- (void *)hicnConnState, str, hicnConnState->isLocal);
- free(str);
- }
-
- messenger_Send(
- forwarder_GetMessenger(forwarder),
- missive_Create(MissiveType_ConnectionCreate, hicnConnState->id));
- messenger_Send(forwarder_GetMessenger(forwarder),
- missive_Create(MissiveType_ConnectionUp, hicnConnState->id));
- } else {
- // _saveSockaddr will already log an error, no need for extra log message
- // here
- logger_Release(&hicnConnState->logger);
- free(hicnConnState->interfaceName);
- parcMemory_Deallocate((void **)&hicnConnState);
- }
-
- return io_ops;
-}
-
-// =================================================================
-// I/O Operations implementation
-
-static void _destroy(IoOperations **opsPtr) {
- parcAssertNotNull(opsPtr, "Parameter opsPtr must be non-null double pointer");
- parcAssertNotNull(*opsPtr,
- "Parameter opsPtr must dereference to non-null pointer");
-
- IoOperations *ops = *opsPtr;
- parcAssertNotNull(ioOperations_GetClosure(ops),
- "ops->context must not be null");
-
- _HicnState *hicnConnState = (_HicnState *)ioOperations_GetClosure(ops);
- addressPair_Release(&hicnConnState->addressPair);
- parcMemory_Deallocate((void **)&(hicnConnState->peerAddress));
- parcMemory_Deallocate((void **)&(hicnConnState->localAddress));
-
- messenger_Send(
- forwarder_GetMessenger(hicnConnState->forwarder),
- missive_Create(MissiveType_ConnectionDestroyed, hicnConnState->id));
-
- if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO,
- PARCLogLevel_Info)) {
- logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Info,
- __func__, "HicnConnection %p destroyed", (void *)hicnConnState);
- }
-
- // do not close hicListenerSocket, the listener will close
- // that when its done
- // should I say something to libhicn?
-
- logger_Release(&hicnConnState->logger);
- free(hicnConnState->interfaceName);
- parcMemory_Deallocate((void **)&hicnConnState);
- parcMemory_Deallocate((void **)&ops);
-
- *opsPtr = NULL;
-}
-
-static bool _isUp(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _HicnState *hicnConnState =
- (const _HicnState *)ioOperations_GetClosure(ops);
- return hicnConnState->isUp;
-}
-
-static bool _isLocal(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _HicnState *hicnConnState =
- (const _HicnState *)ioOperations_GetClosure(ops);
- return hicnConnState->isLocal;
-}
-
-static const Address *_getRemoteAddress(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _HicnState *hicnConnState =
- (const _HicnState *)ioOperations_GetClosure(ops);
- return addressPair_GetRemote(hicnConnState->addressPair);
-}
-
-static const AddressPair *_getAddressPair(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _HicnState *hicnConnState =
- (const _HicnState *)ioOperations_GetClosure(ops);
- return hicnConnState->addressPair;
-}
-
-static unsigned _getConnectionId(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _HicnState *hicnConnState =
- (const _HicnState *)ioOperations_GetClosure(ops);
- return hicnConnState->id;
-}
-
-/**
- * @function hicnConnection_Send
- * @abstract Non-destructive send of the message.
- * @discussion
- * sends a message to the peer.
- *
- * @param dummy is ignored. .
- */
-static bool _send(IoOperations *ops, const Address *dummy, Message *message) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
- _HicnState *hicnConnState = (_HicnState *)ioOperations_GetClosure(ops);
-
- // NAT for HICN
- if (message_GetType(message) == MessagePacketType_ContentObject) {
- // this is a data packet. We need to put the remote address in the
- // destination field
-
- if (messageHandler_GetIPPacketType(message_FixedHeader(message)) ==
- IPv6_TYPE) {
- messageHandler_SetDestination_IPv6(
- (uint8_t *)message_FixedHeader(message),
- &((struct sockaddr_in6 *)hicnConnState->peerAddress)->sin6_addr);
- } else {
- messageHandler_SetDestination_IPv4(
- (uint8_t *)message_FixedHeader(message),
- &(((struct sockaddr_in *)hicnConnState->peerAddress)
- ->sin_addr.s_addr));
- }
- } else if (message_GetType(message) == MessagePacketType_Interest) {
- // this si an interest packet. We need to put the local address in the
- // source field
- if (messageHandler_GetIPPacketType(message_FixedHeader(message)) ==
- IPv6_TYPE) {
- messageHandler_SetSource_IPv6(
- (uint8_t *)message_FixedHeader(message),
- &((struct sockaddr_in6 *)hicnConnState->localAddress)->sin6_addr);
- } else {
- messageHandler_SetSource_IPv4(
- (uint8_t *)message_FixedHeader(message),
- &(((struct sockaddr_in *)hicnConnState->localAddress)
- ->sin_addr.s_addr));
- }
- } else if (message_GetType(message) == MessagePacketType_WldrNotification) {
- // here we don't need to do anything for now
- } else {
- // unkown packet
- if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Debug,
- __func__, "connid %u can't parse the message",
- hicnConnState->id);
- }
- return false;
- }
-
- ssize_t writeLength =
- write(hicnConnState->hicnListenerSocket, message_FixedHeader(message),
- message_Length(message));
-
- if (writeLength < 0) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- return false;
- } else {
- // this print is for debugging
- printf("Incorrect write length %zd, expected %zd: (%d) %s\n", writeLength,
- message_Length(message), errno, strerror(errno));
- return false;
- }
- }
-
- return true;
-}
-
-static bool _sendIOVBuffer(IoOperations *ops, struct iovec *message,
- size_t size) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
-
- _HicnState *hicnConnState = (_HicnState *)ioOperations_GetClosure(ops);
-
-
- ssize_t n = writev(hicnConnState->hicnListenerSocket, message, size);
- if (n < 0) {
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
- if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO,
- PARCLogLevel_Error)) {
- size_t length = 0;
- for (int i = 0; i < size; i++)
- length += message[i].iov_len;
- logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Error,
- __func__, "Incorrect write length %zd, expected %zd: (%d) %s\n",
- n, length, errno, strerror(errno));
- }
- }
- return false;
- }
- return true;
-}
-
-static list_connections_type _getConnectionType(const IoOperations *ops) {
- return CONN_HICN;
-}
-
-static void _sendProbe(IoOperations *ops, uint8_t *message) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
-
- _HicnState *hicnConnState = (_HicnState *)ioOperations_GetClosure(ops);
-
- if(messageHandler_IsInterest(message)){//
- // this is an interest packet. We need to put the local address in the
- // source field
- if (messageHandler_GetIPPacketType(message) == IPv6_TYPE) {
- messageHandler_SetSource_IPv6(message,
- &((struct sockaddr_in6 *)hicnConnState->localAddress)->sin6_addr);
- } else {
- messageHandler_SetSource_IPv4(message,
- &(((struct sockaddr_in *)hicnConnState->localAddress)
- ->sin_addr.s_addr));
- }
- }//if is a data packet the packet is already set (see
- //messageHandler_CreateProbeReply)
-
- ssize_t writeLength = write(hicnConnState->hicnListenerSocket, message,
- messageHandler_GetTotalPacketLength(message));
-
- if (writeLength < 0) {
- return;
- }
-}
-
-// =================================================================
-// Internal API
-
-static bool _saveSockaddr(_HicnState *hicnConnState, const AddressPair *pair) {
- bool success = false;
- const Address *remoteAddress = addressPair_GetRemote(pair);
- const Address *localAddress = addressPair_GetLocal(pair);
- switch (addressGetType(remoteAddress)) { // local must be of the same type
-
- case ADDR_INET: {
- size_t bytes = sizeof(struct sockaddr_in);
- hicnConnState->peerAddress = parcMemory_Allocate(bytes);
- parcAssertNotNull(hicnConnState->peerAddress,
- "parcMemory_Allocate(%zu) returned NULL", bytes);
-
- addressGetInet(remoteAddress,
- (struct sockaddr_in *)hicnConnState->peerAddress);
- hicnConnState->peerAddressLength = (socklen_t)bytes;
-
- hicnConnState->localAddress = parcMemory_Allocate(bytes);
- parcAssertNotNull(hicnConnState->localAddress,
- "parcMemory_Allocate(%zu) returned NULL", bytes);
-
- addressGetInet(localAddress,
- (struct sockaddr_in *)hicnConnState->localAddress);
- hicnConnState->localAddressLength = (socklen_t)bytes;
- success = true;
- break;
- }
-
- case ADDR_INET6: {
- size_t bytes = sizeof(struct sockaddr_in6);
- hicnConnState->peerAddress = parcMemory_Allocate(bytes);
- parcAssertNotNull(hicnConnState->peerAddress,
- "parcMemory_Allocate(%zu) returned NULL", bytes);
-
- addressGetInet6(remoteAddress,
- (struct sockaddr_in6 *)hicnConnState->peerAddress);
- hicnConnState->peerAddressLength = (socklen_t)bytes;
-
- hicnConnState->localAddress = parcMemory_Allocate(bytes);
- parcAssertNotNull(hicnConnState->localAddress,
- "parcMemory_Allocate(%zu) returned NULL", bytes);
-
- addressGetInet6(localAddress,
- (struct sockaddr_in6 *)hicnConnState->localAddress);
- hicnConnState->localAddressLength = (socklen_t)bytes;
- success = true;
- break;
- }
-
- default:
- if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO,
- PARCLogLevel_Error)) {
- char *str = addressToString(remoteAddress);
- logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Error,
- __func__, "Remote address is not INET or INET6: %s", str);
- parcMemory_Deallocate((void **)&str);
- }
- break;
- }
- return success;
-}
-
-static void _setConnectionState(_HicnState *hicnConnState, bool isUp) {
- parcAssertNotNull(hicnConnState, "Parameter HICN must be non-null");
-
- Messenger *messenger = forwarder_GetMessenger(hicnConnState->forwarder);
-
- bool oldStateIsUp = hicnConnState->isUp;
- hicnConnState->isUp = isUp;
-
- if (oldStateIsUp && !isUp) {
- // bring connection DOWN
- Missive *missive =
- missive_Create(MissiveType_ConnectionDown, hicnConnState->id);
- messenger_Send(messenger, missive);
- return;
- }
-
- if (!oldStateIsUp && isUp) {
- // bring connection UP
- Missive *missive =
- missive_Create(MissiveType_ConnectionUp, hicnConnState->id);
- messenger_Send(messenger, missive);
- 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;
-}
-
-#ifdef WITH_POLICY
-static uint32_t _getPriority(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _HicnState *hicnConnState =
- (const _HicnState *)ioOperations_GetClosure(ops);
- return hicnConnState->priority;
-}
-
-static void _setPriority(IoOperations *ops, uint32_t priority) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- _HicnState *hicnConnState =
- (_HicnState *)ioOperations_GetClosure(ops);
- hicnConnState->priority = priority;
-}
-#endif /* WITH_POLICY
-*/
-static const char * _getInterfaceName(const IoOperations *ops)
-{
- parcAssertNotNull(ops, "Parameter must be non-null");
- _HicnState *hicnConnState =
- (_HicnState *)ioOperations_GetClosure(ops);
- return hicnConnState->interfaceName;
-}
diff --git a/hicn-light/src/hicn/io/hicnConnection.h b/hicn-light/src/hicn/io/hicnConnection.h
deleted file mode 100644
index fec18e1bd..000000000
--- a/hicn-light/src/hicn/io/hicnConnection.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 hicnConnection.h
- * @brief Represents a Hicn connection for the connection table
- *
- * <#Detailed Description#>
- *
- */
-
-#ifndef hicnConnection_h
-#define hicnConnection_h
-
-#include <hicn/core/forwarder.h>
-#include <hicn/io/addressPair.h>
-#include <hicn/io/ioOperations.h>
-#include <hicn/utils/address.h>
-
-/**
- * Creates a Hicn connection that can send to the remote address
- *
- * The address pair must both be same type (i.e. INET or INET6).
- *
- * @param [in] an allocated hicn-light Forwarder (saves reference)
- * @param [in] fd The socket to use
- * @param [in] pair An allocated address pair for the connection (saves
- * reference)
- * @param [in] isLocal determines if the remote address is on the current system
- *
- * @retval non-null An allocated Io operations
- * @retval null An error
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
-IoOperations *hicnConnection_Create(Forwarder *forwarder, const char * interfaceName, int fd,
- const AddressPair *pair, bool isLocal);
-#endif // hicnConnection_h
diff --git a/hicn-light/src/hicn/io/hicnListener.c b/hicn-light/src/hicn/io/hicnListener.c
deleted file mode 100644
index bc49f4cee..000000000
--- a/hicn-light/src/hicn/io/hicnListener.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <hicn/hicn-light/config.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <unistd.h>
-
-#include <hicn/io/hicnConnection.h>
-#include <hicn/io/hicnListener.h>
-
-#include <hicn/core/connection.h>
-#include <hicn/core/connectionTable.h>
-#include <hicn/core/forwarder.h>
-#include <parc/algol/parc_Memory.h>
-#include <parc/algol/parc_Network.h>
-#include <parc/assert/parc_Assert.h>
-#include <hicn/core/mapme.h>
-#include <hicn/core/messagePacketType.h>
-#include <hicn/io/listener.h>
-#include <hicn/socket/api.h>
-
-#define IPv6 6
-#define IPv4 4
-#define MTU_SIZE 1500 // bytes
-#define MAX_HICN_RETRY 5
-
-struct hicn_listener {
-
- char *listenerName;
-
- Forwarder *forwarder;
- Logger *logger;
-
- PARCEvent *hicn_event;
- int hicn_fd; // this is the file descriptor got from hicn library
-
- Address
- *localAddress; // this is the local address or 0::0 in case of the
- // main listener this is the address used inside
- // forwarder to identify the listener. Notice that this
- // address is the same as the fisical interfaces on
- // which we create the TUN. it is NOT the TUN address
- // which is given by libhicn after the bind operation
- // However the user alway uses this address since is
- // the only one available at configuration time
-
- unsigned inetFamily;
-
- int connection_id; // this is used only if the listener is used to receive
- // data packets we assume that 1 connection is associated
- // to one listener in this case so we set the
- // connection_id we the connection is create. if this id
- // is not set and a data packet is received, the packet is
- // dropped
-
- unsigned conn_id;
-};
-
-static void _destroy(ListenerOps **listenerOpsPtr);
-static const char *_getListenerName(const ListenerOps *ops);
-static const char *_getInterfaceName(const ListenerOps *ops);
-static unsigned _getInterfaceIndex(const ListenerOps *ops);
-static const Address *_getListenAddress(const ListenerOps *ops);
-static EncapType _getEncapType(const ListenerOps *ops);
-static int _getSocket(const ListenerOps *ops);
-static unsigned _createNewConnection(ListenerOps *listener, int fd, const AddressPair *pair);
-static const Connection * _lookupConnection(ListenerOps * listener, const AddressPair *pair);
-static Message *_readMessage(ListenerOps * listener, int fd, uint8_t *msgBuffer);
-static void _hicnListener_readcb(int fd, PARCEventType what, void *listener_void);
-static Address *_createAddressFromPacket(uint8_t *msgBuffer);
-static void _handleWldrNotification(ListenerOps *listener, uint8_t *msgBuffer);
-static void _readFrameToDiscard(HicnListener *hicn, int fd);
-
-static ListenerOps _hicnTemplate = {
- .context = NULL,
- .destroy = &_destroy,
- .getInterfaceIndex = &_getInterfaceIndex,
- .getListenAddress = &_getListenAddress,
- .getEncapType = &_getEncapType,
- .getSocket = &_getSocket,
- .getInterfaceName = &_getInterfaceName,
- .getListenerName = &_getListenerName,
- .createConnection = &_createNewConnection,
- .lookupConnection = &_lookupConnection,
-};
-
-static bool _isEmptyAddressIPv6(Address *address) {
- struct sockaddr_in6 *addr6 =
- parcMemory_AllocateAndClear(sizeof(struct sockaddr_in6));
- parcAssertNotNull(addr6, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(addr6));
-
- addressGetInet6(address, addr6);
-
- bool res = true;
- for (int i = 0; i < 16; ++i) {
- if (addr6->sin6_addr.s6_addr[i] != 0) {
- res = false;
- }
- }
-
- parcMemory_Deallocate((void **)&addr6);
-
- return res;
-}
-
-static Message *_readMessage(ListenerOps * listener, int fd, uint8_t *msgBuffer) {
- HicnListener * hicn = (HicnListener*)listener->context;
- Message *message = NULL;
-
- ssize_t readLength = read(fd, msgBuffer, MTU_SIZE);
-
- if (readLength < 0) {
- printf("read failed %d: (%d) %s\n", fd, errno, strerror(errno));
- return message;
- }
-
- size_t packetLength = messageHandler_GetTotalPacketLength(msgBuffer);
-
- if (readLength != packetLength) {
- parcMemory_Deallocate((void **)&msgBuffer);
- return message;
- }
-
- if (messageHandler_IsTCP(msgBuffer)) {
- MessagePacketType pktType;
- unsigned connid = 0;
- if (messageHandler_IsData(msgBuffer)) {
- pktType = MessagePacketType_ContentObject;
- if (hicn->connection_id == -1) {
- parcMemory_Deallocate((void **)&msgBuffer);
- return message;
- } else {
- connid = hicn->connection_id;
- }
- } else if (messageHandler_IsInterest(msgBuffer)) {
- // notice that the connections for the interest (the one that we create at
- // run time) uses as a local address 0::0, so the main tun
- pktType = MessagePacketType_Interest;
- Address *packetAddr = _createAddressFromPacket(msgBuffer);
-
- AddressPair *pair_find = addressPair_Create(packetAddr, /* dummy */ hicn->localAddress);
- const Connection *conn = _lookupConnection(listener, pair_find);
- addressPair_Release(&pair_find);
- if (conn == NULL) {
- AddressPair *pair = addressPair_Create(hicn->localAddress, packetAddr);
- connid = _createNewConnection(listener, fd, pair);
- addressPair_Release(&pair);
- } else {
- connid = connection_GetConnectionId(conn);
- }
- addressDestroy(&packetAddr);
- } else {
- printf("Got a packet that is not a data nor an interest, drop it!\n");
- parcMemory_Deallocate((void **)&msgBuffer);
- return message;
- }
-
- message = message_CreateFromByteArray(connid, msgBuffer, pktType,
- forwarder_GetTicks(hicn->forwarder),
- forwarder_GetLogger(hicn->forwarder));
- if (message == NULL) {
- parcMemory_Deallocate((void **)&msgBuffer);
- }
- } else if (messageHandler_IsWldrNotification(msgBuffer)) {
- _handleWldrNotification(listener, msgBuffer);
- } else {
- messageHandler_handleHooks(hicn->forwarder, msgBuffer, listener, fd, NULL);
- parcMemory_Deallocate((void **)&msgBuffer);
- }
-
- return message;
-}
-
-static void _receivePacket(ListenerOps * listener, int fd) {
- HicnListener * hicn = (HicnListener*)listener->context;
- Message *msg = NULL;
- uint8_t *msgBuffer = parcMemory_AllocateAndClear(MTU_SIZE);
- msg = _readMessage(listener, fd, msgBuffer);
-
- if (msg) {
- forwarder_Receive(hicn->forwarder, msg);
- }
-}
-
-static void _hicnListener_readcb(int fd, PARCEventType what, void *listener_void) {
- ListenerOps * listener = (ListenerOps *)listener_void;
- HicnListener *hicn = (HicnListener *)listener->context;
-
- if (hicn->inetFamily == IPv4 || hicn->inetFamily == IPv6) {
- if (what & PARCEventType_Read) {
- _receivePacket(listener, fd);
- }
- } else {
- _readFrameToDiscard(hicn, fd);
- }
-}
-
-static bool _isEmptyAddressIPv4(Address *address) {
- bool res = false;
-
- if (strcmp("inet4://0.0.0.0:1234", addressToString(address)) == 0) res = true;
- return res;
-}
-
-ListenerOps *hicnListener_CreateInet(Forwarder *forwarder, char *symbolic,
- Address *address) {
- HicnListener *hicn = parcMemory_AllocateAndClear(sizeof(HicnListener));
- parcAssertNotNull(hicn, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(HicnListener));
-
- hicn->forwarder = forwarder;
- hicn->listenerName = parcMemory_StringDuplicate(symbolic, strlen(symbolic));
-
- hicn->conn_id = forwarder_GetNextConnectionId(forwarder);
- hicn->inetFamily = IPv4;
-
- hicn->connection_id = -1;
-
- hicn_socket_helper_t *hicnSocketHelper =
- forwarder_GetHicnSocketHelper(forwarder);
-
- if (_isEmptyAddressIPv4(address)) {
- hicn->hicn_fd = hicn_socket(hicnSocketHelper, symbolic, NULL);
- } else {
- struct sockaddr_in *tmpAddr =
- parcMemory_AllocateAndClear(sizeof(struct sockaddr_in));
- parcAssertNotNull(tmpAddr, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(tmpAddr));
- addressGetInet(address, tmpAddr);
- char *local_addr = parcMemory_AllocateAndClear(INET_ADDRSTRLEN);
- inet_ntop(AF_INET, &(tmpAddr->sin_addr), local_addr, INET_ADDRSTRLEN);
- parcMemory_Deallocate((void **)&tmpAddr);
-
- hicn->hicn_fd = hicn_socket(hicnSocketHelper, symbolic, local_addr);
-
- parcMemory_Deallocate((void **)&local_addr);
- }
-
- if (hicn->hicn_fd < 0) {
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- logger_Log(
- hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "HicnListener %s: error while creating an hicn listener in lib_hicn",
- symbolic);
- }
- logger_Release(&hicn->logger);
- addressDestroy(&hicn->localAddress);
- parcMemory_Deallocate((void **)&hicn->listenerName);
- parcMemory_Deallocate((void **)&hicn);
- return NULL;
- }
-
- // Set non-blocking flag
- int flags = fcntl(hicn->hicn_fd, F_GETFL, NULL);
- parcAssertTrue(flags != -1,
- "fcntl failed to obtain file descriptor flags (%d)", errno);
- int failure = fcntl(hicn->hicn_fd, F_SETFL, flags | O_NONBLOCK);
- parcAssertFalse(failure, "fcntl failed to set file descriptor flags (%d)",
- errno);
-
- ListenerOps *ops = parcMemory_AllocateAndClear(sizeof(ListenerOps));
- parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(ListenerOps));
-
- memcpy(ops, &_hicnTemplate, sizeof(ListenerOps));
- ops->context = hicn;
-
- hicn->hicn_event = dispatcher_CreateNetworkEvent(
- forwarder_GetDispatcher(forwarder), true, _hicnListener_readcb,
- (void *)ops, hicn->hicn_fd);
- dispatcher_StartNetworkEvent(forwarder_GetDispatcher(forwarder),
- hicn->hicn_event);
-
-
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "HicnListener %s created", symbolic);
- }
-
- return ops;
- return NULL;
-}
-
-ListenerOps *hicnListener_CreateInet6(Forwarder *forwarder, char *symbolic,
- Address *address) {
- HicnListener *hicn = parcMemory_AllocateAndClear(sizeof(HicnListener));
- parcAssertNotNull(hicn, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(HicnListener));
-
- hicn->forwarder = forwarder;
- hicn->listenerName = parcMemory_StringDuplicate(symbolic, strlen(symbolic));
- hicn->logger = logger_Acquire(forwarder_GetLogger(forwarder));
-
- hicn->conn_id = forwarder_GetNextConnectionId(forwarder);
- hicn->localAddress = addressCopy(address);
-
- hicn->inetFamily = IPv6;
-
- hicn->connection_id = -1;
-
- // the call to libhicn is the same both for the main and the normal listeners
- // in both cases we need to set only the identifier. In the case of normal
- // listener (listener for data packet) we let the library select the right ip
- // address we just need to set the right type of packet
-
- hicn_socket_helper_t *hicnSocketHelper =
- forwarder_GetHicnSocketHelper(forwarder);
-
- if (_isEmptyAddressIPv6(address)) {
- // create main listener
- hicn->hicn_fd = hicn_socket(hicnSocketHelper, symbolic, NULL);
- } else {
- // create listener for the connetion
- struct sockaddr_in6 *tmpAddr =
- parcMemory_AllocateAndClear(sizeof(struct sockaddr_in6));
-
- parcAssertNotNull(tmpAddr, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(tmpAddr));
- addressGetInet6(address, tmpAddr);
-
- char *local_addr = parcMemory_AllocateAndClear(INET6_ADDRSTRLEN);
- inet_ntop(AF_INET6, &(tmpAddr->sin6_addr), local_addr, INET6_ADDRSTRLEN);
-
- parcMemory_Deallocate((void **)&tmpAddr);
-
- hicn->hicn_fd = hicn_socket(hicnSocketHelper, symbolic, local_addr);
-
- parcMemory_Deallocate((void **)&local_addr);
- }
-
- if (hicn->hicn_fd < 0) {
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- logger_Log(
- hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "HicnListener %s: error while creating an hicn listener in lib_hicn",
- symbolic);
- }
- logger_Release(&hicn->logger);
- addressDestroy(&hicn->localAddress);
- parcMemory_Deallocate((void **)&hicn->listenerName);
- parcMemory_Deallocate((void **)&hicn);
- return NULL;
- }
-
- // Set non-blocking flag
- int flags = fcntl(hicn->hicn_fd, F_GETFL, NULL);
- parcAssertTrue(flags != -1,
- "fcntl failed to obtain file descriptor flags (%d)", errno);
- int failure = fcntl(hicn->hicn_fd, F_SETFL, flags | O_NONBLOCK);
- parcAssertFalse(failure, "fcntl failed to set file descriptor flags (%d)",
- errno);
-
- ListenerOps *ops = parcMemory_AllocateAndClear(sizeof(ListenerOps));
- parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(ListenerOps));
-
- memcpy(ops, &_hicnTemplate, sizeof(ListenerOps));
- ops->context = hicn;
-
- hicn->hicn_event = dispatcher_CreateNetworkEvent(
- forwarder_GetDispatcher(forwarder), true, _hicnListener_readcb,
- (void *)ops, hicn->hicn_fd);
- dispatcher_StartNetworkEvent(forwarder_GetDispatcher(forwarder),
- hicn->hicn_event);
-
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "HicnListener %s created", symbolic);
- }
-
- return ops;
-}
-
-bool _hicnListener_BindInet6(ListenerOps *ops, const Address *remoteAddress) {
- HicnListener *hicn = (HicnListener *)ops->context;
- hicn_socket_helper_t *hicnSocketHelper =
- forwarder_GetHicnSocketHelper(hicn->forwarder);
-
- struct sockaddr_in6 *tmpAddr =
- parcMemory_AllocateAndClear(sizeof(struct sockaddr_in6));
- parcAssertNotNull(tmpAddr, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(tmpAddr));
- addressGetInet6(remoteAddress, tmpAddr);
- char *remote_addr = parcMemory_AllocateAndClear(INET6_ADDRSTRLEN);
- inet_ntop(AF_INET6, &(tmpAddr->sin6_addr), remote_addr, INET6_ADDRSTRLEN);
- parcMemory_Deallocate((void **)&tmpAddr);
-
- int res = hicn_bind(hicnSocketHelper, hicn->hicn_fd, remote_addr);
-
- bool result = false;
- if (res < 0) {
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "hicn_bind failed %d %s", res, hicn_socket_strerror(res));
- }
- } else {
- result = true;
- }
-
- parcMemory_Deallocate((void **)&remote_addr);
-
- return result;
-}
-
-bool _hicnListener_BindInet(ListenerOps *ops, const Address *remoteAddress) {
- HicnListener *hicn = (HicnListener *)ops->context;
- hicn_socket_helper_t *hicnSocketHelper =
- forwarder_GetHicnSocketHelper(hicn->forwarder);
-
- struct sockaddr_in *tmpAddr =
- parcMemory_AllocateAndClear(sizeof(struct sockaddr_in));
- parcAssertNotNull(tmpAddr, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(tmpAddr));
- addressGetInet(remoteAddress, tmpAddr);
- char *remote_addr = parcMemory_AllocateAndClear(INET_ADDRSTRLEN);
- inet_ntop(AF_INET, &(tmpAddr->sin_addr), remote_addr, INET_ADDRSTRLEN);
- parcMemory_Deallocate((void **)&tmpAddr);
-
- int res = hicn_bind(hicnSocketHelper, hicn->hicn_fd, remote_addr);
- bool result = false;
-
- if (res < 0) {
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "hicn_bind failed %d %s", res, hicn_socket_strerror(res));
- }
- } else {
- result = true;
- }
-
- parcMemory_Deallocate((void **)&remote_addr);
-
- return result;
-}
-
-bool hicnListener_Bind(ListenerOps *ops, const Address *remoteAddress) {
- if (addressGetType(remoteAddress) == ADDR_INET) {
- return _hicnListener_BindInet(ops, remoteAddress);
- } else if (addressGetType(remoteAddress) == ADDR_INET6) {
- return _hicnListener_BindInet6(ops, remoteAddress);
- } else {
- printf("Bind failed: Invalid address\n");
- return false;
- }
-}
-
-bool hicnListener_Punting(ListenerOps *ops, const char *prefix) {
- HicnListener *hicn = (HicnListener *)ops->context;
- hicn_socket_helper_t *hicnSocketHelper =
- forwarder_GetHicnSocketHelper(hicn->forwarder);
-
- int res = hicn_listen(hicnSocketHelper, hicn->hicn_fd, prefix);
- int retry = 0;
-
- while (res < 0 && retry < MAX_HICN_RETRY) {
- sleep(1);
- res = hicn_listen(hicnSocketHelper, hicn->hicn_fd, prefix);
- retry++;
- }
-
- if (res < 0) {
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "hicn_listen failed %d %s", res, hicn_socket_strerror(res));
- }
- return false;
- }
-
- return true;
-}
-
-bool hicnListener_SetConnectionId(ListenerOps *ops, unsigned connId) {
- HicnListener *hicn = (HicnListener *)ops->context;
- if (hicn) {
- hicn->connection_id = connId;
- return true;
- }
- return false;
-}
-
-static void _hicnListener_Destroy(HicnListener **listenerPtr) {
- parcAssertNotNull(listenerPtr, "Parameter must be non-null double pointer");
- parcAssertNotNull(*listenerPtr,
- "Parameter must derefernce to non-null pointer");
-
- HicnListener *hicn = *listenerPtr;
-
- dispatcher_DestroyNetworkEvent(forwarder_GetDispatcher(hicn->forwarder),
- &hicn->hicn_event);
- logger_Release(&hicn->logger);
- addressDestroy(&hicn->localAddress);
- parcMemory_Deallocate((void **)&hicn);
- *listenerPtr = NULL;
-}
-
-static void _destroy(ListenerOps **listenerOpsPtr) {
- ListenerOps *ops = *listenerOpsPtr;
- HicnListener *hicn = (HicnListener *)ops->context;
- _hicnListener_Destroy(&hicn);
- parcMemory_Deallocate((void **)&ops);
- *listenerOpsPtr = NULL;
-}
-
-static const char *_getListenerName(const ListenerOps *ops) {
- HicnListener *hicn = (HicnListener *)ops->context;
- return hicn->listenerName;
-}
-
-static const char *_getInterfaceName(const ListenerOps *ops) {
- const char *interfaceName = "";
- return interfaceName;
-}
-
-static unsigned _getInterfaceIndex(const ListenerOps *ops) {
- HicnListener *hicn = (HicnListener *)ops->context;
- return hicn->conn_id;
-}
-
-static const Address *_getListenAddress(const ListenerOps *ops) {
- HicnListener *hicn = (HicnListener *)ops->context;
- return hicn->localAddress;
-}
-
-static EncapType _getEncapType(const ListenerOps *ops) { return ENCAP_HICN; }
-
-static int _getSocket(const ListenerOps *ops) {
- HicnListener *hicn = (HicnListener *)ops->context;
- return hicn->hicn_fd;
-}
-
-// ===============================
-
-static void _readFrameToDiscard(HicnListener *hicn, int fd) {
- // we need to discard the frame. Read 1 byte. This will clear it off the
- // stack.
- uint8_t buffer;
- int nread = read(fd, &buffer, 1);
-
- if (nread > 0) {
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "Discarded frame from fd %d", fd);
- }
- } else if (nread < 0) {
- if (logger_IsLoggable(hicn->logger, LoggerFacility_IO,
- PARCLogLevel_Error)) {
- logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "Error trying to discard frame from fd %d: (%d) %s", fd, errno,
- strerror(errno));
- }
- }
-}
-
-static unsigned _createNewConnection(ListenerOps * listener, int fd,
- const AddressPair *pair) {
- HicnListener * hicn = (HicnListener *)listener->context;
- bool isLocal = false;
-
- // udpConnection_Create takes ownership of the pair
- IoOperations *ops = hicnConnection_Create(hicn->forwarder, listener->getInterfaceName(listener), fd, pair, isLocal);
- Connection *conn = connection_Create(ops);
-
- connectionTable_Add(forwarder_GetConnectionTable(hicn->forwarder), conn);
- unsigned connid = ioOperations_GetConnectionId(ops);
-
- return connid;
-}
-
-static const Connection * _lookupConnection(ListenerOps * listener,
- const AddressPair *pair) {
- HicnListener * hicn = (HicnListener*)listener->context;
- const Address * packetSourceAddress = addressPair_GetLocal(pair);
-
- const Connection *conn = NULL;
- if (hicn->connection_id != -1) {
- conn = connectionTable_FindById(
- forwarder_GetConnectionTable(hicn->forwarder), hicn->connection_id);
- } else {
- if (packetSourceAddress != NULL) {
- // in this first check we try to retrieve the standard connection
- // generated by the hicn-light
- AddressPair *pair =
- addressPair_Create(hicn->localAddress, packetSourceAddress);
- conn = connectionTable_FindByAddressPair(
- forwarder_GetConnectionTable(hicn->forwarder), pair);
- addressPair_Release(&pair);
- }
- }
-
- return conn;
-}
-
-static Address *_createAddressFromPacket(uint8_t *msgBuffer) {
- Address *packetAddr = NULL;
- if (messageHandler_GetIPPacketType(msgBuffer) == IPv6_TYPE) {
- struct sockaddr_in6 addr_in6;
- addr_in6.sin6_family = AF_INET6;
- addr_in6.sin6_port = htons(1234);
- addr_in6.sin6_flowinfo = 0;
- addr_in6.sin6_scope_id = 0;
- memcpy(&addr_in6.sin6_addr,
- (struct in6_addr *)messageHandler_GetSource(msgBuffer), 16);
- packetAddr = addressCreateFromInet6(&addr_in6);
- } else if (messageHandler_GetIPPacketType(msgBuffer) == IPv4_TYPE) {
- struct sockaddr_in addr_in;
- addr_in.sin_family = AF_INET;
- addr_in.sin_port = htons(1234);
- memcpy(&addr_in.sin_addr,
- (struct in_addr *)messageHandler_GetSource(msgBuffer), 4);
- packetAddr = addressCreateFromInet(&addr_in);
- }
- return packetAddr;
-}
-
-static void _handleWldrNotification(ListenerOps *listener, uint8_t *msgBuffer) {
- HicnListener * hicn = (HicnListener *)listener->context;
-
- Address *packetAddr = _createAddressFromPacket(msgBuffer);
-
- if (packetAddr == NULL) {
- parcMemory_Deallocate((void **)&msgBuffer);
- return;
- }
-
- AddressPair * pair = addressPair_Create(packetAddr, /* dummy */ hicn->localAddress);
-
- const Connection *conn = _lookupConnection(listener, pair);
-
- addressPair_Release(&pair);
- addressDestroy(&packetAddr);
-
- if (conn == NULL) {
- parcMemory_Deallocate((void **)&msgBuffer);
- return;
- }
-
- Message *message = message_CreateFromByteArray(
- connection_GetConnectionId(conn), msgBuffer,
- MessagePacketType_WldrNotification, forwarder_GetTicks(hicn->forwarder),
- forwarder_GetLogger(hicn->forwarder));
-
- connection_HandleWldrNotification((Connection *)conn, message);
-
- message_Release(&message);
-}
diff --git a/hicn-light/src/hicn/io/hicnListener.h b/hicn-light/src/hicn/io/hicnListener.h
deleted file mode 100644
index faf6ad6b8..000000000
--- a/hicn-light/src/hicn/io/hicnListener.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 hicnListener.h
- * @brief Listens for in coming Hicn connections
- *
- *
- */
-
-#ifndef hicnListener_h
-#define hicnListener_h
-
-#include <hicn/core/forwarder.h>
-#include <hicn/core/messageHandler.h>
-#include <hicn/io/listener.h>
-#include <stdlib.h>
-
-struct hicn_listener;
-typedef struct hicn_listener HicnListener;
-
-ListenerOps *hicnListener_CreateInet(Forwarder *forwarder, char *symbolic,
- Address *address);
-ListenerOps *hicnListener_CreateInet6(Forwarder *forwarder, char *symbolic,
- Address *address);
-bool hicnListener_Punting(ListenerOps *ops, const char *prefix);
-bool hicnListener_Bind(ListenerOps *ops, const Address *remoteAddress);
-bool hicnListener_SetConnectionId(ListenerOps *ops, unsigned connId);
-// const Address *hicnListener_GetTunAddress(const ListenerOps *ops);
-#endif // hicnListener_h
diff --git a/hicn-light/src/hicn/io/hicnTunnel.c b/hicn-light/src/hicn/io/hicnTunnel.c
deleted file mode 100644
index fd5acc680..000000000
--- a/hicn-light/src/hicn/io/hicnTunnel.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <hicn/hicn-light/config.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <parc/assert/parc_Assert.h>
-#include <hicn/io/hicnConnection.h>
-#include <hicn/io/hicnListener.h>
-#include <hicn/io/hicnTunnel.h>
-
-IoOperations *hicnTunnel_CreateOnListener(Forwarder *forwarder,
- ListenerOps *localListener,
- const Address *remoteAddress) {
- parcAssertNotNull(forwarder, "Parameter hicn-light must be non-null");
- parcAssertNotNull(localListener, "Parameter localListener must be non-null");
- parcAssertNotNull(remoteAddress, "Parameter remoteAddress must be non-null");
-
- Logger *logger = forwarder_GetLogger(forwarder);
-
- IoOperations *ops = NULL;
- if (localListener->getEncapType(localListener) == ENCAP_HICN) {
- const Address *localAddress =
- localListener->getListenAddress(localListener);
- address_type localType = addressGetType(localAddress);
- address_type remoteType = addressGetType(remoteAddress);
-
- if (localType == remoteType) {
- bool res = hicnListener_Bind(localListener, remoteAddress);
- if (res == false) {
- if (logger_IsLoggable(logger, LoggerFacility_IO, PARCLogLevel_Error)) {
- logger_Log(logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "Unable to bind local listener to remote node");
- }
- return ops;
- }
-
- // localAddress = hicnListener_GetTunAddress(localListener); //This is the
- // true local address
-
- AddressPair *pair = addressPair_Create(localAddress, remoteAddress);
- bool isLocal = false;
- int fd = localListener->getSocket(localListener);
- ops = hicnConnection_Create(forwarder, localListener->getInterfaceName(localListener), fd, pair, isLocal);
-
- addressPair_Release(&pair);
- } else {
- if (logger_IsLoggable(logger, LoggerFacility_IO, PARCLogLevel_Error)) {
- logger_Log(logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "Local listener of type %s and remote type %s, cannot "
- "establish tunnel",
- addressTypeToString(localType),
- addressTypeToString(remoteType));
- }
- }
- } else {
- if (logger_IsLoggable(logger, LoggerFacility_IO, PARCLogLevel_Error)) {
- logger_Log(logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "Local listener %p is not type UDP, cannot establish tunnel",
- (void *)localListener);
- }
- }
-
- return ops;
-}
-
-IoOperations *hicnTunnel_Create(Forwarder *forwarder,
- const Address *localAddress,
- const Address *remoteAddress) {
- ListenerSet *set = forwarder_GetListenerSet(forwarder);
- ListenerOps *listener = listenerSet_Find(set, ENCAP_HICN, localAddress);
- IoOperations *ops = NULL;
- if (listener) {
- ops = hicnTunnel_CreateOnListener(forwarder, listener, remoteAddress);
- } else {
- if (logger_IsLoggable(forwarder_GetLogger(forwarder), LoggerFacility_IO,
- PARCLogLevel_Error)) {
- char *str = addressToString(localAddress);
- logger_Log(forwarder_GetLogger(forwarder), LoggerFacility_IO,
- PARCLogLevel_Error, __func__,
- "Could not find listener to match address %s", str);
- parcMemory_Deallocate((void **)&str);
- }
- }
-
- if (ops) {
- hicnListener_SetConnectionId(listener, ops->getConnectionId(ops));
- }
-
- return ops;
-}
diff --git a/hicn-light/src/hicn/io/hicnTunnel.h b/hicn-light/src/hicn/io/hicnTunnel.h
deleted file mode 100644
index 1fe0b413c..000000000
--- a/hicn-light/src/hicn/io/hicnTunnel.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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 hicnTunnel.h
- * @brief Establish a tunnel to a remote system
- *
- * Creates a "hicn tunnel" to a remote system. There must already be a local
- * HICN listener for the local side of the connection.
- *
- */
-
-#ifndef hicnTunnel_h
-#define hicnTunnel_h
-
-#include <hicn/core/forwarder.h>
-#include <hicn/io/ioOperations.h>
-#include <hicn/io/listener.h>
-#include <hicn/utils/address.h>
-
-/**
- * Establishes a connection to a remote system over HICN
- *
- * The remoteAddress must be of the same type (i.e. v4 or v6) as the
- * localAddress. There must be an existing HICN listener on the local address.
- * If either of these are not true, will return NULL.
- *
- * The connection will go in the table immediately, and will be in the "up"
- * state.
- *
- * @param [in] an allocated hicn-light Forwarder
- * @param [in] localAddress The local IP address and port to use for the
- * connection
- * @param [in] remote Address the remote IP address for the connection, must
- * include a destination port.
- *
- * @retval non-null An allocated Io Operations structure for the connection
- * @retval null An error
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
-IoOperations *hicnTunnel_Create(Forwarder *forwarder,
- const Address *localAddress,
- const Address *remoteAddress);
-
-IoOperations *hicnTunnel_CreateOnListener(Forwarder *forwarder,
- ListenerOps *localListener,
- const Address *remoteAddress);
-
-#endif // hicnTunnel_h
diff --git a/hicn-light/src/hicn/io/ioOperations.c b/hicn-light/src/hicn/io/ioOperations.c
deleted file mode 100644
index 0087b320a..000000000
--- a/hicn-light/src/hicn/io/ioOperations.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <parc/assert/parc_Assert.h>
-#include <hicn/hicn-light/config.h>
-#include <hicn/io/ioOperations.h>
-#include <stdio.h>
-
-void *ioOperations_GetClosure(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- return ops->closure;
-}
-
-bool ioOperations_Send(IoOperations *ops, const Address *nexthop,
- Message *message) {
- return ops->send(ops, nexthop, message);
-}
-
-bool ioOperations_SendIOVBuffer(IoOperations *ops, struct iovec *message,
- size_t size) {
- return ops->sendIOVBuffer(ops, message, size);
-}
-
-const Address *ioOperations_GetRemoteAddress(const IoOperations *ops) {
- return ops->getRemoteAddress(ops);
-}
-
-const AddressPair *ioOperations_GetAddressPair(const IoOperations *ops) {
- return ops->getAddressPair(ops);
-}
-
-
-
-bool ioOperations_IsUp(const IoOperations *ops) { return ops->isUp(ops); }
-
-bool ioOperations_IsLocal(const IoOperations *ops) { return ops->isLocal(ops); }
-
-unsigned ioOperations_GetConnectionId(const IoOperations *ops) {
- return ops->getConnectionId(ops);
-}
-
-void ioOperations_Release(IoOperations **opsPtr) {
- IoOperations *ops = *opsPtr;
- ops->destroy(opsPtr);
-}
-
-const void *ioOperations_Class(const IoOperations *ops) {
- return ops->class(ops);
-}
-
-list_connections_type ioOperations_GetConnectionType(const IoOperations *ops) {
- return ops->getConnectionType(ops);
-}
-
-void ioOperations_SendProbe(IoOperations *ops, uint8_t *message) {
- ops->sendProbe(ops, 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);
-}
-
-#ifdef WITH_POLICY
-uint32_t ioOperations_GetPriority(const IoOperations *ops) {
- return ops->getPriority(ops);
-}
-
-void ioOperations_SetPriority(IoOperations *ops, uint32_t priority) {
- ops->setPriority(ops, priority);
-}
-#endif /* WITH_POLICY */
-
-const char * ioOperations_GetInterfaceName(const IoOperations *ops) {
- return ops->getInterfaceName(ops);
-}
diff --git a/hicn-light/src/hicn/io/ioOperations.h b/hicn-light/src/hicn/io/ioOperations.h
deleted file mode 100644
index 5d9befac3..000000000
--- a/hicn-light/src/hicn/io/ioOperations.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Defines the interface all connections use to communicate with the forwarder.
- */
-
-/**
- * I/O is built around a callback structure. The connection table contains an
- * operations structure built around function pointers. These allow the
- * connection table to be agnostic about underlying connections.
- */
-
-#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>
-#include <hicn/utils/address.h>
-
-// packet types for probing
-#define PACKET_TYPE_PROBE_REQUEST 5
-#define PACKET_TYPE_PROBE_REPLY 6
-
-struct io_ops;
-typedef struct io_ops IoOperations;
-
-/**
- * @typedef IoOperations
- * @abstract The IO Operations structure abstracts an connection's properties
- * and send() method
- * @constant context Implementation specific opaque data, passed back on each
- * call
- * @constant send function pointer to send a message, does not destroy the
- * message
- * @constant getRemoteAddress function pointer to return the "to" address
- * associated with the connection. Some connections might not have a specific
- * peer, such as multicast, where its the group address.
- * @constant isUp test if the connection is up, ready to send a message.
- * @constant isLocal test if the connection is local to the host.
- * @constant getConnectionId returns the hicn-light id for the connection.
- * @constant destroy releases a refernce count on the connection and possibly
- * destroys the connection.
- * @constant class A unique identifier for each class that instantiates
- * 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.
- * @constant getInterfaceName Returns the interface name associated to a
- * connection.
- * @discussion <#Discussion#>
- */
-struct io_ops {
- void *closure;
- bool (*send)(IoOperations *ops, const Address *nexthop, Message *message);
- bool (*sendIOVBuffer)(IoOperations *ops, struct iovec *message, size_t
- size);
- const Address *(*getRemoteAddress)(const IoOperations *ops);
- const AddressPair *(*getAddressPair)(const IoOperations *ops);
- bool (*isUp)(const IoOperations *ops);
- bool (*isLocal)(const IoOperations *ops);
- unsigned (*getConnectionId)(const IoOperations *ops);
- void (*destroy)(IoOperations **opsPtr);
- const void *(*class)(const IoOperations *ops);
- list_connections_type (*getConnectionType)(const IoOperations *ops);
- void (*sendProbe)(IoOperations *ops, 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);
-#ifdef WITH_POLICY
- uint32_t (*getPriority)(const IoOperations *ops);
- void (*setPriority)(IoOperations *ops, uint32_t priority);
-#endif /* WITH_POLICY */
- const char * (*getInterfaceName)(const IoOperations *ops);
-};
-
-/**
- * Returns the closure of the interface
- *
- * The creator of the closure sets this parameter to store its state.
- *
- * @param [in] ops A concrete instance of the interface
- *
- * @return The value set by the concrete instance of the interface.
- *
- * Example:
- * @clode
- * {
-
- * }
- * @endcode
- */
-void *ioOperations_GetClosure(const IoOperations *ops);
-
-/**
- * Release all memory related to the interface and implementation
- *
- * This function must release all referenced memory in the concrete
- * implementation and memory related to the IoOperations. It should NULL the
- * input parameter.
- *
- * @param [in,out] opsPtr Pointer to interface. Will be NULLed.
- *
- * Example:
- * @code
- *
- * static void
- * _etherConnection_InternalRelease(_EtherState *etherConnState)
- * {
- * // release internal state of _EtherState
- * }
- *
- * static void
- * _etherConnection_Release(IoOperations **opsPtr)
- * {
- * IoOperations *ops = *opsPtr;
- *
- * _EtherState *etherConnState = (_EtherState *)
- * ioOperations_GetClosure(ops);
- * _etherConnection_InternalRelease(etherConnState);
- *
- * parcMemory_Deallocate((void **) &ops);
- * }
- *
- * IoOperations *
- * etherConnection_Create(Forwarder *forwarder, GenericEther *ether,
- * AddressPair *pair)
- * {
- * size_t allocationSize = sizeof(_EtherState) + sizeof(IoOperations);
- * IoOperations *ops = parcMemory_AllocateAndClear(allocationSize);
- * if (ops) {
- * // fill in other interface functions
- * ops->destroy = &_etherConnection_Release;
- * ops->closure = (uint8_t *) ops + sizeof(IoOperations);
- *
- * _EtherState *etherConnState = ioOperations_GetClosure(ops);
- * // fill in Ethernet state
- * }
- * return ops;
- * }
- * @endcode
- */
-void ioOperations_Release(IoOperations **opsPtr);
-
-/**
- * Sends the specified Message out this connection
- *
- * The the implementation of send may queue the message, it must acquire a
- * reference to it.
- *
- * @param [in] ops The connection implementation.
- * @param [in] nexthop On multiple access networks, this parameter might be
- * used, usually NULL.
- * @param [in] message The message to send. If the message will be queued, it
- * will be acquired.
- *
- * @return true The message was sent or queued
- * @retrun false An error occured and the message will not be sent or queued
- *
- * Example:
- * @code
- * {
- * if (ioOperations_IsUp(conn->ops)) {
- * return ioOperations_Send(conn->ops, NULL, message);
- * }
- * }
- * @endcode
- */
-bool ioOperations_Send(IoOperations *ops, const Address *nexthop,
- Message *message);
-
-bool ioOperations_SendIOVBuffer(IoOperations *ops, struct iovec *message,
- size_t size);
-
-/**
- * A connection is made up of a local and a remote address. This function
- * returns the remote address.
- *
- * Represents the destination endpoint of the communication.
- *
- * @param [in] ops The connection implementation.
- *
- * @return non-null The remote address
- * @return null The connection does not have a remote address
- *
- * Example:
- * @code
- * {
- * Address *local = addressCreateFromLink((uint8_t []) { 0x01, 0x02, 0x03,
- * 0x04, 0x05, 0x06 }, 6); Address *remote = addressCreateFromLink((uint8_t [])
- * { 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, 6); AddressPair *pair =
- * addressPair_Create(local, remote); IoOperations *ops =
- * etherConnection_Create(forwarder, ether, pair);
- *
- * const Address *test = ioOperations_GetRemoteAddress(ops);
- * parcAssertTrue(addressEquals(test, remote), "Wrong remote address");
- * ioOperations_Release(&ops);
- * addressPair_Release(&pair);
- * addressDestroy(&local);
- * addressDestroy(&remote);
- * }
- * @endcode
- */
-const Address *ioOperations_GetRemoteAddress(const IoOperations *ops);
-
-/**
- * A connection is made up of a local and a remote address. This function
- * returns the address pair.
- *
- * Represents the destination endpoint of the communication.
- *
- * @param [in] ops The connection implementation.
- *
- * @return non-null The address pair
- * @return null An error.
- *
- * Example:
- * @code
- * {
- * Address *local = addressCreateFromLink((uint8_t []) { 0x01, 0x02, 0x03,
- * 0x04, 0x05, 0x06 }, 6); Address *remote = addressCreateFromLink((uint8_t [])
- * { 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, 6); AddressPair *pair =
- * addressPair_Create(local, remote); IoOperations *ops =
- * etherConnection_Create(forwarder, ether, pair);
- *
- * const AddressPair *test = ioOperations_GetAddressPair(ops);
- * parcAssertTrue(addressPair(test, pair), "Wrong address pair");
- * ioOperations_Release(&ops);
- * addressPair_Release(&pair);
- * addressDestroy(&local);
- * addressDestroy(&remote);
- * }
- * @endcode
- */
-const AddressPair *ioOperations_GetAddressPair(const IoOperations *ops);
-
-/**
- * Returns true if the underlying connection is in operation
- *
- * An UP connection is able to send and receive packets. If a subsystem needs to
- * take actions when a connection goes UP or DOWN, it should subscribe as a
- * Missive listener.
- *
- * @param [in] ops The connection implementation.
- *
- * @return true The connection is UP
- * @return false The connection is not UP
- *
- * Example:
- * @code
- * {
- * if (ioOperations_IsUp(conn->ops)) {
- * return ioOperations_Send(conn->ops, NULL, message);
- * }
- * }
- * @endcode
- */
-bool ioOperations_IsUp(const IoOperations *ops);
-
-/**
- * If the remote address is local to this system, returns true
- *
- * Will return true if an INET or INET6 connection is on localhost. Will return
- * true for AF_UNIX. An Ethernet connection is not local.
- *
- * @param [in] ops The connection implementation.
- *
- * @return true The remote address is local to the system
- * @return false The remote address is not local
- *
- * Example:
- * @code
- * {
- * // Is the ingress connection remote? If so check for non-zero and
- * decrement if (!ioOperations(ingressConnectionOps) { uint8_t hoplimit =
- * message_GetHopLimit(interestMessage); if (hoplimit == 0) {
- * // error
- * } else {
- * hoplimit--;
- * }
- * // take actions on hoplimit
- * }
- * }
- * @endcode
- */
-bool ioOperations_IsLocal(const IoOperations *ops);
-
-/**
- * Returns the connection ID represented by this IoOperations in the
- * ConnectionTable.
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [in] ops The connection implementation.
- *
- * @return number The connection ID in the connection table.
- *
- * Example:
- * @code
- * {
- * unsigned id = ioOperations_GetConnectionId(ingressIoOps);
- * const Connection *conn =
- * connectionTable_FindById(forwarder->connectionTable, id);
- * }
- * @endcode
- */
-unsigned ioOperations_GetConnectionId(const IoOperations *ops);
-
-/**
- * A pointer that represents the class of the connection
- *
- * Each concrete implementation has a class pointer that is unique to the
- * implementation (not instance). Each implementation is free to choose how to
- * determine the value, so long as it is unique on the system. This is a
- * system-local value.
- *
- * @param [in] ops The connection implementation.
- *
- * @return non-null A pointer value unique to the implementation (not instance).
- *
- * Example:
- * @code
- * bool
- * etherConnection_IsInstanceOf(const Connection *conn)
- * {
- * bool result = false;
- * if (conn != NULL) {
- * IoOperations *ops = connection_GetIoOperations(conn);
- * const void *class = ioOperations_Class(ops);
- * result = (class == _etherConnection_Class(ops));
- * }
- * return result;
- * }
- * @endcode
- */
-const void *ioOperations_Class(const IoOperations *ops);
-
-/**
- * Returns the transport type of the connection (TCP, UDP, L2, etc.).
- *
- * TCP and AF_UNIX are both stream connections and will both return
- * "Connection_TCP". Ethernet will return "Connection_L2".
- *
- * @param [in] ops The connection implementation.
- *
- * @return Connection_TCP A TCP4, TCP6, or AF_UNIX connection
- * @return Connection_UDP A UDP4 or UDP6 connection
- * @return Connection_L2 An Ethernet connection
- *
- * Example:
- * @code
- * {
- * ConnectionType type =
- * ioOperations_GetConnectionType(connection_GetIoOperations(connection));
- * Connection *Conn =
- * Connection_Create(connection_GetConnectionId(connection), localAddress,
- * remoteAddress, type);
- * }
- * @endcode
- */
-list_connections_type ioOperations_GetConnectionType(const IoOperations *ops);
-
-void ioOperations_SendProbe(IoOperations *ops, 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);
-
-#ifdef WITH_POLICY
-/**
- * Returns the priority of the connection
- *
- * @param [in] ops The connection implementation.
- *
- * @return Connection state (uint32_t).
- */
-uint32_t ioOperations_GetPriority(const IoOperations *ops);
-
-/**
- * Sets the priority of the connection
- *
- * @param [in] ops The connection implementation.
- * @param [in] state New state to set (uint32_t).
- */
-void ioOperations_SetPriority(IoOperations *ops, uint32_t priority);
-#endif /* WITH_POLICY */
-
-/**
- * Sets the interface name associated to the connection.
- *
- * @param [in] ops The connection implementation.
- * @return the name associated to the connection (const char *)
- */
-const char * ioOperations_GetInterfaceName(const IoOperations *ops);
-
-#endif // io_h
diff --git a/hicn-light/src/hicn/io/listener.h b/hicn-light/src/hicn/io/listener.h
deleted file mode 100644
index 1b473be59..000000000
--- a/hicn-light/src/hicn/io/listener.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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 listener.h
- * @brief Provides the function abstraction of all Listeners.
- *
- * A listener accepts in coming packets. A Stream listener will accept the
- * connection then pass it off to the {@link StreamConnection} class. A
- * datagram listener will have to have its own way to multiplex packets.
- *
- */
-
-#ifndef listener_h
-#define listener_h
-
-#include <hicn/utils/address.h>
-#include <hicn/io/addressPair.h>
-#include <hicn/core/connection.h>
-
-struct listener_ops;
-typedef struct listener_ops ListenerOps;
-
-typedef enum {
- ENCAP_TCP, /**< TCP encapsulation type */
- ENCAP_UDP, /**< UDP encapsulation type */
- ENCAP_ETHER, /**< Ethernet encapsulation type */
- ENCAP_LOCAL, /**< A connection to a local protocol stack */
- ENCAP_HICN
-} EncapType;
-
-struct listener_ops {
- /**
- * A user-defined parameter
- */
- void *context;
-
- /**
- * Called to destroy the Listener.
- *
- * @param [in] listenerOpsPtr Double pointer to this structure
- */
- void (*destroy)(ListenerOps **listenerOpsPtr);
-
- /**
- * Returns the listener name of the listener.
- *
- * @param [in] ops Pointer to this structure
- *
- * @return the listener name of the listener
- */
- const char *(*getListenerName)(const ListenerOps *ops);
-
- /**
- * Returns the interface index of the listener.
- *
- * @param [in] ops Pointer to this structure
- *
- * @return the interface index of the listener
- */
- unsigned (*getInterfaceIndex)(const ListenerOps *ops);
-
- /**
- * Returns the address pair that defines the listener (local, remote)
- *
- * @param [in] ops Pointer to this structure
- *
- * @return the (local, remote) pair of addresses
- */
- const Address *(*getListenAddress)(const ListenerOps *ops);
-
- /**
- * Returns the encapsulation type of the listener (e.g. TCP, UDP, HICN)
- *
- * @param [in] ops Pointer to this structure
- *
- * @return the listener encapsulation type
- */
- EncapType (*getEncapType)(const ListenerOps *ops);
-
- /**
- * Returns the interface name of the listener.
- *
- * @param [in] ops Pointer to this structure
- *
- * @return the interface name of the listener
- */
- const char *(*getInterfaceName)(const ListenerOps *ops);
-
- /**
- * Returns the underlying socket associated with the listener
- *
- * Not all listeners are capable of returning a useful socket. In those
- * cases, this function pointer is NULL.
- *
- * TCP does not support this operation (function is NULL). UDP returns its
- * local socket.
- *
- * The caller should never close this socket, the listener will do that when
- * its destroy method is called.
- *
- * @param [in] ops Pointer to this structure
- *
- * @retval integer The socket descriptor
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
- int (*getSocket)(const ListenerOps *ops);
-
- unsigned (*createConnection)(ListenerOps *listener, int fd, const AddressPair *pair);
- const Connection * (*lookupConnection)(ListenerOps * listener, const AddressPair *pair);
-};
-#endif // listener_h
diff --git a/hicn-light/src/hicn/io/listenerSet.c b/hicn-light/src/hicn/io/listenerSet.c
deleted file mode 100644
index d69632287..000000000
--- a/hicn-light/src/hicn/io/listenerSet.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <hicn/hicn-light/config.h>
-#include <stdio.h>
-
-#include <parc/algol/parc_ArrayList.h>
-#include <parc/algol/parc_Memory.h>
-#include <parc/assert/parc_Assert.h>
-#include <hicn/io/listenerSet.h>
-
-struct listener_set {
- PARCArrayList *listOfListeners;
-};
-
-static void listenerSet_DestroyListenerOps(void **opsPtr) {
- ListenerOps *ops = *((ListenerOps **)opsPtr);
- ops->destroy(&ops);
-}
-
-ListenerSet *listenerSet_Create() {
- ListenerSet *set = parcMemory_AllocateAndClear(sizeof(ListenerSet));
- parcAssertNotNull(set, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(ListenerSet));
- set->listOfListeners = parcArrayList_Create(listenerSet_DestroyListenerOps);
-
- return set;
-}
-
-void listenerSet_Destroy(ListenerSet **setPtr) {
- parcAssertNotNull(setPtr, "Parameter must be non-null double pointer");
- parcAssertNotNull(*setPtr, "Parameter must dereference to non-null pointer");
-
- ListenerSet *set = *setPtr;
- parcArrayList_Destroy(&set->listOfListeners);
- parcMemory_Deallocate((void **)&set);
- *setPtr = NULL;
-}
-
-/**
- * @function listenerSet_Add
- * @abstract Adds the listener to the set
- * @discussion
- * Unique set based on pair (EncapType, localAddress)
- *
- * @param <#param1#>
- * @return <#return#>
- */
-bool listenerSet_Add(ListenerSet *set, ListenerOps *ops) {
- parcAssertNotNull(set, "Parameter set must be non-null");
- parcAssertNotNull(ops, "Parameter ops must be non-null");
-
- int opsEncap = ops->getEncapType(ops);
- const Address *opsAddress = ops->getListenAddress(ops);
-
- // make sure its not in the set
- size_t length = parcArrayList_Size(set->listOfListeners);
- for (size_t i = 0; i < length; i++) {
- ListenerOps *entry = parcArrayList_Get(set->listOfListeners, i);
-
- int entryEncap = entry->getEncapType(entry);
- const Address *entryAddress = entry->getListenAddress(entry);
-
- if (opsEncap == entryEncap && addressEquals(opsAddress, entryAddress)) {
- // duplicate
- return false;
- }
- }
-
- parcArrayList_Add(set->listOfListeners, ops);
- return true;
-}
-
-size_t listenerSet_Length(const ListenerSet *set) {
- parcAssertNotNull(set, "Parameter set must be non-null");
- return parcArrayList_Size(set->listOfListeners);
-}
-
-/**
- * Returns the listener at the given index
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [in] set An allocated listener set
- * @param [in] index The index position (0 <= index < listenerSet_Count)
- *
- * @retval non-null The listener at index
- * @retval null An error
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
-ListenerOps *listenerSet_Get(const ListenerSet *set, size_t index) {
- parcAssertNotNull(set, "Parameter set must be non-null");
- return parcArrayList_Get(set->listOfListeners, index);
-}
-
-ListenerOps *listenerSet_Find(const ListenerSet *set, EncapType encapType,
- const Address *localAddress) {
- parcAssertNotNull(set, "Parameter set must be non-null");
- parcAssertNotNull(localAddress, "Parameter localAddress must be non-null");
-
- ListenerOps *match = NULL;
-
- for (size_t i = 0; i < parcArrayList_Size(set->listOfListeners) && !match;
- i++) {
- ListenerOps *ops = parcArrayList_Get(set->listOfListeners, i);
- parcAssertNotNull(ops, "Got null listener ops at index %zu", i);
-
- if (ops->getEncapType(ops) == encapType) {
- if (addressEquals(localAddress, ops->getListenAddress(ops))) {
- match = ops;
- }
- }
- }
-
- return match;
-}
-
-ListenerOps *listenerSet_FindById(const ListenerSet *set, unsigned id) {
- parcAssertNotNull(set, "Parameter set must be non-null");
-
- ListenerOps *match = NULL;
-
- for (size_t i = 0; i < parcArrayList_Size(set->listOfListeners) && !match;
- i++) {
- ListenerOps *ops = parcArrayList_Get(set->listOfListeners, i);
- parcAssertNotNull(ops, "Got null listener ops at index %zu", i);
- if (ops->getInterfaceIndex(ops) == id) {
- match = ops;
- }
- }
-
- return match;
-}
-
-int listenerSet_FindIdByListenerName(const ListenerSet *set, const char *listenerName ) {
- parcAssertNotNull(set, "Parameter set must be non-null");
- parcAssertNotNull(listenerName, "Parameter listenerName must be non-null");
-
- ListenerOps *match = NULL;
- int index = -1;
- for (size_t i = 0; i < parcArrayList_Size(set->listOfListeners) && !match;
- i++) {
- ListenerOps *ops = parcArrayList_Get(set->listOfListeners, i);
- parcAssertNotNull(ops, "Got null listener ops at index %zu", i);
- if (ops->getListenerName(ops) && strcmp(ops->getListenerName(ops), listenerName) == 0) {
- index = ops->getInterfaceIndex(ops);
- break;
- }
- }
-
- return index;
-}
-
-void listenerSet_RemoveById(const ListenerSet *set, unsigned id) {
- parcAssertNotNull(set, "Parameter set must be non-null");
-
- for (size_t i = 0; i < parcArrayList_Size(set->listOfListeners);
- i++) {
- ListenerOps *ops = parcArrayList_Get(set->listOfListeners, i);
- parcAssertNotNull(ops, "Got null listener ops at index %zu", i);
- if (ops->getInterfaceIndex(ops) == id) {
- parcArrayList_RemoveAndDestroyAtIndex(set->listOfListeners, i);
- break;
- }
- }
-}
diff --git a/hicn-light/src/hicn/io/listenerSet.h b/hicn-light/src/hicn/io/listenerSet.h
deleted file mode 100644
index 5779d2af4..000000000
--- a/hicn-light/src/hicn/io/listenerSet.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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 listenerSet.h
- * @brief A listener set is unique on (EncapType, localAddress)
- *
- * Keeps track of all the running listeners. The set is unique on the
- * encapsulation type and the local address. For example, with TCP
- * encapsulation and local address 127.0.0.1 or Ethernet encapsulation and MAC
- * address 00:11:22:33:44:55.
- *
- * NOTE: This does not allow multiple EtherType on the same interface because
- * the Address for a LINK address does not include an EtherType.
- *
- */
-
-#ifndef listenerSet_h
-#define listenerSet_h
-
-#include <hicn/io/listener.h>
-
-struct listener_set;
-typedef struct listener_set ListenerSet;
-
-/**
- * <#One Line Description#>
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [<#in out in,out#>] <#name#> <#description#>
- *
- * @retval <#value#> <#explanation#>
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
-ListenerSet *listenerSet_Create(void);
-
-/**
- * <#One Line Description#>
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [<#in out in,out#>] <#name#> <#description#>
- *
- * @retval <#value#> <#explanation#>
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
-void listenerSet_Destroy(ListenerSet **setPtr);
-
-/**
- * @function listenerSet_Add
- * @abstract Adds the listener to the set
- * @discussion
- * Unique set based on pair (EncapType, localAddress).
- * Takes ownership of the ops memory if added.
- *
- * @param <#param1#>
- * @return true if added, false if not
- */
-bool listenerSet_Add(ListenerSet *set, ListenerOps *ops);
-
-/**
- * The number of listeners in the set
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [in] set An allocated listener set
- *
- * @retval <#value#> <#explanation#>
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
-size_t listenerSet_Length(const ListenerSet *set);
-size_t listenerSet_Length(const ListenerSet *set);
-
-/**
- * Returns the listener at the given index
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [in] set An allocated listener set
- * @param [in] index The index position (0 <= index < listenerSet_Lenght)
- *
- * @retval non-null The listener at index
- * @retval null An error
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
-ListenerOps *listenerSet_Get(const ListenerSet *set, size_t index);
-
-/**
- * Looks up a listener by its key (EncapType, LocalAddress)
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [in] set An allocated listener set
- * @param [in] encapType the listener type
- * @param [in] localAddress The local bind address (e.g. MAC address or TCP
- * socket)
- *
- * @retval non-null The listener matching the query
- * @retval null Does not exist
- *
- * Example:
- * @code
- *
- * @endcode
- */
-ListenerOps *listenerSet_Find(const ListenerSet *set, EncapType encapType,
- const Address *localAddress);
-
-/**
- * Looks up a listener by its id
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [in] set An allocated listener set
- * @param [in] id of the listener
- *
- * @retval non-null The listener matching the query
- * @retval null Does not exist
- *
- * Example:
- * @code
- *
- * @endcode
- */
-ListenerOps *listenerSet_FindById(const ListenerSet *set, unsigned id);
-
-/**
- * Looks up a listener by its id
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [in] set An allocated listener set
- * @param [in] name of the listener
- *
- * @retval greater or equal to 0 The listener matching the query
- * @retval -1 Does not exist
- *
- * Example:
- * @code
- *
- * @endcode
- */
-int listenerSet_FindIdByListenerName(const ListenerSet *set, const char *listenerName);
-
-/**
- * Remove up a listener by its id
- *
- * <#Paragraphs Of Explanation#>
- *
- * @param [in] set An allocated listener set
- * @param [in] id of the listener
- *
- * Example:
- * @code
- *
- * @endcode
- */
-void listenerSet_RemoveById(const ListenerSet *set, unsigned id);
-#endif
diff --git a/hicn-light/src/hicn/io/streamConnection.c b/hicn-light/src/hicn/io/streamConnection.c
deleted file mode 100644
index 00298d1b0..000000000
--- a/hicn-light/src/hicn/io/streamConnection.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Common activity for STREAM based listeners.
- */
-
-#include <errno.h>
-#include <hicn/hicn-light/config.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <parc/algol/parc_Hash.h>
-#include <hicn/core/connection.h>
-#include <hicn/core/forwarder.h>
-#include <hicn/core/message.h>
-#include <hicn/io/streamConnection.h>
-
-#include <parc/algol/parc_Memory.h>
-#include <parc/assert/parc_Assert.h>
-#include <hicn/core/messageHandler.h>
-
-#include <hicn/utils/commands.h>
-
-#include <hicn/hicn.h>
-// 128 KB output queue
-#define OUTPUT_QUEUE_BYTES (128 * 1024)
-
-static void _conn_readcb(PARCEventQueue *bufferEventVector, PARCEventType type,
- void *ioOpsVoid);
-
-static void _conn_eventcb(PARCEventQueue *bufferEventVector,
- PARCEventQueueEventType events, void *ioOpsVoid);
-
-typedef struct stream_state {
- Forwarder *forwarder;
- char * interfaceName;
- Logger *logger;
-
- int fd;
-
- AddressPair *addressPair;
- PARCEventQueue *bufferEventVector;
-
- bool isLocal;
- bool isUp;
- bool isClosed;
- 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;
-#ifdef WITH_POLICY
- uint32_t priority;
-#endif /* WITH_POLICY */
-} _StreamState;
-
-// Prototypes
-static bool _streamConnection_Send(IoOperations *ops, const Address *nexthop,
- Message *message);
-static bool _streamConnection_SendIOVBuffer(IoOperations *ops, struct
- iovec *msg, size_t size);
-static const Address *_streamConnection_GetRemoteAddress(
- const IoOperations *ops);
-static const AddressPair *_streamConnection_GetAddressPair(
- const IoOperations *ops);
-static unsigned _streamConnection_GetConnectionId(const IoOperations *ops);
-static bool _streamConnection_IsUp(const IoOperations *ops);
-static bool _streamConnection_IsLocal(const IoOperations *ops);
-static void _streamConnection_DestroyOperations(IoOperations **opsPtr);
-
-static void _setConnectionState(_StreamState *stream, bool isUp);
-static list_connections_type _streamConnection_GetConnectionType(
- const IoOperations *ops);
-static void _sendProbe(IoOperations *ops, 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);
-#ifdef WITH_POLICY
-static uint32_t _streamConnection_getPriority(const IoOperations *ops);
-static void _streamConnection_setPriority(IoOperations *ops, uint32_t priority);
-#endif /* WITH_POLICY */
-static const char * _streamConnection_getInterfaceName(const IoOperations *ops);
-
-/*
- * This assigns a unique pointer to the void * which we use
- * as a GUID for this class.
- */
-static const void *_ioOperationsGuid = __FILE__;
-
-/*
- * Return our GUID
- */
-static const void *_streamConnection_Class(const IoOperations *ops) {
- return _ioOperationsGuid;
-}
-
-static IoOperations _template = {
- .closure = NULL,
- .send = &_streamConnection_Send,
- .sendIOVBuffer = &_streamConnection_SendIOVBuffer,
- .getRemoteAddress = &_streamConnection_GetRemoteAddress,
- .getAddressPair = &_streamConnection_GetAddressPair,
- .getConnectionId = &_streamConnection_GetConnectionId,
- .isUp = &_streamConnection_IsUp,
- .isLocal = &_streamConnection_IsLocal,
- .destroy = &_streamConnection_DestroyOperations,
- .class = &_streamConnection_Class,
- .getConnectionType = &_streamConnection_GetConnectionType,
- .sendProbe = &_sendProbe,
- .getState = &_streamConnection_getState,
- .setState = &_streamConnection_setState,
- .getAdminState = &_streamConnection_getAdminState,
- .setAdminState = &_streamConnection_setAdminState,
-#ifdef WITH_POLICY
- .getPriority = &_streamConnection_getPriority,
- .setPriority = &_streamConnection_setPriority,
-#endif /* WITH_POLICY */
- .getInterfaceName = &_streamConnection_getInterfaceName,
-};
-
-IoOperations *streamConnection_AcceptConnection(Forwarder *forwarder, int fd,
- AddressPair *pair,
- bool isLocal) {
- _StreamState *stream = parcMemory_AllocateAndClear(sizeof(_StreamState));
- parcAssertNotNull(stream, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(_StreamState));
-
- Dispatcher *dispatcher = forwarder_GetDispatcher(forwarder);
- PARCEventScheduler *eventBase = dispatcher_GetEventScheduler(dispatcher);
- stream->bufferEventVector = parcEventQueue_Create(
- eventBase, fd,
- PARCEventQueueOption_CloseOnFree | PARCEventQueueOption_DeferCallbacks);
-
- stream->forwarder = forwarder;
- stream->interfaceName = NULL;
- stream->logger = logger_Acquire(forwarder_GetLogger(forwarder));
- stream->fd = fd;
- stream->id = forwarder_GetNextConnectionId(forwarder);
- stream->addressPair = pair;
- stream->isClosed = false;
-
-#ifdef WITH_POLICY
- stream->priority = 0;
-#endif /* WITH_POLICY */
-
- // allocate a connection
- IoOperations *io_ops = parcMemory_AllocateAndClear(sizeof(IoOperations));
- parcAssertNotNull(io_ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(IoOperations));
- memcpy(io_ops, &_template, sizeof(IoOperations));
- io_ops->closure = stream;
- stream->isLocal = isLocal;
-
- parcEventQueue_SetCallbacks(stream->bufferEventVector, _conn_readcb, NULL,
- _conn_eventcb, (void *)io_ops);
- parcEventQueue_Enable(stream->bufferEventVector, PARCEventType_Read);
-
- messenger_Send(forwarder_GetMessenger(stream->forwarder),
- missive_Create(MissiveType_ConnectionCreate, stream->id));
-
- // As we are acceting a connection, we begin in the UP state
- _setConnectionState(stream, true);
-
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- char *pair_str = addressPair_ToString(pair);
- logger_Log(stream->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "StreamConnection %p accept for address pair %s", (void *)stream,
- pair_str);
- free(pair_str);
- }
-
- return io_ops;
-}
-
-IoOperations *streamConnection_OpenConnection(Forwarder *forwarder,
- AddressPair *pair, bool isLocal) {
- parcAssertNotNull(forwarder, "Parameter hicn-light must be non-null");
- parcAssertNotNull(pair, "Parameter pair must be non-null");
-
- // if there's an error on the bind or connect, will return NULL
- PARCEventQueue *bufferEventVector =
- dispatcher_StreamBufferConnect(forwarder_GetDispatcher(forwarder), pair);
- if (bufferEventVector == NULL) {
- // error opening connection
- return NULL;
- }
-
- _StreamState *stream = parcMemory_AllocateAndClear(sizeof(_StreamState));
- parcAssertNotNull(stream, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(_StreamState));
-
- stream->forwarder = forwarder;
- stream->interfaceName = NULL;
- stream->logger = logger_Acquire(forwarder_GetLogger(forwarder));
- stream->fd = parcEventQueue_GetFileDescriptor(bufferEventVector);
- stream->bufferEventVector = bufferEventVector;
- stream->id = forwarder_GetNextConnectionId(forwarder);
- stream->addressPair = pair;
- stream->isClosed = false;
-
- // allocate a connection
- IoOperations *io_ops = parcMemory_AllocateAndClear(sizeof(IoOperations));
- parcAssertNotNull(io_ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(IoOperations));
- memcpy(io_ops, &_template, sizeof(IoOperations));
- io_ops->closure = stream;
- stream->isLocal = isLocal;
-
- parcEventQueue_SetCallbacks(stream->bufferEventVector, _conn_readcb, NULL,
- _conn_eventcb, (void *)io_ops);
- parcEventQueue_Enable(stream->bufferEventVector, PARCEventType_Read);
-
- // we start in DOWN state, until remote side answers
- messenger_Send(forwarder_GetMessenger(stream->forwarder),
- missive_Create(MissiveType_ConnectionCreate, stream->id));
- _setConnectionState(stream, false);
-
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO, PARCLogLevel_Info)) {
- char *pair_str = addressPair_ToString(pair);
- logger_Log(stream->logger, LoggerFacility_IO, PARCLogLevel_Info, __func__,
- "StreamConnection %p connect for address pair %s",
- (void *)stream, pair_str);
- free(pair_str);
- }
-
- return io_ops;
-}
-
-static void _streamConnection_DestroyOperations(IoOperations **opsPtr) {
- parcAssertNotNull(opsPtr, "Parameter opsPtr must be non-null double pointer");
- parcAssertNotNull(*opsPtr,
- "Parameter opsPtr must dereference to non-null pointer");
-
- IoOperations *ops = *opsPtr;
- parcAssertNotNull(ioOperations_GetClosure(ops),
- "ops->context must not be null");
-
- _StreamState *stream = (_StreamState *)ioOperations_GetClosure(ops);
-
- parcEventQueue_Destroy(&stream->bufferEventVector);
-
- addressPair_Release(&stream->addressPair);
-
- if (!stream->isClosed) {
- stream->isClosed = true;
- messenger_Send(forwarder_GetMessenger(stream->forwarder),
- missive_Create(MissiveType_ConnectionClosed, stream->id));
- }
-
- messenger_Send(forwarder_GetMessenger(stream->forwarder),
- missive_Create(MissiveType_ConnectionDestroyed, stream->id));
-
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO, PARCLogLevel_Info)) {
- logger_Log(stream->logger, LoggerFacility_IO, PARCLogLevel_Info, __func__,
- "StreamConnection %p destroyed", (void *)stream);
- }
-
- logger_Release(&stream->logger);
- parcMemory_Deallocate((void **)&stream);
- parcMemory_Deallocate((void **)&ops);
-
- *opsPtr = NULL;
-}
-
-static bool _streamConnection_IsUp(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _StreamState *stream =
- (const _StreamState *)ioOperations_GetClosure(ops);
- return stream->isUp;
-}
-
-static bool _streamConnection_IsLocal(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _StreamState *stream =
- (const _StreamState *)ioOperations_GetClosure(ops);
- return stream->isLocal;
-}
-
-static const Address *_streamConnection_GetRemoteAddress(
- const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _StreamState *stream =
- (const _StreamState *)ioOperations_GetClosure(ops);
- return addressPair_GetRemote(stream->addressPair);
-}
-
-static const AddressPair *_streamConnection_GetAddressPair(
- const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _StreamState *stream =
- (const _StreamState *)ioOperations_GetClosure(ops);
- return stream->addressPair;
-}
-
-static unsigned _streamConnection_GetConnectionId(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _StreamState *stream =
- (const _StreamState *)ioOperations_GetClosure(ops);
- return stream->id;
-}
-
-bool _streamConnection_SendIOVBuffer(IoOperations *ops,
- struct iovec * message, size_t size) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
-
- _StreamState *conn = (_StreamState *)ioOperations_GetClosure(ops);
-
- if (!conn->isUp) {
- if (logger_IsLoggable(conn->logger, LoggerFacility_IO,
- PARCLogLevel_Error)) {
- logger_Log(
- conn->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "connid %u tried to send to down connection (isUp %d isClosed %d)",
- conn->id, conn->isUp, conn->isClosed);
- }
- return false;
- }
-
- PARCEventBuffer *buffer =
- parcEventBuffer_GetQueueBufferOutput(conn->bufferEventVector);
- size_t buffer_backlog = parcEventBuffer_GetLength(buffer);
- parcEventBuffer_Destroy(&buffer);
-
- if (buffer_backlog >= OUTPUT_QUEUE_BYTES) {
- if (logger_IsLoggable(conn->logger, LoggerFacility_IO,
- PARCLogLevel_Warning)) {
- logger_Log(conn->logger, LoggerFacility_IO, PARCLogLevel_Warning,
- __func__,
- "connid %u Writing to buffer backlog %zu bytes DROP MESSAGE",
- conn->id, buffer_backlog);
- }
- return false;
- }
-
- if (logger_IsLoggable(conn->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- size_t length = 0;
- for (int i = 0; i < size; i++)
- length += message[i].iov_len;
-
- logger_Log( conn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "connid %u Writing %zu bytes to buffer with backlog %zu bytes",
- conn->id, length, buffer_backlog);
- }
-
- /* Write directly into the parcEventQueue without passing through message */
- for (int i = 0; i < size; i++) {
- if (parcEventQueue_Write(conn->bufferEventVector, message[i].iov_base,
- message[i].iov_len) != 0)
- return false;
- }
-
- return true;
-}
-
-/**
- * @function streamConnection_Send
- * @abstract Non-destructive send of the message.
- * @discussion
- * Send uses message_CopyToStreamBuffer, which is a non-destructive write.
- * The send may fail if there's no buffer space in the output queue.
- *
- * @param dummy is ignored. A stream has only one peer.
- * @return <#return#>
- */
-static bool _streamConnection_Send(IoOperations *ops, const Address *dummy,
- Message *message) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
- _StreamState *stream = (_StreamState *)ioOperations_GetClosure(ops);
-
- bool success = false;
- if (stream->isUp) {
- PARCEventBuffer *buffer =
- parcEventBuffer_GetQueueBufferOutput(stream->bufferEventVector);
- size_t buffer_backlog = parcEventBuffer_GetLength(buffer);
- parcEventBuffer_Destroy(&buffer);
-
- if (buffer_backlog < OUTPUT_QUEUE_BYTES) {
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO,
- PARCLogLevel_Debug)) {
- logger_Log(
- stream->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "connid %u Writing %zu bytes to buffer with backlog %zu bytes",
- stream->id, message_Length(message), buffer_backlog);
- }
-
- int failure = message_Write(stream->bufferEventVector, message);
- if (failure == 0) {
- success = true;
- }
- } else {
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO,
- PARCLogLevel_Warning)) {
- logger_Log(stream->logger, LoggerFacility_IO, PARCLogLevel_Warning,
- __func__,
- "connid %u Writing to buffer backlog %zu bytes DROP MESSAGE",
- stream->id, buffer_backlog);
- }
- }
- } else {
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO,
- PARCLogLevel_Error)) {
- logger_Log(
- stream->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "connid %u tried to send to down connection (isUp %d isClosed %d)",
- stream->id, stream->isUp, stream->isClosed);
- }
- }
-
- return success;
-}
-
-list_connections_type _streamConnection_GetConnectionType(
- const IoOperations *ops) {
- return CONN_TCP;
-}
-
-static void _sendProbe(IoOperations *ops, uint8_t *message) {
- // we don't need to implemet this here, it is a local connection
-}
-
-// =================================================================
-// the actual I/O functions
-
-int _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);
- // read first byte of the header
-
- // first byte: must be a REQUEST_LIGHT
- if (msg[0] != REQUEST_LIGHT) {
- return LAST_COMMAND_VALUE;
- }
-
- // second byte: must be a command_id
- if (msg[1] < 0 || msg[1] >= LAST_COMMAND_VALUE) {
- return LAST_COMMAND_VALUE;
- }
-
- return msg[1];
-}
-
-PARCEventBuffer *_tryReadControlMessage(_StreamState *stream,
- PARCEventBuffer *input,
- command_id command,
- struct iovec **request) {
- size_t bytesAvailable = parcEventBuffer_GetLength(input);
-
- if (stream->nextMessageLength == 0) {
- stream->nextMessageLength =
- sizeof(header_control_message) +
- payloadLengthDaemon(command); // consider the whole packet.
- }
-
- if (bytesAvailable >= stream->nextMessageLength) {
- PARCEventBuffer *message = parcEventBuffer_Create();
- int bytesRead = parcEventBuffer_ReadIntoBuffer(input, message,
- stream->nextMessageLength);
- parcAssertTrue(bytesRead == stream->nextMessageLength,
- "Partial read, expected %zu got %d",
- stream->nextMessageLength, bytesRead);
-
- uint8_t *control =
- parcEventBuffer_Pullup(message, stream->nextMessageLength);
- if (!(*request = (struct iovec *)parcMemory_AllocateAndClear(
- sizeof(struct iovec) * 2))) {
- return NULL;
- }
- (*request)[0].iov_base = control; // header
- (*request)[0].iov_len = sizeof(header_control_message);
- if (payloadLengthDaemon(command) > 0) {
- (*request)[1].iov_base =
- control + sizeof(header_control_message); // payload
- } else {
- (*request)[1].iov_base = NULL;
- }
- (*request)[1].iov_len = payloadLengthDaemon(command);
- // now reset message length for next packet
-
- stream->nextMessageLength = 0;
-
- return message;
- }
-
- return NULL;
-}
-
-static bool _isAnHicnPacket(PARCEventBuffer *input) {
- size_t bytesAvailable = parcEventBuffer_GetLength(input);
- parcAssertTrue(bytesAvailable >= sizeof(header_control_message),
- "Called with too short an input: %zu", bytesAvailable);
-
- uint8_t *fh = parcEventBuffer_Pullup(input, sizeof(header_control_message));
- return messageHandler_IsValidHicnPacket(fh);
-}
-
-static Message *_readMessage(_StreamState *stream, Ticks time,
- PARCEventBuffer *input) {
- Message *message = message_CreateFromEventBuffer(
- input, stream->nextMessageLength, stream->id, time, stream->logger);
-
- return message;
-}
-
-static void _startNewMessage(_StreamState *stream, PARCEventBuffer *input,
- size_t inputBytesAvailable) {
- parcAssertTrue(stream->nextMessageLength == 0,
- "Invalid state, nextMessageLength not zero: %zu",
- stream->nextMessageLength);
- parcAssertTrue(inputBytesAvailable >= sizeof(header_control_message),
- "read_length not a whole fixed header!: %zd",
- inputBytesAvailable);
-
- // this linearizes the first messageHandler_GetIPv6HeaderLength() bytes of the
- // input buffer's iovecs and returns a pointer to it.
- uint8_t *fh = parcEventBuffer_Pullup(input, sizeof(header_control_message));
-
- // Calculate the total message size based on the fixed header
- stream->nextMessageLength = messageHandler_GetTotalPacketLength(fh);
-}
-
-static Message *_tryReadMessage(PARCEventBuffer *input, _StreamState *stream) {
- size_t bytesAvailable = parcEventBuffer_GetLength(input);
- parcAssertTrue(bytesAvailable >= sizeof(header_control_message),
- "Called with too short an input: %zu", bytesAvailable);
-
- if (stream->nextMessageLength == 0) {
- _startNewMessage(stream, input, bytesAvailable);
- }
-
- // This is not an ELSE statement. We can both start a new message then
- // check if there's enough bytes to read the whole thing.
-
- if (bytesAvailable >= stream->nextMessageLength) {
- Message *message =
- _readMessage(stream, forwarder_GetTicks(stream->forwarder), input);
-
- // now reset message length for next packet
- stream->nextMessageLength = 0;
-
- return message;
- }
-
- return NULL;
-}
-
-/**
- * @function conn_readcb
- * @abstract Event callback for reads
- * @discussion
- * Will read messages off the input. Continues reading as long as we
- * can get a header to determine the next message length or as long as we
- * can read a complete message.
- *
- * This function manipulates the read low water mark. (1) read a fixed header
- * plus complete message, then set the low water mark to FIXED_HEADER_LEN. (2)
- * read a fixed header, but not a complete message, then set low water mark to
- * the total mesage length. Using the low water mark like this means the buffer
- * event will only trigger on meaningful byte boundaries when we can get actual
- * work done.
- *
- * @param <#param1#>
- * @return <#return#>
- */
-static void _conn_readcb(PARCEventQueue *event, PARCEventType type,
- void *ioOpsVoid) {
- command_id command;
- IoOperations *ops = (IoOperations *)ioOpsVoid;
- _StreamState *stream = (_StreamState *)ioOperations_GetClosure(ops);
-
- PARCEventBuffer *input = parcEventBuffer_GetQueueBufferInput(event);
-
- // drain the input buffer
-
- // notice that we always try to read at least 8 bytes
- // (sizeof(header_control_message)). This is enough to read the length of all
- // kind of packets
- while (parcEventBuffer_GetLength(input) >= sizeof(header_control_message) &&
- parcEventBuffer_GetLength(input) >= stream->nextMessageLength) {
-
- if ((command = _isACommand(input)) != LAST_COMMAND_VALUE) {
- struct iovec *rx;
- // Get message from the stream and set the stream->nextMessageLength
- PARCEventBuffer *message =
- _tryReadControlMessage(stream, input, command, &rx);
- // If received correctly the whole message, send to dispatcher
- if (message) {
- forwarder_ReceiveCommand(stream->forwarder, command, rx, stream->id);
- parcMemory_Deallocate((void **)&rx);
- parcEventBuffer_Destroy(&message);
- }
-
- } else if (_isAnHicnPacket(input)) {
- // this is an Hicn packet (here we should distinguish between IPv4 and
- // IPv6 tryReadMessage may set nextMessageLength
- Message *message = _tryReadMessage(input, stream);
-
- if (message) {
- forwarder_Receive(stream->forwarder, message);
- }
-
- } else {
- parcAssertTrue(false,
- "(Local stream connection) malformed packet received");
- }
- }
-
- if (stream->nextMessageLength == 0) {
- // we don't have the next header, so set it to the header length
- streamBuffer_SetWatermark(event, true, false,
- sizeof(header_control_message), 0);
- } else {
- // set it to the packet length
- streamBuffer_SetWatermark(event, true, false, stream->nextMessageLength, 0);
- }
- parcEventBuffer_Destroy(&input);
-}
-
-static void _setConnectionState(_StreamState *stream, bool isUp) {
- parcAssertNotNull(stream, "Parameter stream must be non-null");
-
- Messenger *messenger = forwarder_GetMessenger(stream->forwarder);
-
- bool oldStateIsUp = stream->isUp;
- stream->isUp = isUp;
-
- if (oldStateIsUp && !isUp) {
- // bring connection DOWN
- Missive *missive = missive_Create(MissiveType_ConnectionDown, stream->id);
- messenger_Send(messenger, missive);
- return;
- }
-
- if (!oldStateIsUp && isUp) {
- // bring connection UP
- Missive *missive = missive_Create(MissiveType_ConnectionUp, stream->id);
- messenger_Send(messenger, missive);
- return;
- }
-}
-
-static void _conn_eventcb(PARCEventQueue *event, PARCEventQueueEventType events,
- void *ioOpsVoid) {
- IoOperations *ops = (IoOperations *)ioOpsVoid;
- _StreamState *stream = (_StreamState *)ioOperations_GetClosure(ops);
-
- if (events & PARCEventQueueEventType_Connected) {
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO,
- PARCLogLevel_Info)) {
- logger_Log(stream->logger, LoggerFacility_IO, PARCLogLevel_Info, __func__,
- "Connection %u is connected", stream->id);
- }
-
- // if the stream was closed, do not transition to an UP state
- if (!stream->isClosed) {
- _setConnectionState(stream, true);
- }
- } else if (events & PARCEventQueueEventType_EOF) {
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO,
- PARCLogLevel_Info)) {
- logger_Log(stream->logger, LoggerFacility_IO, PARCLogLevel_Info, __func__,
- "connid %u closed.", stream->id);
- }
-
- parcEventQueue_Disable(stream->bufferEventVector, PARCEventType_Read);
-
- _setConnectionState(stream, false);
-
- if (!stream->isClosed) {
- stream->isClosed = true;
- // this will cause the connection manager to destroy the connection later
- messenger_Send(forwarder_GetMessenger(stream->forwarder),
- missive_Create(MissiveType_ConnectionClosed, stream->id));
- }
- } else if (events & PARCEventQueueEventType_Error) {
- if (logger_IsLoggable(stream->logger, LoggerFacility_IO,
- PARCLogLevel_Error)) {
- logger_Log(stream->logger, LoggerFacility_IO, PARCLogLevel_Error,
- __func__, "Got an error on the connection %u: %s", stream->id,
- strerror(errno));
- }
-
- parcEventQueue_Disable(stream->bufferEventVector,
- PARCEventType_Read | PARCEventType_Write);
-
- _setConnectionState(stream, false);
-
- if (!stream->isClosed) {
- stream->isClosed = true;
- // this will cause the connection manager to destroy the connection later
- messenger_Send(forwarder_GetMessenger(stream->forwarder),
- missive_Create(MissiveType_ConnectionClosed, stream->id));
- }
- }
- /* 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;
-}
-
-#ifdef WITH_POLICY
-static uint32_t _streamConnection_getPriority(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _StreamState *stream =
- (const _StreamState *)ioOperations_GetClosure(ops);
- return stream->priority;
-}
-
-static void _streamConnection_setPriority(IoOperations *ops, uint32_t priority) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- _StreamState *stream =
- (_StreamState *)ioOperations_GetClosure(ops);
- stream->priority = priority;
-}
-#endif /* WITH_POLICY */
-
-static const char * _streamConnection_getInterfaceName(const IoOperations *ops)
-{
- parcAssertNotNull(ops, "Parameter must be non-null");
- _StreamState *stream =
- (_StreamState *)ioOperations_GetClosure(ops);
- return stream->interfaceName;
-}
diff --git a/hicn-light/src/hicn/io/streamConnection.h b/hicn-light/src/hicn/io/streamConnection.h
deleted file mode 100644
index f483d0b82..000000000
--- a/hicn-light/src/hicn/io/streamConnection.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Methods common to TCP and PF_LOCAL stream-based listeners
- */
-
-#ifndef streamConnection_h
-#define streamConnection_h
-
-#include <hicn/core/forwarder.h>
-#include <hicn/core/messagePacketType.h>
-#include <hicn/io/addressPair.h>
-#include <hicn/io/ioOperations.h>
-#include <hicn/utils/address.h>
-
-/**
- * @function streamConnection_AcceptConnection
- * @abstract Receive a connection from a remote peer
- * @discussion
- * We are the "server side" of the stream connection, so we need to accept the
- * client connection and setup state for her.
- *
- * @param <#param1#>
- * @return <#return#>
- */
-IoOperations *streamConnection_AcceptConnection(Forwarder *forwarder, int fd,
- AddressPair *pair,
- bool isLocal);
-
-/**
- * @function streamConnection_OpenConnection
- * @abstract Initiate a connection to a remote peer
- * @discussion
- * We are the "client side" of the stream connection. We'll create state for
- * the peer, but it will be in the "down" state until the connection
- * establishes.
- *
- * For TCP, both address pairs need to be the same address family: both INET
- * or both INET6. The remote address must have the complete socket information
- * (address, port). The local socket could be wildcarded or may specify down to
- * the (address, port) pair.
- *
- * If the local address is IPADDR_ANY and the port is 0, then it is a normal
- * call to "connect" that will use whatever local IP address and whatever local
- * port for the connection. If either the address or port is set, the local
- * socket will first be bound (via bind(2)), and then call connect().
- *
- * AF_UNIX is not yet supported
- *
- * If there's an error binding to the specified address or connecting to the
- * remote address, will return NULL.
- *
- * @param pair (takes ownership of this) is the complete socket pair of
- * (address, port) for each end, if INET or INET6.
- * @return NULL on error, otherwise the connections IO operations.
- */
-IoOperations *streamConnection_OpenConnection(Forwarder *forwarder,
- AddressPair *pair, bool isLocal);
-
-bool streamState_SendIOVBuffer(IoOperations *ops, struct iovec *response,
- size_t size);
-
-#endif // streamConnection_h
diff --git a/hicn-light/src/hicn/io/tcp.c b/hicn-light/src/hicn/io/tcp.c
new file mode 100644
index 000000000..03911e556
--- /dev/null
+++ b/hicn-light/src/hicn/io/tcp.c
@@ -0,0 +1,563 @@
+/*
+ * 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.
+ */
+
+/**
+ * Common activity for STREAM based listeners.
+ */
+
+#include <errno.h>
+#ifndef _WIN32
+#include <unistd.h> // fcntl
+#endif /* _WIN32 */
+#include <fcntl.h> // fcntl
+#include <hicn/hicn-light/config.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <hicn/core/connection.h>
+#include <hicn/core/connection_vft.h>
+#include <hicn/core/listener.h>
+#include <hicn/core/listener_vft.h>
+#include <hicn/core/msgbuf.h>
+#include <hicn/core/forwarder.h>
+
+#include <hicn/core/messageHandler.h>
+
+#include <hicn/utils/commands.h>
+#include <hicn/util/log.h>
+
+#include <hicn/hicn.h>
+// 128 KB output queue
+#define OUTPUT_QUEUE_BYTES (128 * 1024)
+
+#define RECV_BUFLEN 8192
+#define MTU 1500
+
+// XXX TODO what is exactly an eventqueue
+// XXX TODO can't we write directly to the socket ?
+
+/******************************************************************************
+ * Listener
+ ******************************************************************************/
+
+typedef struct {
+} listener_tcp_data_t;
+
+static
+int
+listener_tcp_initialize(listener_t * listener)
+{
+
+ ERROR("[listener_tcp_initialize] Not implemented");
+
+ return 0;
+}
+
+static
+void
+listener_tcp_finalize(listener_t * listener)
+{
+
+ ERROR("[listener_tcp_finalize] Not implemented");
+}
+
+static
+int
+listener_tcp_punt(const listener_t * listener, const char * prefix_s)
+{
+ ERROR("[listener_tcp_punt] Not implemented");
+ return -1;
+}
+
+static
+int
+listener_tcp_get_socket(const listener_t * listener, const address_t * local,
+ const address_t * remote, const char * interface_name)
+{
+
+ ERROR("[listener_tcp_get_socket] Not implemented");
+ return -1;
+
+}
+
+static
+void
+listener_tcp_read_callback(listener_t * listener, int fd, void * data)
+{
+ ERROR("[listener_tcp_read_callback] Not implemented");
+
+}
+
+DECLARE_LISTENER(tcp);
+
+/******************************************************************************
+ * Connection
+ ******************************************************************************/
+
+
+typedef struct {
+ /* Partial receive buffer */
+ u8 buf[RECV_BUFLEN];
+ size_t roff; /**< Read offset */
+ size_t woff; /**< Write offset */
+
+
+ // XXX this should be initialized with the header length, and tells what we
+ // expect to receive next...
+ size_t next_len;
+ struct bufferevent * bufferevent;
+} connection_tcp_data_t;
+
+// XXX This seems more a listener code !
+// XXX we must have accept to the connection table to spawn new ones !!
+// XXX equivalent to initialize
+int
+connection_tcp_accept(connection_t * connection, forwarder_t *forwarder, int fd,
+ address_pair_t *pair, bool local, unsigned connection_id)
+{
+ assert(connection);
+ assert(forwarder);
+
+ *connection = (connection_t) {
+ .id = connection_id,
+ .interface_name = NULL,
+ .type = FACE_TYPE_TCP,
+ .pair = *pair,
+ .fd = fd,
+ .local = local,
+ // As we are accepting a connection, we begin in the UP state
+ .state = FACE_STATE_UP,
+ .admin_state = FACE_STATE_UP,
+#ifdef WITH_POLICY
+ .priority = 0,
+#endif /* WITH_POLICY */
+
+ .forwarder = forwarder,
+ .closed = false,
+ };
+
+ // XXX this new connection needs to be registered
+ //char *str = pair_ToString(udp->pair);
+ INFO("%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;
+}
+
+int
+make_socket(address_pair_t * pair)
+{
+#ifndef _WIN32
+ int fd = socket(address_family(&pair->local), SOCK_STREAM, 0);
+ if (fd < 0) {
+ perror("socket");
+ goto ERR_SOCKET;
+ }
+#else
+ SOCKET fd = socket(address_family(&pair->local), SOCK_STREAM, 0);
+ if (fd == INVALID_SOCKET) {
+ perror("socket");
+ goto ERR_SOCKET;
+ }
+#endif /* _WIN32 */
+
+ /* Set non-blocking flag */
+#ifndef _WIN32
+ int flags = fcntl(fd, F_GETFL, NULL);
+ if (flags == -1) {
+ perror("F_GETFL");
+ goto ERR;
+ }
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+ perror("F_SETFL");
+ goto ERR;
+ }
+#else
+ if (ioctlsocket(fd, FIONBIO, &(u_long){1}) != NO_ERROR) {
+ perror("ioctlsocket");
+ goto ERR;
+ }
+#endif /* _WIN32 */
+
+ if (bind(fd, address_sa(&pair->local), address_socklen(&pair->local)) == -1) {
+ perror("bind");
+ goto ERR;
+ }
+
+ if (connect(fd, address_sa(&pair->remote), address_socklen(&pair->remote)) < 0) {
+ perror("connect");
+ goto ERR;
+ }
+
+
+ return 0;
+
+ERR:
+#ifndef _WIN32
+ close(fd);
+#else
+ closesocket(fd);
+#endif
+
+ERR_SOCKET:
+ return -1;
+
+}
+
+static
+int
+connection_tcp_initialize(connection_t * connection)
+{
+ assert(connection);
+ assert(connection->type = FACE_TYPE_TCP);
+
+ connection_tcp_data_t * data = connection->data;
+ assert(data);
+
+ data->roff = 0;
+ data->woff = 0;
+
+ connection->fd = make_socket(connection_get_pair(connection));
+ if (connection->fd < 0) {
+ ERROR("Error creating TCP socket");
+ return -1;
+ }
+
+ //char *pair_str = address_pair_ToString(pair);
+ INFO("%s connection %p connect for address pair %s",
+ face_type_str(connection->type), connection, "N/A");
+ //free(pair_str);
+
+ return 0;
+}
+
+// XXX a part needs to be handled in the connection.c
+static
+void
+connection_tcp_finalize(connection_t * connection)
+{
+ if (!connection->closed) {
+ connection->closed = true;
+ // XXX need to delete the connection like previously in the connection
+ // manager
+ }
+
+ INFO("%s connection %p destroyed", face_type_str(connection->type),
+ connection);
+ // XXX need to release the "connection"
+}
+
+#if 0
+static
+bool
+connection_tcp_sendv(connnection_t * connection, struct iovec * iov,
+ size_t size)
+{
+ assert(connection);
+ assert(iov);
+
+ if (!connection_is_up(connection)) {
+ ERROR("Connection #%u tried to send to down connection (up=%d closed=%d)",
+ connection_get_id(connection),
+ connection_get_up(connection) ? "true" : "false",
+ connection_get_closed(connection) ? "true" : "false");
+ return false;
+ }
+
+ PARCEventBuffer *buffer =
+ parcEventBuffer_GetQueueBufferOutput(connection->events);
+ size_t buffer_backlog = parcEventBuffer_GetLength(buffer);
+ parcEventBuffer_Destroy(&buffer);
+
+ if (buffer_backlog >= OUTPUT_QUEUE_BYTES) {
+ WARN("Connection #%u Writing to buffer backlog %zu bytes DROP MESSAGE",
+ connection_get_id(connection), buffer_backlog);
+ return false;
+ }
+
+#if 0
+ /* DEBUG */
+ size_t length = 0;
+ for (int i = 0; i < size; i++)
+ length += message[i].iov_len;
+ DEBUG("Connection #%u writing %zu bytes to buffer with backlog %zu bytes",
+ connection_get_id(connection), length, buffer_backlog);
+#endif
+
+ /* Write directly into the parcEventQueue without passing through message */
+ for (int i = 0; i < size; i++) {
+ if (parcEventQueue_Write(conn->events, iov[i].iov_base,
+ iov[i].iov_len) != 0)
+ return false;
+ }
+
+ return true;
+}
+#endif
+
+/**
+ * @function streamConnection_Send
+ * @abstract Non-destructive send of the message.
+ * @discussion
+ * Send uses message_CopyToStreamBuffer, which is a non-destructive write.
+ * The send may fail if there's no buffer space in the output queue.
+ *
+ * @param dummy is ignored. A stream has only one peer.
+ * @return <#return#>
+ */
+// XXX address not used anywhere
+// XXX too much repeated code with sendv here
+static
+int
+connection_tcp_send(const connection_t * connection, //const address_t * address,
+ msgbuf_t * msgbuf, bool queue)
+{
+ assert(connection);
+ assert(address);
+ /* msgbuf can be NULL */
+
+ /* No need to flush */
+ if (!msgbuf)
+ return true;
+
+ if (!connection_is_up(connection)) {
+ ERROR("Connection #%u tried to send to down connection (up=%d closed=%d)",
+ connection_get_id(connection),
+ connection_is_up(connection) ? "true" : "false",
+ connection_is_closed(connection) ? "true" : "false");
+ return false;
+ }
+
+ // XXX TODO write to fd
+#if 0
+ PARCEventBuffer *buffer =
+ parcEventBuffer_GetQueueBufferOutput(connection->events);
+ size_t buffer_backlog = parcEventBuffer_GetLength(buffer);
+ parcEventBuffer_Destroy(&buffer);
+
+ if (buffer_backlog >= OUTPUT_QUEUE_BYTES) {
+ WARN("Connection #%u Writing to buffer backlog %zu bytes DROP MESSAGE",
+ connection_get_id(connection), buffer_backlog);
+ return false;
+ }
+
+ DEBUG("Connection #%u Writing %zu bytes to buffer with backlog %zu bytes",
+ connection_get_id(connection), msgbuf_len(message), buffer_backlog);
+
+ return (parcEventQueue_Write(connection->events, msgbuf_packet(message),
+ msgbuf_len(message)) == 0);
+#endif
+ return true;
+}
+
+static
+int
+connection_tcp_send_packet(const connection_t * connection,
+ const uint8_t * packet, size_t size)
+{
+ /* Not implemented for local connections */
+ // XXX shall we set the pointer to NULL and add a check ?
+
+ ERROR("[connection_tcp_send_packet] Not implemented");
+
+ return -1;
+}
+
+// =================================================================
+// the actual I/O functions
+
+// not needed anymore ?
+#if 0
+// XXX this is called iif there is sufficient data to read, otherwise it raises
+// an assertion error. This was a problem before I guess
+static
+int
+connection_tcp_read_message(connection_t * connection, msgbuf_t * msgbuf)
+{
+ assert(connection);
+ assert(msgbuf);
+
+ connection_tcp_data_t * data = connection->data;
+ assert(data);
+
+ size_t n = evbuffer_get_length(data->evbuffer);
+ // XXX this check was wrong
+ // parcAssertTrue(n >= sizeof(header_control_message),
+ "Called with too short an input: %zu", n);
+
+ // XXX WTF
+ if (stream->next_len == 0) {
+ // this linearizes the first messageHandler_GetIPv6HeaderLength() bytes of the
+ // input buffer's iovecs and returns a pointer to it.
+ uint8_t *fh = parcEventBuffer_Pullup(data->evbuffer, sizeof(header_control_message));
+
+ // Calculate the total message size based on the fixed header
+ stream->next_len = messageHandler_GetTotalPacketLength(fh);
+ }
+ // This is not an ELSE statement. We can both start a new message then
+ // check if there's enough bytes to read the whole thing.
+
+ if (n < stream->next_len)
+ return -1;
+
+ uint8_t packet_type;
+ if (messageHandler_IsInterest(packet)) {
+ packet_type = MESSAGE_TYPE_INTEREST;
+ } else if (messageHandler_IsData(packet)) {
+ packet_type = MESSAGE_TYPE_DATA;
+ } else {
+ ERROR("Dropped packet that is not interest nor data");
+ goto ERR;
+ }
+
+ if (evbuffer_remove(data->evbuffer, data->packet, data->next_len) < 0)
+ return -1;
+
+ msgbuf_from_packet(msgbuf, data->packet, packet_type, stream->id,
+ ticks_now());
+
+ // now reset message length for next packet
+ data->next_len = 0;
+ return 0;
+
+ERR:
+ evbuffer_drain(data->evbuffer, data->next_len);
+ return -1;
+}
+#endif
+
+/**
+ * @function conn_readcb
+ * @abstract Event callback for reads
+ * @discussion
+ * Will read messages off the input. Continues reading as long as we
+ * can get a header to determine the next message length or as long as we
+ * can read a complete message.
+ *
+ * This function manipulates the read low water mark. (1) read a fixed header
+ * plus complete message, then set the low water mark to FIXED_HEADER_LEN. (2)
+ * read a fixed header, but not a complete message, then set low water mark to
+ * the total mesage length. Using the low water mark like this means the buffer
+ * event will only trigger on meaningful byte boundaries when we can get actual
+ * work done.
+ *
+ * @param <#param1#>
+ * @return <#return#>
+ */
+static
+void
+connection_tcp_read_callback(connection_t * connection, int fd, void * user_data)
+{
+ assert(!!(what & PARCEventType_Read));
+ assert(connection_void);
+
+ connection_tcp_data_t * data = connection->data;
+ assert(RECV_BUFLEN - data->woff > MTU);
+
+ /* No batching here as code is not expected to receive much throughput */
+ for (;;) {
+ ssize_t n = recv(connection->fd, data->buf + data->woff,
+ RECV_BUFLEN - data->woff, 0);
+ if (n == 0) /* EOF */
+ return; // XXX close connection
+ if (n < 0) {
+ if (errno == EWOULDBLOCK)
+ break;
+ perror("recv");
+ return; // XXX close connection
+ }
+ data->woff += n;
+
+ /* Process */
+ uint8_t * packet = data->buf + data->roff;
+ size_t size = data->woff - data->roff; /* > 0 */
+
+ ssize_t used = listener_read_callback(connection->forwarder, NULL, fd,
+ address_pair_get_local(&connection->pair), packet, size);
+ if (used < 0)
+ return; // XXX close connection ?
+ if (used == 0)
+ break; /* We would have received more if there was still packets to be read */
+ data->roff += used;
+ assert(data->roff <= data->woff);
+
+ if (data->roff == data->woff) {
+ /* Reset state whenever possible to avoid memcpy's */
+ data->roff = 0;
+ data->woff = 0;
+ return;
+ }
+ }
+
+ /* Make sure there is enough remaining space in the buffer */
+ if (RECV_BUFLEN - data->woff < MTU) {
+ /*
+ * There should be no overlap provided a sufficiently large BUFLEN, but
+ * who knows.
+ */
+ memmove(data->buf, data->buf + data->roff, data->woff - data->roff);
+ data->woff -= data->roff;
+ data->roff = 0;
+ }
+
+ return;
+}
+
+#if 0
+static
+void
+connection_tcp_callback(connection_t * connection, int fd, void * user_data)
+{
+ if (events & PARCEventQueueEventType_Connected) {
+ INFO("Connection %u is connected", stream->id);
+
+ // if the stream was closed, do not transition to an UP state
+ if (!stream->isClosed) {
+ _setConnectionState(stream, true);
+ }
+ } else if (events & PARCEventQueueEventType_EOF) {
+ INFO("connid %u closed.", stream->id);
+
+ parcEventQueue_Disable(stream->events, PARCEventType_Read);
+
+ _setConnectionState(stream, false);
+
+ if (!stream->isClosed) {
+ stream->isClosed = true;
+ // XXX TODO destroy the connection
+ }
+ } else if (events & PARCEventQueueEventType_Error) {
+ ERROR("Got an error on the connection %u: %s", stream->id,
+ strerror(errno));
+
+ parcEventQueue_Disable(stream->events,
+ PARCEventType_Read | PARCEventType_Write);
+
+ _setConnectionState(stream, false);
+
+ if (!stream->isClosed) {
+ stream->isClosed = true;
+ // XXX TODO destroy the connection
+ }
+ }
+ /* None of the other events can happen here, since we haven't enabled
+ * timeouts */
+}
+#endif
+
+DECLARE_CONNECTION(tcp)
diff --git a/hicn-light/src/hicn/io/tcpListener.c b/hicn-light/src/hicn/io/tcpListener.c
deleted file mode 100644
index e2b80c215..000000000
--- a/hicn-light/src/hicn/io/tcpListener.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <hicn/hicn-light/config.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <hicn/core/connectionTable.h>
-#include <hicn/core/forwarder.h>
-#include <hicn/io/listener.h>
-#include <hicn/io/streamConnection.h>
-#include <hicn/io/tcpListener.h>
-
-#include <parc/algol/parc_Memory.h>
-#include <parc/algol/parc_Network.h>
-#include <parc/assert/parc_Assert.h>
-
-typedef struct tcp_listener {
- char *listenerName;
- Forwarder *forwarder;
- Logger *logger;
-
- PARCEventSocket *listener;
-
- Address *localAddress;
-
- unsigned id;
- char *interfaceName;
-
- // is the localAddress as 127.0.0.0 address?
- bool isLocalAddressLocal;
-} _TcpListener;
-
-static void _tcpListener_Destroy(_TcpListener **listenerPtr);
-
-static void _tcpListener_OpsDestroy(ListenerOps **listenerOpsPtr);
-
-static const char *_tcpListener_ListenerName(const ListenerOps *ops);
-
-static unsigned _tcpListener_OpsGetInterfaceIndex(const ListenerOps *ops);
-
-static const Address *_tcpListener_OpsGetListenAddress(const ListenerOps *ops);
-
-static const char *_tcpListener_InterfaceName(const ListenerOps *ops);
-
-static EncapType _tcpListener_OpsGetEncapType(const ListenerOps *ops);
-
-static ListenerOps _tcpTemplate = {
- .context = NULL,
- .destroy = &_tcpListener_OpsDestroy,
- .getListenerName = &_tcpListener_ListenerName,
- .getInterfaceIndex = &_tcpListener_OpsGetInterfaceIndex,
- .getListenAddress = &_tcpListener_OpsGetListenAddress,
- .getEncapType = &_tcpListener_OpsGetEncapType,
- .getInterfaceName = &_tcpListener_InterfaceName,
- .getSocket = NULL};
-
-// STREAM daemon listener callback
-static void _tcpListener_Listen(int, struct sockaddr *, int socklen,
- void *tcpVoid);
-
-ListenerOps *tcpListener_CreateInet6(Forwarder *forwarder, char *listenerName,
- struct sockaddr_in6 sin6, char *interfaceName) {
-
- _TcpListener *tcp = parcMemory_AllocateAndClear(sizeof(_TcpListener));
- parcAssertNotNull(tcp, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(_TcpListener));
-
- tcp->forwarder = forwarder;
- tcp->listenerName = parcMemory_StringDuplicate(listenerName, strlen(listenerName));
- tcp->logger = logger_Acquire(forwarder_GetLogger(forwarder));
- tcp->interfaceName = parcMemory_StringDuplicate(interfaceName, strlen(interfaceName));
-
- tcp->listener = dispatcher_CreateListener(
- forwarder_GetDispatcher(forwarder), _tcpListener_Listen, (void *)tcp, -1,
- (struct sockaddr *)&sin6, sizeof(sin6));
-
- if (tcp->listener == NULL) {
- logger_Log(tcp->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "dispatcher_CreateListener failed to create listener (%d) %s",
- errno, strerror(errno));
- logger_Release(&tcp->logger);
- parcMemory_Deallocate((void **)&tcp);
- return NULL;
- }
-
- tcp->localAddress = addressCreateFromInet6(&sin6);
- tcp->id = forwarder_GetNextConnectionId(forwarder);
- tcp->isLocalAddressLocal =
- parcNetwork_IsSocketLocal((struct sockaddr *)&sin6);
-
- ListenerOps *ops = parcMemory_AllocateAndClear(sizeof(ListenerOps));
- parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(ListenerOps));
-
- memcpy(ops, &_tcpTemplate, sizeof(ListenerOps));
- ops->context = tcp;
-
- if (logger_IsLoggable(tcp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- char *str = addressToString(tcp->localAddress);
- logger_Log(tcp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "TcpListener %p created for address %s (isLocal %d)",
- (void *)tcp, str, tcp->isLocalAddressLocal);
- parcMemory_Deallocate((void **)&str);
- }
-
- return ops;
-}
-
-ListenerOps *tcpListener_CreateInet(Forwarder *forwarder, char *listenerName,
- struct sockaddr_in sin, char *interfaceName) {
- _TcpListener *tcp = parcMemory_AllocateAndClear(sizeof(_TcpListener));
- parcAssertNotNull(tcp, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(_TcpListener));
-
- tcp->forwarder = forwarder;
- tcp->listenerName = parcMemory_StringDuplicate(listenerName, strlen(listenerName));
- tcp->logger = logger_Acquire(forwarder_GetLogger(forwarder));
- tcp->interfaceName = parcMemory_StringDuplicate(interfaceName, strlen(interfaceName));
-
- tcp->listener = dispatcher_CreateListener(
- forwarder_GetDispatcher(forwarder), _tcpListener_Listen, (void *)tcp, -1,
- (struct sockaddr *)&sin, sizeof(sin));
-
- if (tcp->listener == NULL) {
- logger_Log(tcp->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "dispatcher_CreateListener failed to create listener (%d) %s",
- errno, strerror(errno));
-
- logger_Release(&tcp->logger);
- parcMemory_Deallocate((void **)&tcp);
- return NULL;
- }
-
- tcp->localAddress = addressCreateFromInet(&sin);
- tcp->id = forwarder_GetNextConnectionId(forwarder);
- tcp->isLocalAddressLocal = parcNetwork_IsSocketLocal((struct sockaddr *)&sin);
-
- ListenerOps *ops = parcMemory_AllocateAndClear(sizeof(ListenerOps));
- parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(ListenerOps));
-
- memcpy(ops, &_tcpTemplate, sizeof(ListenerOps));
- ops->context = tcp;
-
- if (logger_IsLoggable(tcp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- char *str = addressToString(tcp->localAddress);
- logger_Log(tcp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "TcpListener %p created for address %s (isLocal %d)",
- (void *)tcp, str, tcp->isLocalAddressLocal);
- parcMemory_Deallocate((void **)&str);
- }
-
- return ops;
-}
-
-static void _tcpListener_Destroy(_TcpListener **listenerPtr) {
- parcAssertNotNull(listenerPtr, "Parameter must be non-null double pointer");
- parcAssertNotNull(*listenerPtr,
- "Parameter must derefernce to non-null pointer");
- _TcpListener *tcp = *listenerPtr;
-
- if (logger_IsLoggable(tcp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- char *str = addressToString(tcp->localAddress);
- logger_Log(tcp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "TcpListener %p destroyed", (void *)tcp);
- parcMemory_Deallocate((void **)&str);
- }
-
- parcMemory_Deallocate((void **)&tcp->listenerName);
- parcMemory_Deallocate((void **)&tcp->interfaceName);
- logger_Release(&tcp->logger);
- dispatcher_DestroyListener(forwarder_GetDispatcher(tcp->forwarder),
- &tcp->listener);
- addressDestroy(&tcp->localAddress);
- parcMemory_Deallocate((void **)&tcp);
- *listenerPtr = NULL;
-}
-
-// ==================================================
-
-static const char *_tcpListener_ListenerName(const ListenerOps *ops) {
- _TcpListener *tcp = (_TcpListener *)ops->context;
- return tcp->listenerName;
-}
-
-static const char *_tcpListener_InterfaceName(const ListenerOps *ops) {
- _TcpListener *tcp = (_TcpListener *)ops->context;
- return tcp->interfaceName;
-}
-
-static void _tcpListener_Listen(int fd, struct sockaddr *sa, int socklen,
- void *tcpVoid) {
- _TcpListener *tcp = (_TcpListener *)tcpVoid;
-
- Address *remote;
-
- switch (sa->sa_family) {
- case AF_INET:
- remote = addressCreateFromInet((struct sockaddr_in *)sa);
- break;
-
- case AF_INET6:
- remote = addressCreateFromInet6((struct sockaddr_in6 *)sa);
- break;
-
- default:
- parcTrapIllegalValue(sa, "Expected INET or INET6, got %d", sa->sa_family);
- abort();
- }
-
- AddressPair *pair = addressPair_Create(tcp->localAddress, remote);
-
- IoOperations *ops = streamConnection_AcceptConnection(
- tcp->forwarder, fd, pair, tcp->isLocalAddressLocal);
- Connection *conn = connection_Create(ops);
-
- connectionTable_Add(forwarder_GetConnectionTable(tcp->forwarder), conn);
-
- if (logger_IsLoggable(tcp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- logger_Log(tcp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "TcpListener %p listen started", (void *)tcp);
- }
-
- addressDestroy(&remote);
-}
-
-static void _tcpListener_OpsDestroy(ListenerOps **listenerOpsPtr) {
- ListenerOps *ops = *listenerOpsPtr;
- _TcpListener *tcp = (_TcpListener *)ops->context;
- _tcpListener_Destroy(&tcp);
- parcMemory_Deallocate((void **)&ops);
- *listenerOpsPtr = NULL;
-}
-
-static unsigned _tcpListener_OpsGetInterfaceIndex(const ListenerOps *ops) {
- _TcpListener *tcp = (_TcpListener *)ops->context;
- return tcp->id;
-}
-
-static const Address *_tcpListener_OpsGetListenAddress(const ListenerOps *ops) {
- _TcpListener *tcp = (_TcpListener *)ops->context;
- return tcp->localAddress;
-}
-
-static EncapType _tcpListener_OpsGetEncapType(const ListenerOps *ops) {
- return ENCAP_TCP;
-}
diff --git a/hicn-light/src/hicn/io/tcpListener.h b/hicn-light/src/hicn/io/tcpListener.h
deleted file mode 100644
index a841738e5..000000000
--- a/hicn-light/src/hicn/io/tcpListener.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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 tcpListener.h
- * @brief Listens for in coming TCP connections
- *
- * This is the "server socket" of hicn-light for TCP connections. The actual
- * I/O is handled by {@link StreamConnection}.
- *
- */
-
-#ifndef tcpListener_h
-#define tcpListener_h
-
-#ifndef _WIN32
-#include <netinet/in.h>
-#endif
-
-#include <hicn/core/forwarder.h>
-#include <hicn/io/listener.h>
-#include <stdlib.h>
-
-ListenerOps *tcpListener_CreateInet6(Forwarder *forwarder, char *listenerName,
- struct sockaddr_in6 sin6, char *interfaceName);
-ListenerOps *tcpListener_CreateInet(Forwarder *forwarder, char *listenerName,
- struct sockaddr_in sin, char *interfaceName);
-#endif // tcpListener_h
diff --git a/hicn-light/src/hicn/io/tcpTunnel.c b/hicn-light/src/hicn/io/tcpTunnel.c
deleted file mode 100644
index 7a04a4222..000000000
--- a/hicn-light/src/hicn/io/tcpTunnel.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <hicn/hicn-light/config.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <parc/assert/parc_Assert.h>
-#include <hicn/io/streamConnection.h>
-#include <hicn/io/tcpListener.h>
-#include <hicn/io/tcpTunnel.h>
-
-IoOperations *tcpTunnel_Create(Forwarder *forwarder,
- const Address *localAddress,
- const Address *remoteAddress) {
- IoOperations *ops = NULL;
-
- address_type localType = addressGetType(localAddress);
- address_type remoteType = addressGetType(remoteAddress);
-
- if (localType == remoteType) {
- AddressPair *pair = addressPair_Create(localAddress, remoteAddress);
- bool isLocal = false;
-
- ops = streamConnection_OpenConnection(forwarder, pair, isLocal);
- }
-
- return ops;
-}
diff --git a/hicn-light/src/hicn/io/tcpTunnel.h b/hicn-light/src/hicn/io/tcpTunnel.h
deleted file mode 100644
index d1d2a8524..000000000
--- a/hicn-light/src/hicn/io/tcpTunnel.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 tcpTunnel.h
- * @brief Establish a tunnel to a remote system
- *
- */
-
-#ifndef tcpTunnel_h
-#define tcpTunnel_h
-
-#include <hicn/core/forwarder.h>
-#include <hicn/io/ioOperations.h>
-#include <hicn/io/listener.h>
-#include <hicn/utils/address.h>
-
-/**
- */
-// IoOperations *tcpTunnel_CreateOnListener(Forwarder *forwarder,
-// ListenerOps *localListener,
-// const Address *remoteAddress);
-
-/**
- */
-IoOperations *tcpTunnel_Create(Forwarder *forwarder,
- const Address *localAddress,
- const Address *remoteAddress);
-
-#endif // tcpTunnel_h
diff --git a/hicn-light/src/hicn/io/udp.c b/hicn-light/src/hicn/io/udp.c
new file mode 100644
index 000000000..2baae1e5b
--- /dev/null
+++ b/hicn-light/src/hicn/io/udp.c
@@ -0,0 +1,483 @@
+/*
+ * 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:
+ *
+ * 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 udp.c
+ * #brief Implementation of the UDP face
+ *
+ * Old comment:
+ * - The Send() function may overflow the output buffer
+ *
+ */
+
+/* This has to be included early as other modules are including socket.h */
+
+#ifndef _WIN32
+#include <arpa/inet.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef _WIN32
+#include <sys/uio.h>
+#include <unistd.h>
+#endif
+#include <sys/socket.h>
+
+#ifdef WITH_GSO
+#include <netinet/if_ether.h> // ETH_DATA_LEN
+#include <linux/ipv6.h> // struct ipv6hdr
+#include <netinet/udp.h> // struct udphdr, SOL_UDP
+//#include <linux/udp.h> // UDP_GRO
+#define UDP_GRO 104
+#endif /* WITH_GSO */
+
+#include <hicn/core/address_pair.h>
+#include <hicn/core/connection.h>
+#include <hicn/core/connection_vft.h>
+#include <hicn/core/listener.h>
+#include <hicn/core/listener_vft.h>
+#include <hicn/base/loop.h>
+#include <hicn/core/msgbuf.h>
+#include <hicn/core/forwarder.h>
+#include <hicn/core/messageHandler.h>
+#include <hicn/core/messagePacketType.h>
+#include <hicn/hicn-light/config.h>
+#include <hicn/util/log.h>
+
+// Batching based on recvmmsg is also generic
+// the difference is the handling of packet as in tcp we need to go through the
+// ring buffer first to do the framing, while in UDP this is already done
+//
+// each module should have a function to process a packet, then call a callback
+// in the forwarder again
+
+#define BATCH_SOCKET_BUFFER 512 * 1024 /* 256k */
+
+
+/******************************************************************************
+ * Listener
+ ******************************************************************************/
+
+typedef struct {
+ uint16_t port; // in address ?
+
+ batch_buffer_t bb;
+} listener_udp_data_t;
+
+#ifdef __ANDROID__
+extern int bindSocket(int sock, const char * interface_name);
+#endif
+
+#include <arpa/inet.h>
+char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen)
+{
+ switch(sa->sa_family) {
+ case AF_INET:
+ inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
+ s, maxlen);
+ break;
+
+ case AF_INET6:
+ inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
+ s, maxlen);
+ break;
+
+ default:
+ strncpy(s, "Unknown AF", maxlen);
+ return NULL;
+ }
+
+ return s;
+}
+
+/* socket options */
+int
+socket_set_options(int fd)
+{
+#ifndef _WIN32
+ // Set non-blocking flag
+ int flags = fcntl(fd, F_GETFL, NULL);
+ if (flags < 0) {
+ perror("fcntl");
+ return -1;
+ }
+
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ perror("fcntl");
+ return -1;
+ }
+#else
+ // Set non-blocking flag
+ int result = ioctlsocket(fd, FIONBIO, &(int){1});
+ if (result != NO_ERROR) {
+ perror("ioctlsocket");
+ return -1;
+ }
+#endif
+
+ // don't hang onto address after listener has closed
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0) {
+ perror("setsockopt");
+ return -1;
+ }
+
+#ifdef WITH_GSO
+//● choosing gso_size
+//○ ETH_DATA_LEN
+//○ IP_MTU_DISCOVER
+//● choosing number of segments
+//○ fit in network layer
+//○ <= UDP_MAX_SEGMENTS
+//○ > gso_size
+//● checksum offload
+//○ csum_and_copy_from_user
+ int gso_size = ETH_DATA_LEN - sizeof(struct ipv6hdr) - sizeof(struct udphdr);
+ if (setsockopt(fd, SOL_UDP, UDP_SEGMENT, &gso_size, sizeof(gso_size)) < 0) {
+ perror("setsockopt");
+ return -1;
+ }
+#endif /* WITH_GSO */
+
+#ifdef WITH_GRO
+ if (setsockopt(fd, IPPROTO_UDP, UDP_GRO, &(int){1}, sizeof(int)) < 0) {
+ perror("setsockopt");
+ return -1;
+ }
+#endif /* WITH_GRO */
+
+#ifdef WITH_ZEROCOPY
+ if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &(int){1}, sizeof(int))) {
+ perror("setsockopt");
+ return -1;
+ }
+#endif /* WITH_ZEROCOPY */
+
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &(int){BATCH_SOCKET_BUFFER}, sizeof(int)) < 0) {
+ perror("setsockopt");
+ return -1;
+ }
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &(int){BATCH_SOCKET_BUFFER}, sizeof(int)) < 0) {
+ perror("setsockopt");
+ return -1;
+ }
+ return 0;
+}
+
+#ifdef __linux__
+/* bind to device */
+int
+socket_bind_to_device(int fd, const char * interface_name)
+{
+ if (strncmp("lo", interface_name, 2) == 0)
+ return 0;
+
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name,
+ strlen(interface_name) + 1) < 0) {
+ perror("setsockopt");
+ goto ERR_BIND_TO_DEVICE;
+ }
+
+ return 0;
+
+ERR_BIND_TO_DEVICE:
+#ifdef __ANDROID__
+ if (bindSocket(fd, interface_name) < 0)
+ return -1;
+ return 0;
+#else
+ return -1;
+#endif /* __ANDROID__ */
+}
+#endif /* __linux__ */
+
+static
+int
+listener_udp_initialize(listener_t * listener)
+{
+ assert(listener);
+
+ listener_udp_data_t * data = listener->data;
+ assert(data);
+
+ init_batch_buffers(&data->bb);
+
+ // XXX Socket creation should be a function per-se and not be called in
+ // initialize !
+ listener->fd = listener_get_socket(listener, &listener->address, NULL,
+ listener->interface_name);
+ if (listener->fd < 0) {
+ ERROR("Error creating UDP socket: (%d) %s", errno, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+static
+void
+listener_udp_finalize(listener_t * listener)
+{
+ assert(listener);
+ assert(listener_get_type(listener) == FACE_TYPE_UDP);
+
+ return;
+}
+
+static
+int
+listener_udp_punt(const listener_t * listener, const char * prefix_s)
+{
+ return -1;
+}
+
+static
+int
+listener_udp_get_socket(const listener_t * listener, const address_t * local,
+ const address_t * remote, const char * interface_name)
+{
+ int fd = socket(address_family(remote), SOCK_DGRAM, 0);
+ if (fd < 0)
+ goto ERR_SOCKET;
+
+ if (socket_set_options(fd) < 0) {
+ goto ERR;
+ }
+
+ if (bind(fd, address_sa(local), address_socklen(remote)) < 0) {
+ perror("bind");
+ goto ERR;
+ }
+
+#ifdef __linux__
+ if (socket_bind_to_device(fd, interface_name) < 0) {
+ goto ERR;
+ }
+#endif /* __linux__ */
+
+ if (remote) {
+ if (connect(fd, address_sa(remote), address_socklen(remote)) < 0) {
+ perror("connect");
+ goto ERR;
+ }
+ }
+
+ return fd;
+
+ERR:
+#ifndef _WIN32
+ close(fd);
+#else
+ closesocket(fd);
+#endif
+ERR_SOCKET:
+ return -1;
+}
+
+static
+void
+listener_udp_read_callback(listener_t * listener, int fd, void * user_data)
+{
+ assert(listener);
+ assert(!user_data);
+
+ listener_udp_data_t * data = listener->data;
+ assert(data);
+
+ listener_batch_read_callback(listener->forwarder, listener, fd, &listener->address, &data->bb);
+}
+
+DECLARE_LISTENER(udp);
+
+/******************************************************************************
+ * Connection
+ ******************************************************************************/
+
+typedef struct {
+ batch_buffer_t bb;
+ int queue_len;
+} connection_udp_data_t;
+
+static
+int
+connection_udp_initialize(connection_t * connection)
+{
+
+ assert(connection);
+ assert(connection->type == FACE_TYPE_UDP);
+ assert(interface_name);
+ assert(address_pair);
+
+ connection_udp_data_t * data = connection->data;
+ assert(data);
+
+ init_batch_buffers(&data->bb);
+
+ data->queue_len = 0;
+
+ return 0;
+}
+
+static
+void
+connection_udp_finalize(connection_t * connection)
+{
+ ERROR("[connection_udp_finalize] Not implemented");
+
+}
+
+/**
+ * @function metisUdpConnection_Send
+ * @abstract Non-destructive send of the message.
+ * @discussion
+ * sends a message to the peer.
+ *
+ * @param dummy is ignored. A udp connection has only one peer.
+ * @return <#return#>
+ */
+// XXX address not used anywhere
+static
+int
+connection_udp_send(const connection_t * connection, msgbuf_t * msgbuf, bool queue)
+{
+ assert(connection);
+ /* msgbuf can be NULL */
+
+ connection_udp_data_t * data = connection->data;
+ assert(data);
+
+ /* Flush if required or if queue is full */
+ if ((!msgbuf) || (queue && (data->queue_len > MAX_MSG))) {
+ /* Flush operation */
+#ifdef WITH_ZEROCOPY
+ int flags = MSG_ZEROCOPY;
+#else
+ int flags = 0;
+#endif /* WITH_ZEROCOPY */
+ int n = sendmmsg(connection->fd, data->bb.msghdr, data->queue_len, flags);
+ if (n == -1) {
+ perror("sendmmsg()");
+ data->queue_len = 0;
+ return false;
+ }
+
+ if (n < data->queue_len) {
+ // XXX TODO
+ printf("Unhandled Error after sending n=%d msgbufs\n", n);
+ }
+
+ /* XXX check msglen */
+ data->queue_len = 0;
+ return true;
+ }
+
+ if (queue) {
+ struct iovec *iovec = &data->bb.iovecs[data->queue_len++];
+ iovec->iov_base = msgbuf_get_packet(msgbuf);
+ iovec->iov_len = msgbuf_get_len(msgbuf);
+
+ } else {
+ ssize_t writeLength = write(connection->fd, msgbuf_get_packet(msgbuf),
+ msgbuf_get_len(msgbuf));
+
+ if (writeLength < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ return false;
+ } else {
+ // this print is for debugging
+ printf("Incorrect write length %zd, expected %u: (%d) %s\n", writeLength,
+ msgbuf_get_len(msgbuf), errno, strerror(errno));
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+#if 0
+static
+bool
+connection_udp_sendv(const connection_t * connection, struct iovec * iov,
+ size_t size)
+{
+
+ assert(connetion);
+ assert(iov);
+
+ connection_udp_data_t * data = connection->data;
+ assert(data);
+
+#ifndef _WIN32
+ // Perform connect before to establish association between this peer and
+ // the remote peer. This is required to use writev.
+ // Connection association can be changed at any time.
+
+ if (writev(connection->fd, iov, (int)size) < 0)
+ return false;
+#else
+ WSABUF *buf = (WSABUF *) malloc(size * sizeof(WSABUF));
+
+ DWORD bytes_sent = 0;
+
+ for (int i = 0; i < size; i++) {
+ buf[i].buf = iov[i].iov_base;
+ buf[i].len = (ULONG)iov[i].iov_len;
+ }
+
+ int rc = WSASendTo(udp->fd, buf, size, &bytes_sent, 0,
+ (SOCKADDR *)address_sa(address_pair_remote(&udp->pair)),
+ address_socklen(address_pair_remote(&udp->pair)), NULL, NULL);
+ free(dataBuf);
+ if (rc == SOCKET_ERROR)
+ return false;
+#endif
+
+ return true;
+}
+#endif
+
+static
+int
+connection_udp_send_packet(const connection_t * connection, const uint8_t * packet, size_t size)
+{
+ assert(ops);
+ assert(packet);
+
+ if(connection_is_local(connection))
+ return -1;
+
+ ssize_t n = sendto(connection->fd, packet, size, 0,
+ address_sa(address_pair_get_remote(&connection->pair)),
+ address_socklen(address_pair_get_remote(&connection->pair)));
+ if (n < 0)
+ return -1;
+ return 0;
+}
+
+static
+void
+connection_udp_read_callback(connection_t * connection, int fd, void * user_data)
+{
+ assert(connection);
+ assert(!user_data);
+
+ connection_udp_data_t * data = connection->data;
+ assert(data);
+ listener_batch_read_callback(connection->forwarder, NULL, fd, address_pair_get_local(&connection->pair), &data->bb);
+}
+
+DECLARE_CONNECTION(udp);
diff --git a/hicn-light/src/hicn/io/udpConnection.c b/hicn-light/src/hicn/io/udpConnection.c
deleted file mode 100644
index cd3ccc84a..000000000
--- a/hicn-light/src/hicn/io/udpConnection.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Embodies the reader/writer for a UDP connection
- *
- * NB The Send() function may overflow the output buffer
- *
- */
-
-#ifndef _WIN32
-#include <sys/uio.h>
-#endif
-#include <errno.h>
-#include <hicn/hicn-light/config.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <hicn/core/messageHandler.h>
-#include <hicn/io/udpConnection.h>
-
-#include <parc/algol/parc_Hash.h>
-#include <parc/algol/parc_Memory.h>
-#include <parc/assert/parc_Assert.h>
-#include <hicn/core/connection.h>
-#include <hicn/core/forwarder.h>
-#include <hicn/core/message.h>
-
-typedef struct udp_state {
- Forwarder *forwarder;
- char * interfaceName;
- Logger *logger;
-
- // the udp listener socket we receive packets on
- int udpListenerSocket;
-
- AddressPair *addressPair;
-
- // We need to access this all the time, so grab it out
- // of the addressPair;
- struct sockaddr *peerAddress;
- socklen_t peerAddressLength;
-
- bool isLocal;
- bool isUp;
- 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;
-#ifdef WITH_POLICY
- uint32_t priority;
-#endif /* WITH_POLICY */
-} _UdpState;
-
-// Prototypes
-static bool _send(IoOperations *ops, const Address *nexthop, Message *message);
-static bool _sendIOVBuffer(IoOperations *ops, struct iovec *message,
- size_t size);
-static const Address *_getRemoteAddress(const IoOperations *ops);
-static const AddressPair *_getAddressPair(const IoOperations *ops);
-static unsigned _getConnectionId(const IoOperations *ops);
-static bool _isUp(const IoOperations *ops);
-static bool _isLocal(const IoOperations *ops);
-static void _destroy(IoOperations **opsPtr);
-static list_connections_type _getConnectionType(const IoOperations *ops);
-static void _sendProbe(IoOperations *ops, 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);
-#ifdef WITH_POLICY
-static uint32_t _getPriority(const IoOperations *ops);
-static void _setPriority(IoOperations *ops, uint32_t priority);
-#endif /* WITH_POLICY */
-static const char * _getInterfaceName(const IoOperations *ops);
-
-/*
- * This assigns a unique pointer to the void * which we use
- * as a GUID for this class.
- */
-static const void *_IoOperationsGuid = __FILE__;
-
-/*
- * Return our GUID
- */
-static const void *_streamConnection_Class(const IoOperations *ops) {
- return _IoOperationsGuid;
-}
-
-static IoOperations _template = {
- .closure = NULL,
- .send = &_send,
- .sendIOVBuffer = &_sendIOVBuffer,
- .getRemoteAddress = &_getRemoteAddress,
- .getAddressPair = &_getAddressPair,
- .getConnectionId = &_getConnectionId,
- .isUp = &_isUp,
- .isLocal = &_isLocal,
- .destroy = &_destroy,
- .class = &_streamConnection_Class,
- .getConnectionType = &_getConnectionType,
- .sendProbe = &_sendProbe,
- .getState = &_getState,
- .setState = &_setState,
- .getAdminState = &_getAdminState,
- .setAdminState = &_setAdminState,
-#ifdef WITH_POLICY
- .getPriority = &_getPriority,
- .setPriority = &_setPriority,
-#endif /* WITH_POLICY */
- .getInterfaceName = &_getInterfaceName,
-};
-
-// =================================================================
-
-static void _setConnectionState(_UdpState *Udp, bool isUp);
-static bool _saveSockaddr(_UdpState *udpConnState, const AddressPair *pair);
-
-IoOperations *udpConnection_Create(Forwarder *forwarder, const char * interfaceName, int fd,
- const AddressPair *pair, bool isLocal) {
- IoOperations *io_ops = NULL;
-
- _UdpState *udpConnState = parcMemory_AllocateAndClear(sizeof(_UdpState));
- parcAssertNotNull(udpConnState,
- "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(_UdpState));
-
- udpConnState->forwarder = forwarder;
- udpConnState->interfaceName = strdup(interfaceName);
- udpConnState->logger = logger_Acquire(forwarder_GetLogger(forwarder));
-
- bool saved = _saveSockaddr(udpConnState, pair);
- if (saved) {
- udpConnState->udpListenerSocket = fd;
- udpConnState->id = forwarder_GetNextConnectionId(forwarder);
- udpConnState->addressPair = addressPair_Acquire(pair);
- udpConnState->isLocal = isLocal;
-
- // allocate a connection
- io_ops = parcMemory_AllocateAndClear(sizeof(IoOperations));
- parcAssertNotNull(io_ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(IoOperations));
- memcpy(io_ops, &_template, sizeof(IoOperations));
- io_ops->closure = udpConnState;
-
- _setConnectionState(udpConnState, true);
-
-#ifdef WITH_POLICY
- udpConnState->priority = 0;
-#endif /* WITH_POLICY */
-
- if (logger_IsLoggable(udpConnState->logger, LoggerFacility_IO,
- PARCLogLevel_Info)) {
- char *str = addressPair_ToString(udpConnState->addressPair);
- logger_Log(udpConnState->logger, LoggerFacility_IO, PARCLogLevel_Info,
- __func__,
- "UdpConnection %p created for address %s (isLocal %d)",
- (void *)udpConnState, str, udpConnState->isLocal);
- free(str);
- }
-
- messenger_Send(
- forwarder_GetMessenger(forwarder),
- missive_Create(MissiveType_ConnectionCreate, udpConnState->id));
- messenger_Send(forwarder_GetMessenger(forwarder),
- missive_Create(MissiveType_ConnectionUp, udpConnState->id));
- } else {
- // _saveSockaddr will already log an error, no need for extra log message
- // here
- logger_Release(&udpConnState->logger);
-
- free(udpConnState->interfaceName);
- parcMemory_Deallocate((void **)&udpConnState);
- }
-
- return io_ops;
-}
-
-// =================================================================
-// I/O Operations implementation
-
-static void _destroy(IoOperations **opsPtr) {
- parcAssertNotNull(opsPtr, "Parameter opsPtr must be non-null double pointer");
- parcAssertNotNull(*opsPtr,
- "Parameter opsPtr must dereference to non-null pointer");
-
- IoOperations *ops = *opsPtr;
- parcAssertNotNull(ioOperations_GetClosure(ops),
- "ops->context must not be null");
-
- _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops);
- addressPair_Release(&udpConnState->addressPair);
- parcMemory_Deallocate((void **)&(udpConnState->peerAddress));
-
- messenger_Send(
- forwarder_GetMessenger(udpConnState->forwarder),
- missive_Create(MissiveType_ConnectionDestroyed, udpConnState->id));
-
- if (logger_IsLoggable(udpConnState->logger, LoggerFacility_IO,
- PARCLogLevel_Info)) {
- logger_Log(udpConnState->logger, LoggerFacility_IO, PARCLogLevel_Info,
- __func__, "UdpConnection %p destroyed", (void *)udpConnState);
- }
-
- // do not close udp->udpListenerSocket, the listener will close
- // that when its done
-
- logger_Release(&udpConnState->logger);
- free(udpConnState->interfaceName);
- parcMemory_Deallocate((void **)&udpConnState);
- parcMemory_Deallocate((void **)&ops);
-
- *opsPtr = NULL;
-}
-
-static bool _isUp(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _UdpState *udpConnState =
- (const _UdpState *)ioOperations_GetClosure(ops);
- return udpConnState->isUp;
-}
-
-static bool _isLocal(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _UdpState *udpConnState =
- (const _UdpState *)ioOperations_GetClosure(ops);
- return udpConnState->isLocal;
-}
-
-static const Address *_getRemoteAddress(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _UdpState *udpConnState =
- (const _UdpState *)ioOperations_GetClosure(ops);
- return addressPair_GetRemote(udpConnState->addressPair);
-}
-
-static const AddressPair *_getAddressPair(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _UdpState *udpConnState =
- (const _UdpState *)ioOperations_GetClosure(ops);
- return udpConnState->addressPair;
-}
-
-static unsigned _getConnectionId(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _UdpState *udpConnState =
- (const _UdpState *)ioOperations_GetClosure(ops);
- return udpConnState->id;
-}
-
-/**
- * @function metisUdpConnection_Send
- * @abstract Non-destructive send of the message.
- * @discussion
- * sends a message to the peer.
- *
- * @param dummy is ignored. A udp connection has only one peer.
- * @return <#return#>
- */
-static bool _send(IoOperations *ops, const Address *dummy, Message *message) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
- _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops);
-
- // NAT for HICN
- // in this particular connection we don't need natting beacause we send the
- // packet to the next hop using upd connection
-
- ssize_t writeLength =
- sendto(udpConnState->udpListenerSocket, message_FixedHeader(message),
- (int)message_Length(message), 0, udpConnState->peerAddress,
- udpConnState->peerAddressLength);
-
- if (writeLength < 0) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- return false;
- } else {
- // this print is for debugging
- printf("Incorrect write length %zd, expected %zd: (%d) %s\n", writeLength,
- message_Length(message), errno, strerror(errno));
- return false;
- }
- }
-
- return true;
-}
-
-static bool _sendIOVBuffer(IoOperations *ops, struct iovec *message,
- size_t size) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
- _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops);
-
-#ifndef _WIN32
- // Perform connect before to establish association between this peer and
- // the remote peer. This is required to use writev.
- // Connection association can be changed at any time.
- connect(udpConnState->udpListenerSocket,
- udpConnState->peerAddress,
- udpConnState->peerAddressLength);
-
- ssize_t writeLength = writev(udpConnState->udpListenerSocket, message, (int)size);
-
- struct sockaddr any_address = {0};
- any_address.sa_family = AF_UNSPEC;
- connect(udpConnState->udpListenerSocket,
- &any_address, (socklen_t)sizeof(any_address));
-
- if (writeLength < 0) {
- return false;
- }
-#else
-
- WSABUF *dataBuf = (WSABUF *) malloc(size * sizeof (dataBuf));
- DWORD BytesSent = 0;
-
- for (int i = 0; i < size; i++) {
- dataBuf[i].buf = message[i].iov_base;
- dataBuf[i].len = (ULONG)message[i].iov_len;
- }
-
- int rc = WSASendTo(udpConnState->udpListenerSocket, dataBuf, size,
- &BytesSent, 0, (SOCKADDR *)udpConnState->peerAddress,
- udpConnState->peerAddressLength, NULL, NULL);
- free(dataBuf);
- if (rc == SOCKET_ERROR) {
- return false;
- }
-#endif
- return true;
-}
-
-static list_connections_type _getConnectionType(const IoOperations *ops) {
- return CONN_UDP;
-}
-
-static void _sendProbe(IoOperations *ops, uint8_t *message) {
- parcAssertNotNull(ops, "Parameter ops must be non-null");
- parcAssertNotNull(message, "Parameter message must be non-null");
- _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops);
-
- if(udpConnState->isLocal)
- return;
-
- ssize_t writeLength =
- sendto(udpConnState->udpListenerSocket, message,
- messageHandler_GetTotalPacketLength(message), 0, udpConnState->peerAddress,
- udpConnState->peerAddressLength);
-
- if (writeLength < 0) {
- return;
- }
-}
-
-// =================================================================
-// Internal API
-
-static bool _saveSockaddr(_UdpState *udpConnState, const AddressPair *pair) {
- bool success = false;
- const Address *remoteAddress = addressPair_GetRemote(pair);
-
- switch (addressGetType(remoteAddress)) {
- case ADDR_INET: {
- size_t bytes = sizeof(struct sockaddr_in);
- udpConnState->peerAddress = parcMemory_Allocate(bytes);
- parcAssertNotNull(udpConnState->peerAddress,
- "parcMemory_Allocate(%zu) returned NULL", bytes);
-
- addressGetInet(remoteAddress,
- (struct sockaddr_in *)udpConnState->peerAddress);
- udpConnState->peerAddressLength = (socklen_t)bytes;
-
- success = true;
- break;
- }
-
- case ADDR_INET6: {
- size_t bytes = sizeof(struct sockaddr_in6);
- udpConnState->peerAddress = parcMemory_Allocate(bytes);
- parcAssertNotNull(udpConnState->peerAddress,
- "parcMemory_Allocate(%zu) returned NULL", bytes);
-
- addressGetInet6(remoteAddress,
- (struct sockaddr_in6 *)udpConnState->peerAddress);
- udpConnState->peerAddressLength = (socklen_t)bytes;
-
- success = true;
- break;
- }
-
- default:
- if (logger_IsLoggable(udpConnState->logger, LoggerFacility_IO,
- PARCLogLevel_Error)) {
- char *str = addressToString(remoteAddress);
- logger_Log(udpConnState->logger, LoggerFacility_IO, PARCLogLevel_Error,
- __func__, "Remote address is not INET or INET6: %s", str);
- parcMemory_Deallocate((void **)&str);
- }
- break;
- }
- return success;
-}
-
-static void _setConnectionState(_UdpState *udpConnState, bool isUp) {
- parcAssertNotNull(udpConnState, "Parameter Udp must be non-null");
-
- Messenger *messenger = forwarder_GetMessenger(udpConnState->forwarder);
-
- bool oldStateIsUp = udpConnState->isUp;
- udpConnState->isUp = isUp;
-
- if (oldStateIsUp && !isUp) {
- // bring connection DOWN
- Missive *missive =
- missive_Create(MissiveType_ConnectionDown, udpConnState->id);
- messenger_Send(messenger, missive);
- return;
- }
-
- if (!oldStateIsUp && isUp) {
- // bring connection UP
- Missive *missive =
- missive_Create(MissiveType_ConnectionUp, udpConnState->id);
- messenger_Send(messenger, missive);
- 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;
-}
-
-#ifdef WITH_POLICY
-static uint32_t _getPriority(const IoOperations *ops) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- const _UdpState *udpConnState =
- (const _UdpState *)ioOperations_GetClosure(ops);
- return udpConnState->priority;
-}
-
-static void _setPriority(IoOperations *ops, uint32_t priority) {
- parcAssertNotNull(ops, "Parameter must be non-null");
- _UdpState *udpConnState =
- (_UdpState *)ioOperations_GetClosure(ops);
- udpConnState->priority = priority;
-}
-#endif /* WITH_POLICY */
-
-static const char * _getInterfaceName(const IoOperations *ops)
-{
- parcAssertNotNull(ops, "Parameter must be non-null");
- _UdpState *udpConnState =
- (_UdpState *)ioOperations_GetClosure(ops);
- return udpConnState->interfaceName;
-}
diff --git a/hicn-light/src/hicn/io/udpConnection.h b/hicn-light/src/hicn/io/udpConnection.h
deleted file mode 100644
index 9fbc5348b..000000000
--- a/hicn-light/src/hicn/io/udpConnection.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 udpConnection.h
- * @brief Represents a UDP connection (socket) for the connection table
- *
- * <#Detailed Description#>
- *
- */
-
-#ifndef udpConnection_h
-#define udpConnection_h
-
-#include <hicn/core/forwarder.h>
-#include <hicn/io/addressPair.h>
-#include <hicn/io/ioOperations.h>
-#include <hicn/utils/address.h>
-
-/**
- * Creates a UDP connection that can send to the remote address
- *
- * The address pair must both be same type (i.e. INET or INET6).
- *
- * @param [in] metis An allocated MetisForwarder (saves reference)
- * @param [in] fd The socket to use
- * @param [in] pair An allocated address pair for the connection (saves
- * reference)
- * @param [in] isLocal determines if the remote address is on the current system
- *
- * @retval non-null An allocated Io operations
- * @retval null An error
- *
- * Example:
- * @code
- * <#example#>
- * @endcode
- */
-IoOperations *udpConnection_Create(Forwarder *forwarder, const char * interfaceName, int fd,
- const AddressPair *pair, bool isLocal);
-#endif // udpConnection_h
diff --git a/hicn-light/src/hicn/io/udpListener.c b/hicn-light/src/hicn/io/udpListener.c
deleted file mode 100644
index 21b4f6190..000000000
--- a/hicn-light/src/hicn/io/udpListener.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _WIN32
-#include <arpa/inet.h>
-#include <unistd.h>
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#include <hicn/hicn-light/config.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <hicn/core/messageHandler.h>
-
-#include <hicn/io/udpConnection.h>
-#include <hicn/io/udpListener.h>
-
-#include <parc/algol/parc_Network.h>
-#include <parc/algol/parc_Memory.h>
-#include <parc/assert/parc_Assert.h>
-#include <hicn/core/connection.h>
-#include <hicn/core/forwarder.h>
-#include <hicn/core/messagePacketType.h>
-
-#define IPv4 4
-#define IPv6 6
-
-struct udp_listener {
- char *listenerName;
- Forwarder *forwarder;
- Logger *logger;
-
- PARCEvent *udp_event;
- SocketType udp_socket;
- uint16_t port;
-
- unsigned id;
- char *interfaceName;
- Address *localAddress;
-};
-
-static void _destroy(ListenerOps **listenerOpsPtr);
-static const char *_getListenerName(const ListenerOps *ops);
-static unsigned _getInterfaceIndex(const ListenerOps *ops);
-static const Address *_getListenAddress(const ListenerOps *ops);
-static EncapType _getEncapType(const ListenerOps *ops);
-static const char *_getInterfaceName(const ListenerOps *ops);
-static int _getSocket(const ListenerOps *ops);
-static unsigned _createNewConnection(ListenerOps *listener, int fd, const AddressPair *pair);
-static const Connection * _lookupConnection(ListenerOps * listener, const AddressPair *pair);
-
-static ListenerOps udpTemplate = {
- .context = NULL,
- .destroy = &_destroy,
- .getInterfaceIndex = &_getInterfaceIndex,
- .getListenAddress = &_getListenAddress,
- .getEncapType = &_getEncapType,
- .getSocket = &_getSocket,
- .getListenerName = &_getListenerName,
- .createConnection = &_createNewConnection,
- .lookupConnection = &_lookupConnection,
- .getInterfaceName = &_getInterfaceName,
-};
-
-
-static void _readcb(int fd, PARCEventType what, void * listener_void);
-
-#ifdef __ANDROID__
-extern int bindSocket(int sock, const char* ifname);
-#endif
-
-ListenerOps *udpListener_CreateInet6(Forwarder *forwarder, char *listenerName,
- struct sockaddr_in6 sin6, const char *interfaceName) {
- ListenerOps *ops = NULL;
-
- UdpListener *udp = parcMemory_AllocateAndClear(sizeof(UdpListener));
- parcAssertNotNull(udp, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(UdpListener));
- udp->forwarder = forwarder;
- udp->listenerName = parcMemory_StringDuplicate(listenerName, strlen(listenerName));
- udp->interfaceName = parcMemory_StringDuplicate(interfaceName, strlen(interfaceName));
- udp->logger = logger_Acquire(forwarder_GetLogger(forwarder));
- udp->localAddress = addressCreateFromInet6(&sin6);
- udp->id = forwarder_GetNextConnectionId(forwarder);
-
- udp->udp_socket = (SocketType)socket(AF_INET6, SOCK_DGRAM, 0);
- parcAssertFalse(udp->udp_socket < 0, "Error opening UDP socket: (%d) %s",
- errno, strerror(errno));
-
- int failure = 0;
-#ifndef _WIN32
- // Set non-blocking flag
- int flags = fcntl(udp->udp_socket, F_GETFL, NULL);
- parcAssertTrue(flags != -1,
- "fcntl failed to obtain file descriptor flags (%d)", errno);
- failure = fcntl(udp->udp_socket, F_SETFL, flags | O_NONBLOCK);
- parcAssertFalse(failure, "fcntl failed to set file descriptor flags (%d)",
- errno);
-#else
- // Set non-blocking flag
- u_long mode = 1;
- int result = ioctlsocket(udp->udp_socket, FIONBIO, &mode);
- if (result != NO_ERROR) {
- parcAssertTrue(result != NO_ERROR,
- "ioctlsocket failed to set file descriptor");
- }
-#endif
-
- int one = 1;
- // don't hang onto address after listener has closed
- failure = setsockopt(udp->udp_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
- (socklen_t)sizeof(one));
- parcAssertFalse(failure, "failed to set REUSEADDR on socket(%d)", errno);
-
- failure = bind(udp->udp_socket, (struct sockaddr *)&sin6, sizeof(sin6));
-
- if (failure == 0) {
-#ifdef __linux__
- if (strncmp("lo", interfaceName, 2) != 0) {
- int ret = setsockopt(udp->udp_socket, SOL_SOCKET, SO_BINDTODEVICE,
- interfaceName, strlen(interfaceName) + 1);
- if (ret < 0) {
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "setsockopt(%d, SO_BINDTODEVICE, %s) failed (%d) %s",
- udp->udp_socket, interfaceName, errno, strerror(errno));
-#ifdef __ANDROID__
- ret = bindSocket(udp->udp_socket, interfaceName);
- if (ret < 0) {
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "bindSocket(%d, %s) failed", udp->udp_socket, interfaceName);
- close(udp->udp_socket);
- addressDestroy(&udp->localAddress);
- logger_Release(&udp->logger);
- parcMemory_Deallocate((void **)&udp);
- return NULL;
- } else {
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "bindSocket(%d, %s) success", udp->udp_socket, interfaceName);
- }
-#else
- close(udp->udp_socket);
- addressDestroy(&udp->localAddress);
- logger_Release(&udp->logger);
- parcMemory_Deallocate((void **)&udp);
- return NULL;
-#endif
- }
- }
-#endif
-
- ops = parcMemory_AllocateAndClear(sizeof(ListenerOps));
- parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(ListenerOps));
- memcpy(ops, &udpTemplate, sizeof(ListenerOps));
- ops->context = udp;
-
- udp->udp_event =
- dispatcher_CreateNetworkEvent(forwarder_GetDispatcher(forwarder), true,
- _readcb, (void*)ops, udp->udp_socket);
- dispatcher_StartNetworkEvent(forwarder_GetDispatcher(forwarder),
- udp->udp_event);
-
- if (logger_IsLoggable(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- char *str = addressToString(udp->localAddress);
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "UdpListener %p created for address %s", (void *)udp, str);
- parcMemory_Deallocate((void **)&str);
- }
- } else {
- if (logger_IsLoggable(udp->logger, LoggerFacility_IO, PARCLogLevel_Error)) {
- int myerrno = errno;
- char *str = addressToString(udp->localAddress);
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "Error binding UDP socket to address %s: (%d) %s", str,
- myerrno, strerror(myerrno));
- parcMemory_Deallocate((void **)&str);
- }
- parcMemory_Deallocate((void **)&udp->listenerName);
- parcMemory_Deallocate((void **)&udp->interfaceName);
-#ifndef _WIN32
- close(udp->udp_socket);
-#else
- closesocket(udp->udp_socket);
-#endif
- addressDestroy(&udp->localAddress);
- logger_Release(&udp->logger);
- parcMemory_Deallocate((void **)&udp);
- }
-
- return ops;
-}
-
-ListenerOps *udpListener_CreateInet(Forwarder *forwarder, char *listenerName,
- struct sockaddr_in sin, const char *interfaceName) {
- ListenerOps *ops = NULL;
-
- UdpListener *udp = parcMemory_AllocateAndClear(sizeof(UdpListener));
- parcAssertNotNull(udp, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(UdpListener));
- udp->forwarder = forwarder;
- udp->listenerName = parcMemory_StringDuplicate(listenerName, strlen(listenerName));
- udp->interfaceName = parcMemory_StringDuplicate(interfaceName, strlen(interfaceName));
- udp->logger = logger_Acquire(forwarder_GetLogger(forwarder));
- udp->localAddress = addressCreateFromInet(&sin);
- udp->id = forwarder_GetNextConnectionId(forwarder);
-
- udp->udp_socket = (SocketType)socket(AF_INET, SOCK_DGRAM, 0);
- parcAssertFalse(udp->udp_socket < 0, "Error opening UDP socket: (%d) %s",
- errno, strerror(errno));
-
- int failure = 0;
-#ifndef _WIN32
- // Set non-blocking flag
- int flags = fcntl(udp->udp_socket, F_GETFL, NULL);
- parcAssertTrue(flags != -1,
- "fcntl failed to obtain file descriptor flags (%d)", errno);
- failure = fcntl(udp->udp_socket, F_SETFL, flags | O_NONBLOCK);
- parcAssertFalse(failure, "fcntl failed to set file descriptor flags (%d)",
- errno);
-#else
- u_long mode = 1;
- int result = ioctlsocket(udp->udp_socket, FIONBIO, &mode);
- if (result != NO_ERROR) {
- parcAssertTrue(result != NO_ERROR,
- "ioctlsocket failed to set file descriptor");
- }
-#endif
-
- int one = 1;
- // don't hang onto address after listener has closed
- failure = setsockopt(udp->udp_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
- (socklen_t)sizeof(one));
- parcAssertFalse(failure, "failed to set REUSEADDR on socket(%d)", errno);
-
- failure = bind(udp->udp_socket, (struct sockaddr *)&sin, sizeof(sin));
- if (failure == 0) {
-#ifdef __linux__
- if (strncmp("lo", interfaceName, 2) != 0) {
- int ret = setsockopt(udp->udp_socket, SOL_SOCKET, SO_BINDTODEVICE,
- interfaceName, strlen(interfaceName) + 1);
- if (ret < 0) {
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "setsockopt(%d, SO_BINDTODEVICE, %s) failed (%d) %s",
- udp->udp_socket, interfaceName, errno, strerror(errno));
-#ifdef __ANDROID__
- ret = bindSocket(udp->udp_socket, interfaceName);
- if (ret < 0) {
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "bindSocket(%d, %s) failed", udp->udp_socket, interfaceName);
- close(udp->udp_socket);
- addressDestroy(&udp->localAddress);
- logger_Release(&udp->logger);
- parcMemory_Deallocate((void **)&udp);
- return NULL;
- } else {
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "bindSocket(%d, %s) success", udp->udp_socket, interfaceName);
- }
-#else
- close(udp->udp_socket);
- addressDestroy(&udp->localAddress);
- logger_Release(&udp->logger);
- parcMemory_Deallocate((void **)&udp);
- return NULL;
-#endif
- }
- }
-#endif
- ops = parcMemory_AllocateAndClear(sizeof(ListenerOps));
- parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(ListenerOps));
- memcpy(ops, &udpTemplate, sizeof(ListenerOps));
- ops->context = udp;
-
- udp->udp_event =
- dispatcher_CreateNetworkEvent(forwarder_GetDispatcher(forwarder), true,
- _readcb, (void *)ops, udp->udp_socket);
- dispatcher_StartNetworkEvent(forwarder_GetDispatcher(forwarder),
- udp->udp_event);
-
-
- if (logger_IsLoggable(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- char *str = addressToString(udp->localAddress);
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "UdpListener %p created for address %s", (void *)udp, str);
- parcMemory_Deallocate((void **)&str);
- }
- } else {
- if (logger_IsLoggable(udp->logger, LoggerFacility_IO, PARCLogLevel_Error)) {
- int myerrno = errno;
- char *str = addressToString(udp->localAddress);
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "Error binding UDP socket to address %s: (%d) %s", str,
- myerrno, strerror(myerrno));
- parcMemory_Deallocate((void **)&str);
- }
- parcMemory_Deallocate((void **)&udp->listenerName);
- parcMemory_Deallocate((void **)&udp->interfaceName);
-#ifndef _WIN32
- close(udp->udp_socket);
-#else
- closesocket(udp->udp_socket);
-#endif
- addressDestroy(&udp->localAddress);
- logger_Release(&udp->logger);
- parcMemory_Deallocate((void **)&udp);
- }
-
- return ops;
-}
-
-static void udpListener_Destroy(UdpListener **listenerPtr) {
- parcAssertNotNull(listenerPtr, "Parameter must be non-null double pointer");
- parcAssertNotNull(*listenerPtr,
- "Parameter must derefernce to non-null pointer");
-
- UdpListener *udp = *listenerPtr;
-
- if (logger_IsLoggable(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "UdpListener %p destroyed", (void *)udp);
- }
-
- parcMemory_Deallocate((void **)&udp->listenerName);
- parcMemory_Deallocate((void **)&udp->interfaceName);
-#ifndef _WIN32
- close(udp->udp_socket);
-#else
- closesocket(udp->udp_socket);
-#endif
-
- addressDestroy(&udp->localAddress);
- dispatcher_DestroyNetworkEvent(forwarder_GetDispatcher(udp->forwarder),
- &udp->udp_event);
- logger_Release(&udp->logger);
- parcMemory_Deallocate((void **)&udp);
- *listenerPtr = NULL;
-}
-
-static const char *_getListenerName(const ListenerOps *ops) {
- UdpListener *udp = (UdpListener *)ops->context;
- return udp->listenerName;
-}
-
-static const char *_getInterfaceName(const ListenerOps *ops) {
- UdpListener *udp = (UdpListener *)ops->context;
- return udp->interfaceName;
-}
-
-static void _destroy(ListenerOps **listenerOpsPtr) {
- ListenerOps *ops = *listenerOpsPtr;
- UdpListener *udp = (UdpListener *)ops->context;
- udpListener_Destroy(&udp);
- parcMemory_Deallocate((void **)&ops);
- *listenerOpsPtr = NULL;
-}
-
-static unsigned _getInterfaceIndex(const ListenerOps *ops) {
- UdpListener *udp = (UdpListener *)ops->context;
- return udp->id;
-}
-
-static const Address *_getListenAddress(const ListenerOps *ops) {
- UdpListener *udp = (UdpListener *)ops->context;
- return udp->localAddress;
-}
-
-static EncapType _getEncapType(const ListenerOps *ops) { return ENCAP_UDP; }
-
-static int _getSocket(const ListenerOps *ops) {
- UdpListener *udp = (UdpListener *)ops->context;
- return (int)udp->udp_socket;
-}
-
-// =====================================================================
-
-/**
- * @function _constructAddressPair
- * @abstract Creates the address pair that uniquely identifies the connection
- * @discussion
- * The peerIpAddress must be of AF_INET or AF_INET6 family.
- *
- * @param <#param1#>
- * @return Allocated MetisAddressPair, must be destroyed
- */
-static AddressPair *_constructAddressPair(UdpListener *udp,
- struct sockaddr *peerIpAddress,
- socklen_t peerIpAddressLength) {
- Address *remoteAddress;
-
- switch (peerIpAddress->sa_family) {
- case AF_INET:
- remoteAddress =
- addressCreateFromInet((struct sockaddr_in *)peerIpAddress);
- break;
-
- case AF_INET6:
- remoteAddress =
- addressCreateFromInet6((struct sockaddr_in6 *)peerIpAddress);
- break;
-
- default:
- parcTrapIllegalValue(peerIpAddress,
- "Peer address unrecognized family for IP: %d",
- peerIpAddress->sa_family);
- }
-
- AddressPair *pair = addressPair_Create(udp->localAddress, remoteAddress);
- addressDestroy(&remoteAddress);
-
- return pair;
-}
-
-static const Connection * _lookupConnection(ListenerOps * listener,
- const AddressPair *pair) {
- UdpListener * udp = (UdpListener *)listener->context;
- ConnectionTable *connTable = forwarder_GetConnectionTable(udp->forwarder);
- return connectionTable_FindByAddressPair(connTable, pair);
-
-}
-
-/**
- * @function _createNewConnection
- * @abstract Creates a new Metis connection for the peer
- * @discussion
- * PRECONDITION: you know there's not an existing connection with the address
- * pair
- *
- * Creates a new connection and adds it to the connection table.
- *
- * @param <#param1#>
- * @return The connection id for the new connection
- */
-
-static unsigned _createNewConnection(ListenerOps * listener, int fd,
- const AddressPair *pair) {
- UdpListener * udp = (UdpListener *)listener->context;
-
- //check it the connection is local
- bool isLocal = false;
- const Address *localAddress = addressPair_GetLocal(pair);
- if(addressGetType(localAddress) == ADDR_INET){
- struct sockaddr_in tmpAddr;
- addressGetInet(localAddress, &tmpAddr);
- if(parcNetwork_IsSocketLocal((struct sockaddr *)&tmpAddr))
- isLocal = true;
- }else{
- struct sockaddr_in6 tmpAddr6;
- addressGetInet6(localAddress, &tmpAddr6);
- if(parcNetwork_IsSocketLocal((struct sockaddr *)&tmpAddr6))
- isLocal = true;
- }
-
- // metisUdpConnection_Create takes ownership of the pair
- IoOperations *ops = udpConnection_Create(udp->forwarder, udp->interfaceName, fd, pair, isLocal);
- Connection *conn = connection_Create(ops);
- // connection_AllowWldrAutoStart(conn);
-
- connectionTable_Add(forwarder_GetConnectionTable(udp->forwarder), conn);
- unsigned connid = ioOperations_GetConnectionId(ops);
-
- return connid;
-}
-
-static void _handleWldrNotification(UdpListener *udp, unsigned connId,
- uint8_t *msgBuffer) {
- const Connection *conn = connectionTable_FindById(
- forwarder_GetConnectionTable(udp->forwarder), connId);
- if (conn == NULL) {
- return;
- }
-
- Message *message = message_CreateFromByteArray(
- connId, msgBuffer, MessagePacketType_WldrNotification,
- forwarder_GetTicks(udp->forwarder), forwarder_GetLogger(udp->forwarder));
-
- connection_HandleWldrNotification((Connection *)conn, message);
-
- message_Release(&message);
-}
-
-static Message *_readMessage(ListenerOps * listener, int fd,
- AddressPair *pair, uint8_t * packet, bool * processed) {
- UdpListener * udp = (UdpListener *)listener->context;
-
- Message *message = NULL;
-
- unsigned connid;
- bool foundConnection;
-
- const Connection *conn = _lookupConnection(listener, pair);
- if (conn) {
- connid = connection_GetConnectionId(conn);
- foundConnection = true;
- } else {
- connid = 0;
- foundConnection = false;
- }
-
- if (messageHandler_IsTCP(packet)) {
- *processed = true;
- MessagePacketType pktType;
-
- if (messageHandler_IsData(packet)) {
- pktType = MessagePacketType_ContentObject;
- if (!foundConnection) {
- parcMemory_Deallocate((void **)&packet);
- return message;
- }
- } else if (messageHandler_IsInterest(packet)) {
- pktType = MessagePacketType_Interest;
- if (!foundConnection) {
- connid = _createNewConnection(listener, fd, pair);
- }
- } else {
- printf("Got a packet that is not a data nor an interest, drop it!\n");
- parcMemory_Deallocate((void **)&packet);
- return message;
- }
-
- message = message_CreateFromByteArray(
- connid, packet, pktType, forwarder_GetTicks(udp->forwarder),
- forwarder_GetLogger(udp->forwarder));
-
- if (message == NULL) {
- parcMemory_Deallocate((void **)&packet);
- }
- } else if (messageHandler_IsWldrNotification(packet)) {
- *processed = true;
- _handleWldrNotification(udp, connid, packet);
- } else {
-
- *processed = messageHandler_handleHooks(udp->forwarder, packet, listener, fd, pair);
- }
-
- return message;
-}
-
-static void _readCommand(ListenerOps * listener, int fd,
- AddressPair *pair, uint8_t * command) {
- UdpListener * udp = (UdpListener *)listener->context;
-
- if (*command != REQUEST_LIGHT){
- printf("the message received is not a command, drop\n");
- return;
- }
-
- command_id id = *(command + 1);
-
- if (id >= LAST_COMMAND_VALUE){
- printf("the message received is not a valid command, drop\n");
- return;
- }
-
- unsigned connid;
-
- const Connection *conn = _lookupConnection(listener, pair);
- if (conn) {
- connid = connection_GetConnectionId(conn);
- } else {
- connid = _createNewConnection(listener, fd, pair);
- }
-
- struct iovec *request;
- if (!(request = (struct iovec *) parcMemory_AllocateAndClear(
- sizeof(struct iovec) * 2))) {
- return;
- }
-
- request[0].iov_base = command;
- request[0].iov_len = sizeof(header_control_message);
- request[1].iov_base = command + sizeof(header_control_message);
- request[1].iov_len = payloadLengthDaemon(id);
-
- forwarder_ReceiveCommand(udp->forwarder, id, request, connid);
- parcMemory_Deallocate((void **) &command);
- parcMemory_Deallocate((void **) &request);
-}
-
-
-static bool _receivePacket(ListenerOps * listener, int fd,
- AddressPair *pair,
- uint8_t * packet) {
- UdpListener * udp = (UdpListener *)listener->context;
- bool processed = false;
- Message *message = _readMessage(listener, fd, pair,
- packet, &processed);
- if (message) {
- forwarder_Receive(udp->forwarder, message);
- }
- return processed;
-}
-
-static void _readcb(int fd, PARCEventType what, void * listener_void) {
- ListenerOps * listener = (ListenerOps *)listener_void;
- UdpListener * udp = (UdpListener *)listener->context;
-
- if (logger_IsLoggable(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) {
- logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__,
- "%s socket %d what %s%s%s%s data %p", __func__, fd,
- (what & PARCEventType_Timeout) ? " timeout" : "",
- (what & PARCEventType_Read) ? " read" : "",
- (what & PARCEventType_Write) ? " write" : "",
- (what & PARCEventType_Signal) ? " signal" : "", udp);
- }
-
- if (what & PARCEventType_Read) {
- struct sockaddr_storage peerIpAddress;
- socklen_t peerIpAddressLength = sizeof(peerIpAddress);
-
- //packet it deallocated by _receivePacket or _readCommand
- uint8_t * packet = parcMemory_AllocateAndClear(1500); //max MTU
- ssize_t readLength = recvfrom(fd, packet, 1500, 0,
- (struct sockaddr *)&peerIpAddress, &peerIpAddressLength);
-
-#ifdef __APPLE__
- peerIpAddress.ss_len = 0x00;
-#endif
-
- if(readLength < 0) {
- printf("unable to read the message\n");
- return;
- }
-
- AddressPair *pair = _constructAddressPair(
- udp, (struct sockaddr *)&peerIpAddress, peerIpAddressLength);
-
- bool done = _receivePacket(listener, fd, pair, packet);
- if(!done){
- _readCommand(listener, fd, pair, packet);
- }
-
- addressPair_Release(&pair);
- }
-}
diff --git a/hicn-light/src/hicn/io/udpListener.h b/hicn-light/src/hicn/io/udpListener.h
deleted file mode 100644
index 62c09e4db..000000000
--- a/hicn-light/src/hicn/io/udpListener.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef udpListener_h
-#define udpListener_h
-
-#ifndef _WIN32
-#include <netinet/in.h>
-#endif
-
-#include <hicn/core/forwarder.h>
-#include <hicn/io/listener.h>
-#include <stdlib.h>
-
-struct udp_listener;
-typedef struct udp_listener UdpListener;
-
-ListenerOps *udpListener_CreateInet6(Forwarder *forwarder, char *listenerName,
- struct sockaddr_in6 sin6, const char *if_bind);
-ListenerOps *udpListener_CreateInet(Forwarder *forwarder, char *listenerName,
- struct sockaddr_in sin, const char *if_bind);
-// void udpListener_SetPacketType(ListenerOps *ops, MessagePacketType type);
-#endif // udpListener_h
diff --git a/hicn-light/src/hicn/io/udpTunnel.c b/hicn-light/src/hicn/io/udpTunnel.c
deleted file mode 100644
index 9f5249e3c..000000000
--- a/hicn-light/src/hicn/io/udpTunnel.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <hicn/hicn-light/config.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <parc/algol/parc_Network.h>
-#include <parc/assert/parc_Assert.h>
-#include <hicn/io/udpConnection.h>
-#include <hicn/io/udpListener.h>
-#include <hicn/io/udpTunnel.h>
-
-IoOperations *udpTunnel_CreateOnListener(Forwarder *forwarder,
- ListenerOps *localListener,
- const Address *remoteAddress) {
- parcAssertNotNull(forwarder, "Parameter metis must be non-null");
- parcAssertNotNull(localListener, "Parameter localListener must be non-null");
- parcAssertNotNull(remoteAddress, "Parameter remoteAddress must be non-null");
-
- Logger *logger = forwarder_GetLogger(forwarder);
-
- IoOperations *ops = NULL;
- if (localListener->getEncapType(localListener) == ENCAP_UDP) {
- const Address *localAddress =
- localListener->getListenAddress(localListener);
- address_type localType = addressGetType(localAddress);
- address_type remoteType = addressGetType(remoteAddress);
-
- if (localType == remoteType) {
- AddressPair *pair = addressPair_Create(localAddress, remoteAddress);
-
- //check it the connection is local
- bool isLocal = false;
- if(localType == ADDR_INET){
- struct sockaddr_in tmpAddr;
- addressGetInet(localAddress, &tmpAddr);
- if(parcNetwork_IsSocketLocal((struct sockaddr *)&tmpAddr))
- isLocal = true;
- }else{
- struct sockaddr_in6 tmpAddr6;
- addressGetInet6(localAddress, &tmpAddr6);
- if(parcNetwork_IsSocketLocal((struct sockaddr *)&tmpAddr6))
- isLocal = true;
- }
- int fd = localListener->getSocket(localListener);
- // udpListener_SetPacketType(localListener,
- // MessagePacketType_ContentObject);
- ops = udpConnection_Create(forwarder, localListener->getInterfaceName(localListener), fd, pair, isLocal);
-
- addressPair_Release(&pair);
- } else {
- if (logger_IsLoggable(logger, LoggerFacility_IO, PARCLogLevel_Error)) {
- logger_Log(logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "Local listener of type %s and remote type %s, cannot "
- "establish tunnel",
- addressTypeToString(localType),
- addressTypeToString(remoteType));
- }
- }
- } else {
- if (logger_IsLoggable(logger, LoggerFacility_IO, PARCLogLevel_Error)) {
- logger_Log(logger, LoggerFacility_IO, PARCLogLevel_Error, __func__,
- "Local listener %p is not type UDP, cannot establish tunnel",
- (void *)localListener);
- }
- }
-
- return ops;
-}
-
-IoOperations *udpTunnel_Create(Forwarder *forwarder,
- const Address *localAddress,
- const Address *remoteAddress) {
- ListenerSet *set = forwarder_GetListenerSet(forwarder);
- ListenerOps *listener = listenerSet_Find(set, ENCAP_UDP, localAddress);
- IoOperations *ops = NULL;
- if (listener) {
- ops = udpTunnel_CreateOnListener(forwarder, listener, remoteAddress);
- } else {
- if (logger_IsLoggable(forwarder_GetLogger(forwarder), LoggerFacility_IO,
- PARCLogLevel_Error)) {
- char *str = addressToString(localAddress);
- logger_Log(forwarder_GetLogger(forwarder), LoggerFacility_IO,
- PARCLogLevel_Error, __func__,
- "Could not find listener to match address %s", str);
- parcMemory_Deallocate((void **)&str);
- }
- }
- return ops;
-}
diff --git a/hicn-light/src/hicn/io/udpTunnel.h b/hicn-light/src/hicn/io/udpTunnel.h
deleted file mode 100644
index dacfdbb01..000000000
--- a/hicn-light/src/hicn/io/udpTunnel.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 udpTunnel.h
- * @brief Establish a tunnel to a remote system
- *
- */
-
-#ifndef udpTunnel_h
-#define udpTunnel_h
-
-#include <hicn/core/forwarder.h>
-#include <hicn/io/ioOperations.h>
-#include <hicn/io/listener.h>
-#include <hicn/utils/address.h>
-
-/**
- */
-IoOperations *udpTunnel_CreateOnListener(Forwarder *forwarder,
- ListenerOps *localListener,
- const Address *remoteAddress);
-
-/**
- */
-IoOperations *udpTunnel_Create(Forwarder *forwarder,
- const Address *localAddress,
- const Address *remoteAddress);
-
-#endif // udpTunnel_h