diff options
Diffstat (limited to 'libtransport/src/core')
39 files changed, 115 insertions, 4489 deletions
diff --git a/libtransport/src/core/CMakeLists.txt b/libtransport/src/core/CMakeLists.txt index 4e3ac10ec..e442bb863 100644 --- a/libtransport/src/core/CMakeLists.txt +++ b/libtransport/src/core/CMakeLists.txt @@ -11,8 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.5 FATAL_ERROR) - list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/facade.h ${CMAKE_CURRENT_SOURCE_DIR}/manifest.h @@ -24,7 +22,6 @@ list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/errors.h ${CMAKE_CURRENT_SOURCE_DIR}/global_configuration.h ${CMAKE_CURRENT_SOURCE_DIR}/local_connector.h - ${CMAKE_CURRENT_SOURCE_DIR}/rs.h ) list(APPEND SOURCE_FILES @@ -39,8 +36,6 @@ list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/global_configuration.cc ${CMAKE_CURRENT_SOURCE_DIR}/io_module.cc ${CMAKE_CURRENT_SOURCE_DIR}/local_connector.cc - ${CMAKE_CURRENT_SOURCE_DIR}/fec.cc - ${CMAKE_CURRENT_SOURCE_DIR}/rs.cc ) set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE) diff --git a/libtransport/src/core/connector.cc b/libtransport/src/core/connector.cc deleted file mode 100644 index 63919537d..000000000 --- a/libtransport/src/core/connector.cc +++ /dev/null @@ -1,51 +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 <core/connector.h> - -namespace transport { - -namespace core { - -std::once_flag Connector::init_flag_; - -Connector::Connector(PacketReceivedCallback &&receive_callback, - OnReconnect &&reconnect_callback) - : packet_pool_(), - receive_callback_(std::move(receive_callback)), - on_reconnect_callback_(std::move(reconnect_callback)), - state_(ConnectorState::CLOSED) { - init(); -} - -void Connector::init() { increasePoolSize(); } - -void Connector::increasePoolSize(std::size_t size) { - // Allocate space for receiving packets - const auto capacity = packet_size * size; - uint8_t *buffer = static_cast<uint8_t *>(malloc(capacity)); - std::unique_ptr<utils::MemBuf> buffer0 = - utils::MemBuf::takeOwnership(buffer, capacity, 0, nullptr, nullptr, true); - - for (std::size_t i = 1; i < size; i++) { - auto b = buffer0->cloneOne(); - b->advance(i * packet_size); - packet_pool_.add(b.release()); - } -} - -} // end namespace core - -} // end namespace transport diff --git a/libtransport/src/core/connector.h b/libtransport/src/core/connector.h deleted file mode 100644 index f2bbe5dcd..000000000 --- a/libtransport/src/core/connector.h +++ /dev/null @@ -1,109 +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. - */ - -#pragma once - -#include <hicn/transport/core/packet.h> -#include <hicn/transport/utils/membuf.h> -#include <hicn/transport/utils/object_pool.h> -#include <hicn/transport/utils/ring_buffer.h> - -#include <deque> -#include <functional> - -namespace transport { - -namespace core { - -enum class ConnectorType : uint8_t { - SOCKET_CONNECTOR, - RAW_SOCKET_CONNECTOR, - VPP_CONNECTOR, -}; - -class Connector { - protected: - enum class ConnectorState { - CLOSED, - CONNECTING, - CONNECTED, - }; - - public: - static constexpr std::size_t packet_size = 2048; - static constexpr std::size_t queue_size = 4096; - static constexpr std::size_t packet_pool_size = 4096; - - using PacketRing = utils::CircularFifo<Packet::MemBufPtr, queue_size>; - using PacketQueue = std::deque<Packet::MemBufPtr>; - using PacketReceivedCallback = std::function<void(Packet::MemBufPtr &&)>; - using OnReconnect = std::function<void()>; - using PacketSentCallback = std::function<void()>; - - Connector(PacketReceivedCallback &&receive_callback, - OnReconnect &&reconnect_callback); - - virtual ~Connector(){}; - - virtual void send(const Packet::MemBufPtr &packet) = 0; - - virtual void send(const uint8_t *packet, std::size_t len, - const PacketSentCallback &packet_sent = 0) = 0; - - virtual void close() = 0; - - virtual ConnectorState state() { return state_; }; - - virtual bool isConnected() { return state_ == ConnectorState::CONNECTED; } - - protected: - void increasePoolSize(std::size_t size = packet_pool_size); - - TRANSPORT_ALWAYS_INLINE utils::ObjectPool<utils::MemBuf>::Ptr getPacket() { - auto result = packet_pool_.get(); - - while (TRANSPORT_EXPECT_FALSE(!result.first)) { - // Add packets to the pool - increasePoolSize(); - result = packet_pool_.get(); - } - - if (result.second->isChained()) { - result.second->separateChain(result.second->next(), - result.second->prev()); - } - - result.second->trimEnd(result.second->length()); - return std::move(result.second); - } - - private: - void init(); - - protected: - static std::once_flag init_flag_; - utils::ObjectPool<utils::MemBuf> packet_pool_; - PacketQueue output_buffer_; - - // Connector events - PacketReceivedCallback receive_callback_; - OnReconnect on_reconnect_callback_; - - // Connector state - ConnectorState state_; -}; -} // end namespace core - -} // end namespace transport diff --git a/libtransport/src/core/content_object.cc b/libtransport/src/core/content_object.cc index 0c68ef559..411494fdf 100644 --- a/libtransport/src/core/content_object.cc +++ b/libtransport/src/core/content_object.cc @@ -104,19 +104,6 @@ void ContentObject::setName(const Name &name) { } } -void ContentObject::setName(Name &&name) { - if (hicn_data_set_name(format_, packet_start_, name.getStructReference()) < - 0) { - throw errors::RuntimeException( - "Error getting the payload length from content object."); - } - - if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) < - 0) { - throw errors::MalformedPacketException(); - } -} - uint32_t ContentObject::getPathLabel() const { uint32_t path_label; if (hicn_data_get_path_label(packet_start_, &path_label) < 0) { diff --git a/libtransport/src/core/fec.cc b/libtransport/src/core/fec.cc deleted file mode 100644 index 0ce9625a2..000000000 --- a/libtransport/src/core/fec.cc +++ /dev/null @@ -1,880 +0,0 @@ -/* - * fec.c -- forward error correction based on Vandermonde matrices - * 980624 - * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) - * - * Portions derived from code by Phil Karn (karn@ka9q.ampr.org), - * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari - * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -/* - * The following parameter defines how many bits are used for - * field elements. The code supports any value from 2 to 16 - * but fastest operation is achieved with 8 bit elements - * This is the only parameter you may want to change. - */ -#ifndef GF_BITS -#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */ -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <hicn/transport/portability/platform.h> -#include "fec.h" - -/** - * XXX This disable a warning raising only in some platforms. - * TODO Check if this warning is a mistake or it is a real bug: - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83404 - * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=88059 - */ -#ifndef __clang__ -#ifndef _WIN32 -#pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif -#endif - -/* - * compatibility stuff - */ -#if defined (MSDOS) || defined (_WIN32) /* but also for others, e.g. sun... */ -#define NEED_BCOPY -#define bcmp(a,b,n) memcmp(a,b,n) -#endif - -#ifdef ANDROID -#define bcmp(a,b,n) memcmp(a,b,n) -#endif - -#ifdef NEED_BCOPY -#define bcopy(s, d, siz) memcpy((d), (s), (siz)) -#define bzero(d, siz) memset((d), '\0', (siz)) -#endif - -/* - * stuff used for testing purposes only - */ - -#ifdef TEST -#define DEB(x) -#define DDB(x) x -#define DEBUG 0 /* minimal debugging */ -#ifdef MSDOS -#include <time.h> -struct timeval { - unsigned long ticks; -}; -#define gettimeofday(x, dummy) { (x)->ticks = clock() ; } -#define DIFF_T(a,b) (1+ 1000000*(a.ticks - b.ticks) / CLOCKS_PER_SEC ) -typedef unsigned long u_long ; -typedef unsigned short u_short ; -#else /* typically, unix systems */ -#include <sys/time.h> -#define DIFF_T(a,b) \ - (1+ 1000000*(a.tv_sec - b.tv_sec) + (a.tv_usec - b.tv_usec) ) -#endif - -#define TICK(t) \ - {struct timeval x ; \ - gettimeofday(&x, NULL) ; \ - t = x.tv_usec + 1000000* (x.tv_sec & 0xff ) ; \ - } -#define TOCK(t) \ - { u_long t1 ; TICK(t1) ; \ - if (t1 < t) t = 256000000 + t1 - t ; \ - else t = t1 - t ; \ - if (t == 0) t = 1 ;} - -u_long ticks[10]; /* vars for timekeeping */ -#else -#define DEB(x) -#define DDB(x) -#define TICK(x) -#define TOCK(x) -#endif /* TEST */ - -/* - * You should not need to change anything beyond this point. - * The first part of the file implements linear algebra in GF. - * - * gf is the type used to store an element of the Galois Field. - * Must constain at least GF_BITS bits. - * - * Note: unsigned char will work up to GF(256) but int seems to run - * faster on the Pentium. We use int whenever have to deal with an - * index, since they are generally faster. - */ -#if (GF_BITS < 2 && GF_BITS >16) -#error "GF_BITS must be 2 .. 16" -#endif - - -#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */ - -/* - * Primitive polynomials - see Lin & Costello, Appendix A, - * and Lee & Messerschmitt, p. 453. - */ -static const char *allPp[] = { /* GF_BITS polynomial */ - NULL, /* 0 no code */ - NULL, /* 1 no code */ - "111", /* 2 1+x+x^2 */ - "1101", /* 3 1+x+x^3 */ - "11001", /* 4 1+x+x^4 */ - "101001", /* 5 1+x^2+x^5 */ - "1100001", /* 6 1+x+x^6 */ - "10010001", /* 7 1 + x^3 + x^7 */ - "101110001", /* 8 1+x^2+x^3+x^4+x^8 */ - "1000100001", /* 9 1+x^4+x^9 */ - "10010000001", /* 10 1+x^3+x^10 */ - "101000000001", /* 11 1+x^2+x^11 */ - "1100101000001", /* 12 1+x+x^4+x^6+x^12 */ - "11011000000001", /* 13 1+x+x^3+x^4+x^13 */ - "110000100010001", /* 14 1+x+x^6+x^10+x^14 */ - "1100000000000001", /* 15 1+x+x^15 */ - "11010000000010001" /* 16 1+x+x^3+x^12+x^16 */ -}; - - -/* - * To speed up computations, we have tables for logarithm, exponent - * and inverse of a number. If GF_BITS <= 8, we use a table for - * multiplication as well (it takes 64K, no big deal even on a PDA, - * especially because it can be pre-initialized an put into a ROM!), - * otherwhise we use a table of logarithms. - * In any case the macro gf_mul(x,y) takes care of multiplications. - */ - -static gf gf_exp[2*GF_SIZE]; /* index->poly form conversion table */ -static int gf_log[GF_SIZE + 1]; /* Poly->index form conversion table */ -static gf inverse[GF_SIZE+1]; /* inverse of field elem. */ - /* inv[\alpha**i]=\alpha**(GF_SIZE-i-1) */ - -/* - * modnn(x) computes x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, - * without a slow divide. - */ -static inline gf -modnn(int x) -{ - while (x >= GF_SIZE) { - x -= GF_SIZE; - x = (x >> GF_BITS) + (x & GF_SIZE); - } - return x; -} - -#define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;} - -/* - * gf_mul(x,y) multiplies two numbers. If GF_BITS<=8, it is much - * faster to use a multiplication table. - * - * USE_GF_MULC, GF_MULC0(c) and GF_ADDMULC(x) can be used when multiplying - * many numbers by the same constant. In this case the first - * call sets the constant, and others perform the multiplications. - * A value related to the multiplication is held in a local variable - * declared with USE_GF_MULC . See usage in addmul1(). - */ -#if (GF_BITS <= 8) -static gf gf_mul_table[GF_SIZE + 1][GF_SIZE + 1]; - -#define gf_mul(x,y) gf_mul_table[x][y] - -#define USE_GF_MULC gf * __gf_mulc_ -#define GF_MULC0(c) __gf_mulc_ = gf_mul_table[c] -#define GF_ADDMULC(dst, x) dst ^= __gf_mulc_[x] - -static void -init_mul_table() -{ - int i, j; - for (i=0; i< GF_SIZE+1; i++) - for (j=0; j< GF_SIZE+1; j++) - gf_mul_table[i][j] = gf_exp[modnn(gf_log[i] + gf_log[j]) ] ; - - for (j=0; j< GF_SIZE+1; j++) - gf_mul_table[0][j] = gf_mul_table[j][0] = 0; -} -#else /* GF_BITS > 8 */ -static inline gf -gf_mul(x,y) -{ - if ( (x) == 0 || (y)==0 ) return 0; - - return gf_exp[gf_log[x] + gf_log[y] ] ; -} -#define init_mul_table() - -#define USE_GF_MULC register gf * __gf_mulc_ -#define GF_MULC0(c) __gf_mulc_ = &gf_exp[ gf_log[c] ] -#define GF_ADDMULC(dst, x) { if (x) dst ^= __gf_mulc_[ gf_log[x] ] ; } -#endif - -/* - * Generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m] - * Lookup tables: - * index->polynomial form gf_exp[] contains j= \alpha^i; - * polynomial form -> index form gf_log[ j = \alpha^i ] = i - * \alpha=x is the primitive element of GF(2^m) - * - * For efficiency, gf_exp[] has size 2*GF_SIZE, so that a simple - * multiplication of two numbers can be resolved without calling modnn - */ - -/* - * i use malloc so many times, it is easier to put checks all in - * one place. - */ -static void * -my_malloc(int sz, const char *err_string) -{ - void *p = malloc( sz ); - if (p == NULL) { - fprintf(stderr, "-- malloc failure allocating %s\n", err_string); - exit(1) ; - } - return p ; -} - -#define NEW_GF_MATRIX(rows, cols) \ - (gf *)my_malloc(rows * cols * sizeof(gf), " ## __LINE__ ## " ) - -/* - * initialize the data structures used for computations in GF. - */ -static void -generate_gf(void) -{ - int i; - gf mask; - const char *Pp = allPp[GF_BITS] ; - - mask = 1; /* x ** 0 = 1 */ - gf_exp[GF_BITS] = 0; /* will be updated at the end of the 1st loop */ - /* - * first, generate the (polynomial representation of) powers of \alpha, - * which are stored in gf_exp[i] = \alpha ** i . - * At the same time build gf_log[gf_exp[i]] = i . - * The first GF_BITS powers are simply bits shifted to the left. - */ - for (i = 0; i < GF_BITS; i++, mask <<= 1 ) { - gf_exp[i] = mask; - gf_log[gf_exp[i]] = i; - /* - * If Pp[i] == 1 then \alpha ** i occurs in poly-repr - * gf_exp[GF_BITS] = \alpha ** GF_BITS - */ - if ( Pp[i] == '1' ) - gf_exp[GF_BITS] ^= mask; - } - /* - * now gf_exp[GF_BITS] = \alpha ** GF_BITS is complete, so can als - * compute its inverse. - */ - gf_log[gf_exp[GF_BITS]] = GF_BITS; - /* - * Poly-repr of \alpha ** (i+1) is given by poly-repr of - * \alpha ** i shifted left one-bit and accounting for any - * \alpha ** GF_BITS term that may occur when poly-repr of - * \alpha ** i is shifted. - */ - mask = 1 << (GF_BITS - 1 ) ; - for (i = GF_BITS + 1; i < GF_SIZE; i++) { - if (gf_exp[i - 1] >= mask) - gf_exp[i] = gf_exp[GF_BITS] ^ ((gf_exp[i - 1] ^ mask) << 1); - else - gf_exp[i] = gf_exp[i - 1] << 1; - gf_log[gf_exp[i]] = i; - } - /* - * log(0) is not defined, so use a special value - */ - gf_log[0] = GF_SIZE ; - /* set the extended gf_exp values for fast multiply */ - for (i = 0 ; i < GF_SIZE ; i++) - gf_exp[i + GF_SIZE] = gf_exp[i] ; - - /* - * again special cases. 0 has no inverse. This used to - * be initialized to GF_SIZE, but it should make no difference - * since noone is supposed to read from here. - */ - inverse[0] = 0 ; - inverse[1] = 1; - for (i=2; i<=GF_SIZE; i++) - inverse[i] = gf_exp[GF_SIZE-gf_log[i]]; -} - -/* - * Various linear algebra operations that i use often. - */ - -/* - * addmul() computes dst[] = dst[] + c * src[] - * This is used often, so better optimize it! Currently the loop is - * unrolled 16 times, a good value for 486 and pentium-class machines. - * The case c=0 is also optimized, whereas c=1 is not. These - * calls are unfrequent in my typical apps so I did not bother. - * - * Note that gcc on - */ -#define addmul(dst, src, c, sz) \ - if (c != 0) addmul1(dst, src, c, sz) - -#define UNROLL 16 /* 1, 4, 8, 16 */ -static void -addmul1(gf *dst1, gf *src1, gf c, int sz) -{ - USE_GF_MULC ; - gf *dst = dst1, *src = src1 ; - gf *lim = &dst[sz - UNROLL + 1] ; - - GF_MULC0(c) ; - -#if (UNROLL > 1) /* unrolling by 8/16 is quite effective on the pentium */ - for (; dst < lim ; dst += UNROLL, src += UNROLL ) { - GF_ADDMULC( dst[0] , src[0] ); - GF_ADDMULC( dst[1] , src[1] ); - GF_ADDMULC( dst[2] , src[2] ); - GF_ADDMULC( dst[3] , src[3] ); -#if (UNROLL > 4) - GF_ADDMULC( dst[4] , src[4] ); - GF_ADDMULC( dst[5] , src[5] ); - GF_ADDMULC( dst[6] , src[6] ); - GF_ADDMULC( dst[7] , src[7] ); -#endif -#if (UNROLL > 8) - GF_ADDMULC( dst[8] , src[8] ); - GF_ADDMULC( dst[9] , src[9] ); - GF_ADDMULC( dst[10] , src[10] ); - GF_ADDMULC( dst[11] , src[11] ); - GF_ADDMULC( dst[12] , src[12] ); - GF_ADDMULC( dst[13] , src[13] ); - GF_ADDMULC( dst[14] , src[14] ); - GF_ADDMULC( dst[15] , src[15] ); -#endif - } -#endif - lim += UNROLL - 1 ; - for (; dst < lim; dst++, src++ ) /* final components */ - GF_ADDMULC( *dst , *src ); -} - -/* - * computes C = AB where A is n*k, B is k*m, C is n*m - */ -static void -matmul(gf *a, gf *b, gf *c, int n, int k, int m) -{ - int row, col, i ; - - for (row = 0; row < n ; row++) { - for (col = 0; col < m ; col++) { - gf *pa = &a[ row * k ]; - gf *pb = &b[ col ]; - gf acc = 0 ; - for (i = 0; i < k ; i++, pa++, pb += m ) - acc ^= gf_mul( *pa, *pb ) ; - c[ row * m + col ] = acc ; - } - } -} - -#ifdef DEBUGG -/* - * returns 1 if the square matrix is identiy - * (only for test) - */ -static int -is_identity(gf *m, int k) -{ - int row, col ; - for (row=0; row<k; row++) - for (col=0; col<k; col++) - if ( (row==col && *m != 1) || - (row!=col && *m != 0) ) - return 0 ; - else - m++ ; - return 1 ; -} -#endif /* debug */ - -/* - * invert_mat() takes a matrix and produces its inverse - * k is the size of the matrix. - * (Gauss-Jordan, adapted from Numerical Recipes in C) - * Return non-zero if singular. - */ -DEB( int pivloops=0; int pivswaps=0 ; /* diagnostic */) -static int -invert_mat(gf *src, int k) -{ - gf c, *p ; - int irow, icol, row, col, i, ix ; - - int error = 1 ; - int *indxc = (int*)my_malloc(k*sizeof(int), "indxc"); - int *indxr = (int*)my_malloc(k*sizeof(int), "indxr"); - int *ipiv = (int*)my_malloc(k*sizeof(int), "ipiv"); - gf *id_row = NEW_GF_MATRIX(1, k); - gf *temp_row = NEW_GF_MATRIX(1, k); - - bzero(id_row, k*sizeof(gf)); - DEB( pivloops=0; pivswaps=0 ; /* diagnostic */ ) - /* - * ipiv marks elements already used as pivots. - */ - for (i = 0; i < k ; i++) - ipiv[i] = 0 ; - - for (col = 0; col < k ; col++) { - gf *pivot_row ; - /* - * Zeroing column 'col', look for a non-zero element. - * First try on the diagonal, if it fails, look elsewhere. - */ - irow = icol = -1 ; - if (ipiv[col] != 1 && src[col*k + col] != 0) { - irow = col ; - icol = col ; - goto found_piv ; - } - for (row = 0 ; row < k ; row++) { - if (ipiv[row] != 1) { - for (ix = 0 ; ix < k ; ix++) { - DEB( pivloops++ ; ) - if (ipiv[ix] == 0) { - if (src[row*k + ix] != 0) { - irow = row ; - icol = ix ; - goto found_piv ; - } - } else if (ipiv[ix] > 1) { - fprintf(stderr, "singular matrix\n"); - goto fail ; - } - } - } - } - if (icol == -1) { - fprintf(stderr, "XXX pivot not found!\n"); - goto fail ; - } -found_piv: - ++(ipiv[icol]) ; - /* - * swap rows irow and icol, so afterwards the diagonal - * element will be correct. Rarely done, not worth - * optimizing. - */ - if (irow != icol) { - for (ix = 0 ; ix < k ; ix++ ) { - SWAP( src[irow*k + ix], src[icol*k + ix], gf) ; - } - } - indxr[col] = irow ; - indxc[col] = icol ; - pivot_row = &src[icol*k] ; - c = pivot_row[icol] ; - if (c == 0) { - fprintf(stderr, "singular matrix 2\n"); - goto fail ; - } - if (c != 1 ) { /* otherwhise this is a NOP */ - /* - * this is done often , but optimizing is not so - * fruitful, at least in the obvious ways (unrolling) - */ - DEB( pivswaps++ ; ) - c = inverse[ c ] ; - pivot_row[icol] = 1 ; - for (ix = 0 ; ix < k ; ix++ ) - pivot_row[ix] = gf_mul(c, pivot_row[ix] ); - } - /* - * from all rows, remove multiples of the selected row - * to zero the relevant entry (in fact, the entry is not zero - * because we know it must be zero). - * (Here, if we know that the pivot_row is the identity, - * we can optimize the addmul). - */ - id_row[icol] = 1; - if (bcmp(pivot_row, id_row, k*sizeof(gf)) != 0) { - for (p = src, ix = 0 ; ix < k ; ix++, p += k ) { - if (ix != icol) { - c = p[icol] ; - p[icol] = 0 ; - addmul(p, pivot_row, c, k ); - } - } - } - id_row[icol] = 0; - } /* done all columns */ - for (col = k-1 ; col >= 0 ; col-- ) { - if (indxr[col] <0 || indxr[col] >= k) - fprintf(stderr, "AARGH, indxr[col] %d\n", indxr[col]); - else if (indxc[col] <0 || indxc[col] >= k) - fprintf(stderr, "AARGH, indxc[col] %d\n", indxc[col]); - else - if (indxr[col] != indxc[col] ) { - for (row = 0 ; row < k ; row++ ) { - SWAP( src[row*k + indxr[col]], src[row*k + indxc[col]], gf) ; - } - } - } - error = 0 ; -fail: - free(indxc); - free(indxr); - free(ipiv); - free(id_row); - free(temp_row); - return error ; -} - -/* - * fast code for inverting a vandermonde matrix. - * XXX NOTE: It assumes that the matrix - * is not singular and _IS_ a vandermonde matrix. Only uses - * the second column of the matrix, containing the p_i's. - * - * Algorithm borrowed from "Numerical recipes in C" -- sec.2.8, but - * largely revised for my purposes. - * p = coefficients of the matrix (p_i) - * q = values of the polynomial (known) - */ - -int -invert_vdm(gf *src, int k) -{ - int i, j, row, col ; - gf *b, *c, *p; - gf t, xx ; - - if (k == 1) /* degenerate case, matrix must be p^0 = 1 */ - return 0 ; - /* - * c holds the coefficient of P(x) = Prod (x - p_i), i=0..k-1 - * b holds the coefficient for the matrix inversion - */ - c = NEW_GF_MATRIX(1, k); - b = NEW_GF_MATRIX(1, k); - - p = NEW_GF_MATRIX(1, k); - - for ( j=1, i = 0 ; i < k ; i++, j+=k ) { - c[i] = 0 ; - p[i] = src[j] ; /* p[i] */ - } - /* - * construct coeffs. recursively. We know c[k] = 1 (implicit) - * and start P_0 = x - p_0, then at each stage multiply by - * x - p_i generating P_i = x P_{i-1} - p_i P_{i-1} - * After k steps we are done. - */ - c[k-1] = p[0] ; /* really -p(0), but x = -x in GF(2^m) */ - for (i = 1 ; i < k ; i++ ) { - gf p_i = p[i] ; /* see above comment */ - for (j = k-1 - ( i - 1 ) ; j < k-1 ; j++ ) - c[j] ^= gf_mul( p_i, c[j+1] ) ; - c[k-1] ^= p_i ; - } - - for (row = 0 ; row < k ; row++ ) { - /* - * synthetic division etc. - */ - xx = p[row] ; - t = 1 ; - b[k-1] = 1 ; /* this is in fact c[k] */ - for (i = k-2 ; i >= 0 ; i-- ) { - b[i] = c[i+1] ^ gf_mul(xx, b[i+1]) ; - t = gf_mul(xx, t) ^ b[i] ; - } - for (col = 0 ; col < k ; col++ ) - src[col*k + row] = gf_mul(inverse[t], b[col] ); - } - free(c) ; - free(b) ; - free(p) ; - return 0 ; -} - -static int fec_initialized = 0 ; -static void -init_fec() -{ - TICK(ticks[0]); - generate_gf(); - TOCK(ticks[0]); - DDB(fprintf(stderr, "generate_gf took %ldus\n", ticks[0]);) - TICK(ticks[0]); - init_mul_table(); - TOCK(ticks[0]); - DDB(fprintf(stderr, "init_mul_table took %ldus\n", ticks[0]);) - fec_initialized = 1 ; -} - -/* - * This section contains the proper FEC encoding/decoding routines. - * The encoding matrix is computed starting with a Vandermonde matrix, - * and then transforming it into a systematic matrix. - */ - -#define FEC_MAGIC 0xFECC0DEC - -void -fec_free(struct fec_parms *p) -{ - if (p==NULL || - p->magic != ( ( (FEC_MAGIC ^ p->k) ^ p->n) ^ (unsigned long)(p->enc_matrix)) ) { - fprintf(stderr, "bad parameters to fec_free\n"); - return ; - } - free(p->enc_matrix); - free(p); -} - -/* - * create a new encoder, returning a descriptor. This contains k,n and - * the encoding matrix. - */ -struct fec_parms * -fec_new(int k, int n) -{ - int row, col ; - gf *p, *tmp_m ; - - struct fec_parms *retval ; - - if (fec_initialized == 0) - init_fec(); - - if (k > GF_SIZE + 1 || n > GF_SIZE + 1 || k > n ) { - fprintf(stderr, "Invalid parameters k %d n %d GF_SIZE %d\n", - k, n, GF_SIZE ); - return NULL ; - } - retval = (struct fec_parms *)my_malloc(sizeof(struct fec_parms), "new_code"); - retval->k = k ; - retval->n = n ; - retval->enc_matrix = NEW_GF_MATRIX(n, k); - retval->magic = ( ( FEC_MAGIC ^ k) ^ n) ^ (unsigned long)(retval->enc_matrix) ; - tmp_m = NEW_GF_MATRIX(n, k); - /* - * fill the matrix with powers of field elements, starting from 0. - * The first row is special, cannot be computed with exp. table. - */ - tmp_m[0] = 1 ; - for (col = 1; col < k ; col++) - tmp_m[col] = 0 ; - for (p = tmp_m + k, row = 0; row < n-1 ; row++, p += k) { - for ( col = 0 ; col < k ; col ++ ) - p[col] = gf_exp[modnn(row*col)]; - } - - /* - * quick code to build systematic matrix: invert the top - * k*k vandermonde matrix, multiply right the bottom n-k rows - * by the inverse, and construct the identity matrix at the top. - */ - TICK(ticks[3]); - invert_vdm(tmp_m, k); /* much faster than invert_mat */ - matmul(tmp_m + k*k, tmp_m, retval->enc_matrix + k*k, n - k, k, k); - /* - * the upper matrix is I so do not bother with a slow multiply - */ - bzero(retval->enc_matrix, k*k*sizeof(gf) ); - for (p = retval->enc_matrix, col = 0 ; col < k ; col++, p += k+1 ) - *p = 1 ; - free(tmp_m); - TOCK(ticks[3]); - - DDB(fprintf(stderr, "--- %ld us to build encoding matrix\n", - ticks[3]);) - DEB(pr_matrix(retval->enc_matrix, n, k, "encoding_matrix");) - return retval ; -} - -/* - * fec_encode accepts as input pointers to n data packets of size sz, - * and produces as output a packet pointed to by fec, computed - * with index "index". - */ -void -fec_encode(struct fec_parms *code, gf *src[], gf *fec, int index, int sz) -{ - int i, k = code->k ; - gf *p ; - - if (GF_BITS > 8) - sz /= 2 ; - - if (index < k) - bcopy(src[index], fec, sz*sizeof(gf) ) ; - else if (index < code->n) { - p = &(code->enc_matrix[index*k] ); - bzero(fec, sz*sizeof(gf)); - for (i = 0; i < k ; i++) - addmul(fec, src[i], p[i], sz ) ; - } else - fprintf(stderr, "Invalid index %d (max %d)\n", - index, code->n - 1 ); -} - -/* - * shuffle move src packets in their position - */ -static int -shuffle(gf *pkt[], int index[], int k) -{ - int i; - - for ( i = 0 ; i < k ; ) { - if (index[i] >= k || index[i] == i) - i++ ; - else { - /* - * put pkt in the right position (first check for conflicts). - */ - int c = index[i] ; - - if (index[c] == c) { - DEB(fprintf(stderr, "\nshuffle, error at %d\n", i);) - return 1 ; - } - SWAP(index[i], index[c], int) ; - SWAP(pkt[i], pkt[c], gf *) ; - } - } - DEB( /* just test that it works... */ - for ( i = 0 ; i < k ; i++ ) { - if (index[i] < k && index[i] != i) { - fprintf(stderr, "shuffle: after\n"); - for (i=0; i<k ; i++) fprintf(stderr, "%3d ", index[i]); - fprintf(stderr, "\n"); - return 1 ; - } - } - ) - return 0 ; -} - -/* - * build_decode_matrix constructs the encoding matrix given the - * indexes. The matrix must be already allocated as - * a vector of k*k elements, in row-major order - */ -static gf * -build_decode_matrix(struct fec_parms *code, gf *pkt[], int index[]) -{ - int i , k = code->k ; - gf *p, *matrix = NEW_GF_MATRIX(k, k); - - TICK(ticks[9]); - for (i = 0, p = matrix ; i < k ; i++, p += k ) { -#if 1 /* this is simply an optimization, not very useful indeed */ - if (index[i] < k) { - bzero(p, k*sizeof(gf) ); - p[i] = 1 ; - } else -#endif - if (index[i] < code->n ) - bcopy( &(code->enc_matrix[index[i]*k]), p, k*sizeof(gf) ); - else { - fprintf(stderr, "decode: invalid index %d (max %d)\n", - index[i], code->n - 1 ); - free(matrix) ; - return NULL ; - } - } - TICK(ticks[9]); - if (invert_mat(matrix, k)) { - free(matrix); - matrix = NULL ; - } - TOCK(ticks[9]); - return matrix ; -} - -/* - * fec_decode receives as input a vector of packets, the indexes of - * packets, and produces the correct vector as output. - * - * Input: - * code: pointer to code descriptor - * pkt: pointers to received packets. They are modified - * to store the output packets (in place) - * index: pointer to packet indexes (modified) - * sz: size of each packet - */ -int -fec_decode(struct fec_parms *code, gf *pkt[], int index[], int sz) -{ - gf *m_dec ; - gf **new_pkt ; - int row, col , k = code->k ; - - if (GF_BITS > 8) - sz /= 2 ; - - if (shuffle(pkt, index, k)) /* error if true */ - return 1 ; - m_dec = build_decode_matrix(code, pkt, index); - - if (m_dec == NULL) - return 1 ; /* error */ - /* - * do the actual decoding - */ - new_pkt = (gf**)my_malloc (k * sizeof (gf * ), "new pkt pointers" ); - for (row = 0 ; row < k ; row++ ) { - if (index[row] >= k) { - new_pkt[row] = (gf*) my_malloc (sz * sizeof (gf), "new pkt buffer" ); - bzero(new_pkt[row], sz * sizeof(gf) ) ; - for (col = 0 ; col < k ; col++ ) - addmul(new_pkt[row], pkt[col], m_dec[row*k + col], sz) ; - } - } - /* - * move pkts to their final destination - */ - for (row = 0 ; row < k ; row++ ) { - if (index[row] >= k) { - bcopy(new_pkt[row], pkt[row], sz*sizeof(gf)); - free(new_pkt[row]); - } - } - free(new_pkt); - free(m_dec); - - return 0; -} diff --git a/libtransport/src/core/fec.h b/libtransport/src/core/fec.h deleted file mode 100644 index 8234057a7..000000000 --- a/libtransport/src/core/fec.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * fec.c -- forward error correction based on Vandermonde matrices - * 980614 - * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) - * - * Portions derived from code by Phil Karn (karn@ka9q.ampr.org), - * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari - * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -/* - * The following parameter defines how many bits are used for - * field elements. The code supports any value from 2 to 16 - * but fastest operation is achieved with 8 bit elements - * This is the only parameter you may want to change. - */ -#ifndef GF_BITS -#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */ -#endif - -#if (GF_BITS <= 8) -typedef unsigned char gf; -#else -typedef unsigned short gf; -#endif - -#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */ - -struct fec_parms { - unsigned long magic ; - int k, n ; /* parameters of the code */ - gf *enc_matrix ; -}; - -void fec_free(struct fec_parms *p) ; -struct fec_parms *fec_new(int k, int n) ; - -void fec_encode(struct fec_parms *code, gf *src[], gf *fec, int index, int sz); -int fec_decode(struct fec_parms *code, gf *pkt[], int index[], int sz); - -/* end of file */ diff --git a/libtransport/src/core/forwarder_interface.h b/libtransport/src/core/forwarder_interface.h deleted file mode 100644 index a94414d38..000000000 --- a/libtransport/src/core/forwarder_interface.h +++ /dev/null @@ -1,149 +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. - */ - -#pragma once - -#include <core/udp_socket_connector.h> -#include <hicn/transport/core/prefix.h> -#include <hicn/transport/portability/portability.h> -#include <hicn/transport/utils/chrono_typedefs.h> - -#include <deque> - -namespace transport { - -namespace core { - -typedef struct { - uint64_t rx_packets; - uint64_t tx_packets; - uint64_t rx_bytes; - uint64_t tx_bytes; - uint64_t rx_errors; - uint64_t tx_errors; -} Counters; - -template <typename Implementation, typename ConnectorType> -class ForwarderInterface { - static_assert(std::is_base_of<Connector, ConnectorType>::value, - "T must inherit from connector!"); - - static constexpr uint32_t standard_cs_reserved = 5000; - - protected: - ForwarderInterface(ConnectorType &c) - : connector_(c), - inet_address_({}), - inet6_address_({}), - mtu_(1500), - output_interface_(""), - content_store_reserved_(standard_cs_reserved) { - inet_address_.v4.as_u32 = htonl(0x7f00001); - inet6_address_.v6.as_u8[15] = 0x01; - } - - public: - virtual ~ForwarderInterface() {} - - TRANSPORT_ALWAYS_INLINE void connect(bool is_consumer = true) { - static_cast<Implementation &>(*this).connect(is_consumer); - } - - TRANSPORT_ALWAYS_INLINE void registerRoute(Prefix &prefix) { - static_cast<Implementation &>(*this).registerRoute(); - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t getMtu() { - return static_cast<Implementation &>(*this).getMtu(); - } - - TRANSPORT_ALWAYS_INLINE static bool isControlMessage(const uint8_t *message) { - return Implementation::isControlMessageImpl(message); - } - - template <typename R> - TRANSPORT_ALWAYS_INLINE void processControlMessageReply(R &&packet_buffer) { - return static_cast<Implementation &>(*this).processControlMessageReplyImpl( - std::forward<R &&>(packet_buffer)); - } - - TRANSPORT_ALWAYS_INLINE void closeConnection() { - return static_cast<Implementation &>(*this).closeConnection(); - } - - template < - typename R, - typename = std::enable_if_t< - std::is_base_of<Packet, typename std::remove_reference_t<R>>::value, - R>> - TRANSPORT_ALWAYS_INLINE void send(R &&packet) { - counters_.tx_packets++; - counters_.tx_bytes += packet.payloadSize() + packet.headerSize(); - - if (_is_ipv4(packet.getFormat())) { - packet.setLocator(inet_address_); - } else { - packet.setLocator(inet6_address_); - } - -#ifndef __vpp__ - /* In the case of VPP we try to offload checksum computation to hardware */ - packet.setChecksum(); -#endif - connector_.send(packet.acquireMemBufReference()); - } - - TRANSPORT_ALWAYS_INLINE void send(const uint8_t *packet, std::size_t len) { - counters_.tx_packets++; - counters_.tx_bytes += len; - - // Perfect forwarding - connector_.send(packet, len); - } - - TRANSPORT_ALWAYS_INLINE void shutdown() { connector_.close(); } - - TRANSPORT_ALWAYS_INLINE Connector &getConnector() { return connector_; } - - TRANSPORT_ALWAYS_INLINE void setContentStoreSize(uint32_t cs_size) { - content_store_reserved_ = cs_size; - } - - TRANSPORT_ALWAYS_INLINE uint32_t getContentStoreSize() const { - return content_store_reserved_; - } - - TRANSPORT_ALWAYS_INLINE void setOutputInterface( - const std::string &interface) { - output_interface_ = interface; - } - - TRANSPORT_ALWAYS_INLINE std::string &getOutputInterface() { - return output_interface_; - } - - protected: - ConnectorType &connector_; - ip_address_t inet_address_; - ip_address_t inet6_address_; - uint16_t mtu_; - std::string output_interface_; - uint32_t content_store_reserved_; - Counters counters_; -}; - -} // namespace core - -} // namespace transport diff --git a/libtransport/src/core/global_configuration.cc b/libtransport/src/core/global_configuration.cc index 3e37a30a4..9da37c2fa 100644 --- a/libtransport/src/core/global_configuration.cc +++ b/libtransport/src/core/global_configuration.cc @@ -14,8 +14,8 @@ */ #include <core/global_configuration.h> +#include <glog/logging.h> #include <hicn/transport/core/connector.h> -#include <hicn/transport/utils/log.h> #include <libconfig.h++> #include <map> @@ -32,11 +32,11 @@ bool GlobalConfiguration::parseTransportConfig(const std::string& path) { try { cfg.readFile(path.c_str()); } catch (const FileIOException& fioex) { - TRANSPORT_LOGE("I/O error while reading file: %s", fioex.what()); + LOG(ERROR) << "I/O error while reading file."; return false; } catch (const ParseException& pex) { - TRANSPORT_LOGE("Parse error at %s:%d - %s", pex.getFile(), pex.getLine(), - pex.getError()); + LOG(ERROR) << "Parse error at " << pex.getFile() << ":" << pex.getLine() + << " - " << pex.getError(); return false; } @@ -50,11 +50,11 @@ bool GlobalConfiguration::parseTransportConfig(const std::string& path) { for (auto section = root.begin(); section != root.end(); section++) { std::string name = section->getName(); std::error_code ec; - TRANSPORT_LOGD("Parsing Section: %s", name.c_str()); + VLOG(2) << "Parsing Section: " << name; auto it = configuration_parsers_.find(name); if (it != configuration_parsers_.end() && !it->second.first) { - TRANSPORT_LOGD("Found valid configuration parser"); + VLOG(2) << "Found valid configuration parser"; it->second.second(*section, ec); it->second.first = true; } @@ -64,18 +64,17 @@ bool GlobalConfiguration::parseTransportConfig(const std::string& path) { } void GlobalConfiguration::parseConfiguration(const std::string& path) { - // Check if an environment variable with the configuration path exists. COnf + // Check if an environment variable with the configuration path exists. Conf // variable comes first. std::unique_lock<std::mutex> lck(cp_mtx_); - if (const char* env_c = std::getenv(GlobalConfiguration::conf_file)) { parseTransportConfig(env_c); } else if (!path.empty()) { conf_file_path_ = path; parseTransportConfig(conf_file_path_); } else { - TRANSPORT_LOGD( - "Called parseConfiguration but no configuration file was provided."); + LOG(ERROR) + << "Called parseConfiguration but no configuration file was provided."; } } @@ -83,10 +82,9 @@ void GlobalConfiguration::registerConfigurationSetter( const std::string& key, const SetCallback& set_callback) { std::unique_lock<std::mutex> lck(cp_mtx_); if (configuration_setters_.find(key) != configuration_setters_.end()) { - TRANSPORT_LOGW( - "Trying to register configuration setter %s twice. Ignoring second " - "registration attempt.", - key.c_str()); + LOG(WARNING) << "Trying to register configuration setter " << key + << " twice. Ignoring second " + "registration attempt."; } else { configuration_setters_.emplace(key, set_callback); } @@ -96,10 +94,9 @@ void GlobalConfiguration::registerConfigurationGetter( const std::string& key, const GetCallback& get_callback) { std::unique_lock<std::mutex> lck(cp_mtx_); if (configuration_getters_.find(key) != configuration_getters_.end()) { - TRANSPORT_LOGW( - "Trying to register configuration getter %s twice. Ignoring second " - "registration attempt.", - key.c_str()); + LOG(WARNING) << "Trying to register configuration setter " << key + << " twice. Ignoring second " + "registration attempt."; } else { configuration_getters_.emplace(key, get_callback); } @@ -109,10 +106,9 @@ void GlobalConfiguration::registerConfigurationParser( const std::string& key, const ParserCallback& parser) { std::unique_lock<std::mutex> lck(cp_mtx_); if (configuration_parsers_.find(key) != configuration_parsers_.end()) { - TRANSPORT_LOGW( - "Trying to register configuration key %s twice. Ignoring second " - "registration attempt.", - key.c_str()); + LOG(WARNING) << "Trying to register configuration setter " << key + << " twice. Ignoring second " + "registration attempt."; } else { configuration_parsers_.emplace(key, std::make_pair(false, parser)); diff --git a/libtransport/src/core/hicn_forwarder_interface.cc b/libtransport/src/core/hicn_forwarder_interface.cc deleted file mode 100644 index 5a0faa360..000000000 --- a/libtransport/src/core/hicn_forwarder_interface.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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. - */ - -#include <core/hicn_forwarder_interface.h> - -union AddressLight { - uint32_t ipv4; - struct in6_addr ipv6; -}; - -typedef struct { - uint8_t message_type; - uint8_t command_id; - uint16_t length; - uint32_t seq_num; -} CommandHeader; - -typedef struct { - uint8_t message_type; - uint8_t command_id; - uint16_t length; - uint32_t seq_num; - char symbolic_or_connid[16]; - union AddressLight address; - uint16_t cost; - uint8_t address_type; - uint8_t len; -} RouteToSelfCommand; - -typedef struct { - uint8_t message_type; - uint8_t command_id; - uint16_t length; - uint32_t seq_num; - char symbolic_or_connid[16]; -} DeleteSelfConnectionCommand; - -namespace { -static constexpr uint8_t addr_inet = 1; -static constexpr uint8_t addr_inet6 = 2; -static constexpr uint8_t add_route_command = 3; -static constexpr uint8_t delete_connection_command = 5; -static constexpr uint8_t request_light = 0xc0; -static constexpr char identifier[] = "SELF"; - -void fillCommandHeader(CommandHeader *header) { - // Allocate and fill the header - header->message_type = request_light; - header->length = 1; -} - -RouteToSelfCommand createCommandRoute(std::unique_ptr<sockaddr> &&addr, - uint8_t prefix_length) { - RouteToSelfCommand command = {0}; - - // check and set IP address - if (addr->sa_family == AF_INET) { - command.address_type = addr_inet; - command.address.ipv4 = ((sockaddr_in *)addr.get())->sin_addr.s_addr; - } else if (addr->sa_family == AF_INET6) { - command.address_type = addr_inet6; - command.address.ipv6 = ((sockaddr_in6 *)addr.get())->sin6_addr; - } - - // Fill remaining payload fields -#ifndef _WIN32 - strcpy(command.symbolic_or_connid, identifier); -#else - strcpy_s(command.symbolic_or_connid, 16, identifier); -#endif - command.cost = 1; - command.len = (uint8_t)prefix_length; - - // Allocate and fill the header - command.command_id = add_route_command; - fillCommandHeader((CommandHeader *)&command); - - return command; -} - -DeleteSelfConnectionCommand createCommandDeleteConnection() { - DeleteSelfConnectionCommand command = {0}; - fillCommandHeader((CommandHeader *)&command); - command.command_id = delete_connection_command; - -#ifndef _WIN32 - strcpy(command.symbolic_or_connid, identifier); -#else - strcpy_s(command.symbolic_or_connid, 16, identifier); -#endif - - return command; -} - -} // namespace - -namespace transport { - -namespace core { - -HicnForwarderInterface::HicnForwarderInterface(UdpSocketConnector &connector) - : ForwarderInterface<HicnForwarderInterface, UdpSocketConnector>( - connector) {} - -HicnForwarderInterface::~HicnForwarderInterface() {} - -void HicnForwarderInterface::connect(bool is_consumer) { connector_.connect(); } - -void HicnForwarderInterface::registerRoute(Prefix &prefix) { - auto command = createCommandRoute(prefix.toSockaddr(), - (uint8_t)prefix.getPrefixLength()); - send((uint8_t *)&command, sizeof(RouteToSelfCommand)); -} - -void HicnForwarderInterface::closeConnection() { - auto command = createCommandDeleteConnection(); - send((uint8_t *)&command, sizeof(DeleteSelfConnectionCommand)); - connector_.close(); -} - -} // namespace core - -} // namespace transport diff --git a/libtransport/src/core/hicn_forwarder_interface.h b/libtransport/src/core/hicn_forwarder_interface.h deleted file mode 100644 index c4138c6c2..000000000 --- a/libtransport/src/core/hicn_forwarder_interface.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - */ - -#pragma once - -#include <hicn/transport/core/prefix.h> - -#include <core/forwarder_interface.h> -#include <core/udp_socket_connector.h> - -#include <deque> - -namespace transport { - -namespace core { - -class HicnForwarderInterface - : public ForwarderInterface<HicnForwarderInterface, UdpSocketConnector> { - static constexpr uint8_t ack_code = 0xc2; - static constexpr uint8_t nack_code = 0xc3; - - public: - union addressLight { - uint32_t ipv4; - struct in6_addr ipv6; - }; - - struct route_to_self_command { - uint8_t messageType; - uint8_t commandID; - uint16_t length; - uint32_t seqNum; - char symbolicOrConnid[16]; - union addressLight address; - uint16_t cost; - uint8_t addressType; - uint8_t len; - }; - - using route_to_self_command = struct route_to_self_command; - using ConnectorType = UdpSocketConnector; - - HicnForwarderInterface(UdpSocketConnector &connector); - - ~HicnForwarderInterface(); - - void connect(bool is_consumer); - - void registerRoute(Prefix &prefix); - - std::uint16_t getMtu() { return interface_mtu; } - - TRANSPORT_ALWAYS_INLINE static bool isControlMessageImpl( - const uint8_t *message) { - return message[0] == ack_code || message[0] == nack_code; - } - - TRANSPORT_ALWAYS_INLINE void processControlMessageReplyImpl( - Packet::MemBufPtr &&packet_buffer) { - if (packet_buffer->data()[0] == nack_code) { - throw errors::RuntimeException( - "Received Nack message from hicn light forwarder."); - } - } - - void closeConnection(); - - private: - static constexpr std::uint16_t interface_mtu = 1500; -}; - -} // namespace core - -} // namespace transport diff --git a/libtransport/src/core/hicn_vapi.c b/libtransport/src/core/hicn_vapi.c deleted file mode 100644 index be556f3aa..000000000 --- a/libtransport/src/core/hicn_vapi.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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. - */ - -#include <hicn/transport/config.h> - -#ifdef __vpp__ - -#include <hicn/transport/utils/log.h> -#include <core/hicn_vapi.h> - -#define HICN_VPP_PLUGIN -#include <hicn/name.h> -#undef HICN_VPP_PLUGIN - -#include <vapi/vapi_safe.h> -#include <vlib/vlib.h> -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <vppinfra/error.h> - -#include <vnet/ip/format.h> -#include <vnet/ip/ip4_packet.h> -#include <vnet/ip/ip6_packet.h> -#include <vapi/ip.api.vapi.h> - -#include <vapi/hicn.api.vapi.h> -#include <vpp_plugins/hicn/error.h> - -///////////////////////////////////////////////////// -const char *HICN_ERROR_STRING[] = { -#define _(a, b, c) c, - foreach_hicn_error -#undef _ -}; -///////////////////////////////////////////////////// - -/*********************** Missing Symbol in vpp libraries - * *************************/ -u8 *format_vl_api_address_union(u8 *s, va_list *args) { return NULL; } - -/*********************************************************************************/ - -DEFINE_VAPI_MSG_IDS_HICN_API_JSON -DEFINE_VAPI_MSG_IDS_IP_API_JSON - -static vapi_error_e register_prod_app_cb( - vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv, bool is_last, - vapi_payload_hicn_api_register_prod_app_reply *reply) { - hicn_producer_output_params *output_params = - (hicn_producer_output_params *)callback_ctx; - - if (reply == NULL) return rv; - - output_params->cs_reserved = reply->cs_reserved; - output_params->prod_addr = (ip_address_t *)malloc(sizeof(ip_address_t)); - memset(output_params->prod_addr, 0, sizeof(ip_address_t)); - if (reply->prod_addr.af == ADDRESS_IP6) - memcpy(&output_params->prod_addr->v6, reply->prod_addr.un.ip6, - sizeof(ip6_address_t)); - else - memcpy(&output_params->prod_addr->v4, reply->prod_addr.un.ip4, - sizeof(ip4_address_t)); - output_params->face_id = reply->faceid; - - return reply->retval; -} - -int hicn_vapi_register_prod_app(vapi_ctx_t ctx, - hicn_producer_input_params *input_params, - hicn_producer_output_params *output_params) { - vapi_lock(); - vapi_msg_hicn_api_register_prod_app *msg = - vapi_alloc_hicn_api_register_prod_app(ctx); - - if (ip46_address_is_ip4((ip46_address_t *)&input_params->prefix->address)) { - memcpy(&msg->payload.prefix.address.un.ip4, &input_params->prefix->address, - sizeof(ip4_address_t)); - msg->payload.prefix.address.af = ADDRESS_IP4; - } else { - memcpy(&msg->payload.prefix.address.un.ip6, &input_params->prefix->address, - sizeof(ip6_address_t)); - msg->payload.prefix.address.af = ADDRESS_IP6; - } - msg->payload.prefix.len = input_params->prefix->len; - - msg->payload.swif = input_params->swif; - msg->payload.cs_reserved = input_params->cs_reserved; - - int ret = vapi_hicn_api_register_prod_app(ctx, msg, register_prod_app_cb, - output_params); - vapi_unlock(); - return ret; -} - -static vapi_error_e face_prod_del_cb( - vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv, bool is_last, - vapi_payload_hicn_api_face_prod_del_reply *reply) { - if (reply == NULL) return rv; - - return reply->retval; -} - -int hicn_vapi_face_prod_del(vapi_ctx_t ctx, - hicn_del_face_app_input_params *input_params) { - vapi_lock(); - vapi_msg_hicn_api_face_prod_del *msg = vapi_alloc_hicn_api_face_prod_del(ctx); - - msg->payload.faceid = input_params->face_id; - - int ret = vapi_hicn_api_face_prod_del(ctx, msg, face_prod_del_cb, NULL); - vapi_unlock(); - return ret; -} - -static vapi_error_e register_cons_app_cb( - vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv, bool is_last, - vapi_payload_hicn_api_register_cons_app_reply *reply) { - hicn_consumer_output_params *output_params = - (hicn_consumer_output_params *)callback_ctx; - - if (reply == NULL) return rv; - - output_params->src6 = (ip_address_t *)malloc(sizeof(ip_address_t)); - output_params->src4 = (ip_address_t *)malloc(sizeof(ip_address_t)); - memset(output_params->src6, 0, sizeof(ip_address_t)); - memset(output_params->src4, 0, sizeof(ip_address_t)); - memcpy(&output_params->src6->v6, &reply->src_addr6.un.ip6, - sizeof(ip6_address_t)); - memcpy(&output_params->src4->v4, &reply->src_addr4.un.ip4, - sizeof(ip4_address_t)); - - output_params->face_id1 = reply->faceid1; - output_params->face_id2 = reply->faceid2; - - return reply->retval; -} - -int hicn_vapi_register_cons_app(vapi_ctx_t ctx, - hicn_consumer_input_params *input_params, - hicn_consumer_output_params *output_params) { - vapi_lock(); - vapi_msg_hicn_api_register_cons_app *msg = - vapi_alloc_hicn_api_register_cons_app(ctx); - - msg->payload.swif = input_params->swif; - - int ret = vapi_hicn_api_register_cons_app(ctx, msg, register_cons_app_cb, - output_params); - vapi_unlock(); - return ret; -} - -static vapi_error_e face_cons_del_cb( - vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv, bool is_last, - vapi_payload_hicn_api_face_cons_del_reply *reply) { - if (reply == NULL) return rv; - - return reply->retval; -} - -int hicn_vapi_face_cons_del(vapi_ctx_t ctx, - hicn_del_face_app_input_params *input_params) { - vapi_lock(); - vapi_msg_hicn_api_face_cons_del *msg = vapi_alloc_hicn_api_face_cons_del(ctx); - - msg->payload.faceid = input_params->face_id; - - int ret = vapi_hicn_api_face_cons_del(ctx, msg, face_cons_del_cb, NULL); - vapi_unlock(); - return ret; -} - -static vapi_error_e reigster_route_cb( - vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv, bool is_last, - vapi_payload_ip_route_add_del_reply *reply) { - if (reply == NULL) return rv; - - return reply->retval; -} - -int hicn_vapi_register_route(vapi_ctx_t ctx, - hicn_producer_set_route_params *input_params) { - vapi_lock(); - vapi_msg_ip_route_add_del *msg = vapi_alloc_ip_route_add_del(ctx, 1); - - msg->payload.is_add = 1; - if (ip46_address_is_ip4((ip46_address_t *)(input_params->prod_addr))) { - memcpy(&msg->payload.route.prefix.address.un.ip4, &input_params->prefix->address.v4, - sizeof(ip4_address_t)); - msg->payload.route.prefix.address.af = ADDRESS_IP4; - msg->payload.route.prefix.len = input_params->prefix->len; - } else { - memcpy(&msg->payload.route.prefix.address.un.ip6, &input_params->prefix->address.v6, - sizeof(ip6_address_t)); - msg->payload.route.prefix.address.af = ADDRESS_IP6; - msg->payload.route.prefix.len = input_params->prefix->len; - } - - msg->payload.route.paths[0].sw_if_index = ~0; - msg->payload.route.paths[0].table_id = 0; - if (ip46_address_is_ip4((ip46_address_t *)(input_params->prod_addr))) { - memcpy(&(msg->payload.route.paths[0].nh.address.ip4), input_params->prod_addr->v4.as_u8, sizeof(ip4_address_t)); - msg->payload.route.paths[0].proto = FIB_API_PATH_NH_PROTO_IP4; - } - else{ - memcpy(&(msg->payload.route.paths[0].nh.address.ip6), input_params->prod_addr->v6.as_u8, sizeof(ip6_address_t)); - msg->payload.route.paths[0].proto = FIB_API_PATH_NH_PROTO_IP6; - } - - msg->payload.route.paths[0].type = FIB_API_PATH_FLAG_NONE; - msg->payload.route.paths[0].flags = FIB_API_PATH_FLAG_NONE; - - int ret = vapi_ip_route_add_del(ctx, msg, reigster_route_cb, NULL); - - vapi_unlock(); - return ret; -} - -char *hicn_vapi_get_error_string(int ret_val) { - return get_error_string(ret_val); -} - -#endif // __vpp__ diff --git a/libtransport/src/core/hicn_vapi.h b/libtransport/src/core/hicn_vapi.h deleted file mode 100644 index f5d61e7ef..000000000 --- a/libtransport/src/core/hicn_vapi.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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. - */ - -#pragma once - -#include <hicn/transport/config.h> -#include <hicn/util/ip_address.h> - -#ifdef __vpp__ - - - -#ifdef __cplusplus -extern "C" { -#endif - -#include <vapi/vapi.h> - -#include "stdint.h" - -typedef struct { - ip_prefix_t* prefix; - uint32_t swif; - uint32_t cs_reserved; -} hicn_producer_input_params; - -typedef struct { - uint32_t swif; -} hicn_consumer_input_params; - -typedef struct { - uint32_t face_id; -} hicn_del_face_app_input_params; - -typedef struct { - uint32_t cs_reserved; - ip_address_t* prod_addr; - uint32_t face_id; -} hicn_producer_output_params; - -typedef struct { - ip_address_t* src4; - ip_address_t* src6; - uint32_t face_id1; - uint32_t face_id2; -} hicn_consumer_output_params; - -typedef struct { - ip_prefix_t* prefix; - ip_address_t* prod_addr; -} hicn_producer_set_route_params; - -int hicn_vapi_register_prod_app( - vapi_ctx_t ctx, hicn_producer_input_params* input_params, - hicn_producer_output_params* output_params); - -int hicn_vapi_register_cons_app( - vapi_ctx_t ctx, hicn_consumer_input_params* input_params, - hicn_consumer_output_params* output_params); - -int hicn_vapi_register_route( - vapi_ctx_t ctx, hicn_producer_set_route_params* input_params); - -int hicn_vapi_face_cons_del( - vapi_ctx_t ctx, hicn_del_face_app_input_params *input_params); - -int hicn_vapi_face_prod_del( - vapi_ctx_t ctx, hicn_del_face_app_input_params *input_params); - -char* hicn_vapi_get_error_string(int ret_val); - -#ifdef __cplusplus -} -#endif - -#endif // __vpp__ diff --git a/libtransport/src/core/interest.cc b/libtransport/src/core/interest.cc index b4a74762d..9d868ced0 100644 --- a/libtransport/src/core/interest.cc +++ b/libtransport/src/core/interest.cc @@ -101,18 +101,6 @@ void Interest::setName(const Name &name) { } } -void Interest::setName(Name &&name) { - if (hicn_interest_set_name(format_, packet_start_, - name.getStructReference()) < 0) { - throw errors::RuntimeException("Error setting interest name."); - } - - if (hicn_interest_get_name(format_, packet_start_, - name_.getStructReference()) < 0) { - throw errors::MalformedPacketException(); - } -} - void Interest::setLocator(const ip_address_t &ip_address) { if (hicn_interest_set_locator(format_, packet_start_, &ip_address) < 0) { throw errors::RuntimeException("Error setting interest locator."); @@ -175,8 +163,9 @@ void Interest::encodeSuffixes() { // We assume interest does not hold signature for the moment. auto int_manifest_header = (InterestManifestHeader *)(writableData() + headerSize()); - int_manifest_header->n_suffixes = (uint32_t)suffix_set_.size(); + int_manifest_header->n_suffixes = suffix_set_.size(); std::size_t additional_length = + sizeof(InterestManifestHeader) + int_manifest_header->n_suffixes * sizeof(uint32_t); uint32_t *suffix = (uint32_t *)(int_manifest_header + 1); @@ -184,6 +173,7 @@ void Interest::encodeSuffixes() { *suffix = *it; } + append(additional_length); updateLength(additional_length); } diff --git a/libtransport/src/core/io_module.cc b/libtransport/src/core/io_module.cc index 7c2ec2cab..a751eabf5 100644 --- a/libtransport/src/core/io_module.cc +++ b/libtransport/src/core/io_module.cc @@ -16,8 +16,8 @@ #ifndef _WIN32 #include <dlfcn.h> #endif +#include <glog/logging.h> #include <hicn/transport/core/io_module.h> -#include <hicn/transport/utils/log.h> #ifdef ANDROID #include <io_modules/udp/hicn_forwarder_module.h> @@ -45,16 +45,16 @@ IoModule *IoModule::load(const char *module_name) { handle = dlopen(module_name, RTLD_NOW); if (!handle) { if ((error = dlerror()) != 0) { - TRANSPORT_LOGE("%s", error); + LOG(ERROR) << error; } return 0; } - // link factory method + // get factory method creator = (IoModule * (*)(void)) dlsym(handle, "create_module"); if (!creator) { if ((error = dlerror()) != 0) { - TRANSPORT_LOGE("%s", error); + LOG(ERROR) << error; return 0; } } diff --git a/libtransport/src/core/local_connector.cc b/libtransport/src/core/local_connector.cc index f0e36a3d7..50dadc677 100644 --- a/libtransport/src/core/local_connector.cc +++ b/libtransport/src/core/local_connector.cc @@ -14,12 +14,11 @@ */ #include <core/local_connector.h> +#include <glog/logging.h> +#include <hicn/transport/core/asio_wrapper.h> #include <hicn/transport/core/content_object.h> #include <hicn/transport/core/interest.h> #include <hicn/transport/errors/not_implemented_exception.h> -#include <hicn/transport/utils/log.h> - -#include <asio/io_service.hpp> namespace transport { namespace core { @@ -33,7 +32,7 @@ void LocalConnector::send(Packet &packet) { return; } - TRANSPORT_LOGD("Sending packet to local socket."); + DLOG_IF(INFO, VLOG_IS_ON(3)) << "Sending packet to local socket."; io_service_.get().post([this, p{packet.shared_from_this()}]() mutable { receive_callback_(this, *p, std::make_error_code(std::errc(0))); }); diff --git a/libtransport/src/core/local_connector.h b/libtransport/src/core/local_connector.h index b0daa4f53..0e2d8f676 100644 --- a/libtransport/src/core/local_connector.h +++ b/libtransport/src/core/local_connector.h @@ -15,17 +15,13 @@ #pragma once +#include <hicn/transport/core/asio_wrapper.h> #include <hicn/transport/core/connector.h> #include <hicn/transport/core/global_object_pool.h> #include <hicn/transport/utils/move_wrapper.h> #include <hicn/transport/utils/shared_ptr_utils.h> #include <io_modules/forwarder/errors.h> -#ifndef ASIO_STANDALONE -#define ASIO_STANDALONE -#endif -#include <asio/io_service.hpp> - namespace transport { namespace core { diff --git a/libtransport/src/core/manifest_format.h b/libtransport/src/core/manifest_format.h index b759942cb..90d221f5e 100644 --- a/libtransport/src/core/manifest_format.h +++ b/libtransport/src/core/manifest_format.h @@ -15,7 +15,7 @@ #pragma once -#include <hicn/transport/auth/crypto_hasher.h> +#include <hicn/transport/auth/crypto_hash.h> #include <hicn/transport/core/name.h> #include <cinttypes> diff --git a/libtransport/src/core/manifest_format_fixed.cc b/libtransport/src/core/manifest_format_fixed.cc index 7076a4c90..11d4a56cb 100644 --- a/libtransport/src/core/manifest_format_fixed.cc +++ b/libtransport/src/core/manifest_format_fixed.cc @@ -34,7 +34,7 @@ FixedManifestEncoder::FixedManifestEncoder(Packet &packet, current_entry_(0), signature_size_(signature_size) { if (clear) { - memset(manifest_header_, 0, sizeof(*manifest_header_)); + *manifest_header_ = {0}; } } @@ -51,7 +51,7 @@ FixedManifestEncoder &FixedManifestEncoder::clearImpl() { packet_.trimEnd(sizeof(ManifestHeader) + manifest_header_->number_of_entries * sizeof(ManifestEntry)); current_entry_ = 0; - memset(manifest_header_, 0, sizeof(*manifest_header_)); + *manifest_header_ = {0}; return *this; } @@ -85,8 +85,8 @@ FixedManifestEncoder &FixedManifestEncoder::setBaseNameImpl( FixedManifestEncoder &FixedManifestEncoder::addSuffixAndHashImpl( uint32_t suffix, const auth::CryptoHash &hash) { - auto _hash = hash.getDigest<std::uint8_t>(); - addSuffixHashBytes(suffix, _hash.data(), _hash.length()); + auto _hash = hash.getDigest(); + addSuffixHashBytes(suffix, _hash.data(), _hash.size()); return *this; } diff --git a/libtransport/src/core/manifest_inline.h b/libtransport/src/core/manifest_inline.h index fcb1d214f..a487ccfe3 100644 --- a/libtransport/src/core/manifest_inline.h +++ b/libtransport/src/core/manifest_inline.h @@ -48,7 +48,7 @@ class ManifestInline static TRANSPORT_ALWAYS_INLINE ManifestInline *createManifest( const core::Name &manifest_name, ManifestVersion version, - ManifestType type, auth::CryptoHashType algorithm, bool is_last, + ManifestType type, HashType algorithm, bool is_last, const Name &base_name, NextSegmentCalculationStrategy strategy, std::size_t signature_size) { auto manifest = new ManifestInline(manifest_name, signature_size); @@ -110,24 +110,24 @@ class ManifestInline // Convert several manifests into a single map from suffixes to packet hashes. // All manifests must have been decoded beforehand. - static std::unordered_map<Suffix, HashEntry> getSuffixMap( + static std::unordered_map<Suffix, Hash> getSuffixMap( const std::vector<ManifestInline *> &manifests) { - std::unordered_map<Suffix, HashEntry> suffix_map; + std::unordered_map<Suffix, Hash> suffix_map; for (auto manifest_ptr : manifests) { - HashType hash_algorithm = manifest_ptr->getHashAlgorithm(); + HashType hash_type = manifest_ptr->getHashAlgorithm(); SuffixList suffix_list = manifest_ptr->getSuffixList(); for (auto it = suffix_list.begin(); it != suffix_list.end(); ++it) { - std::vector<uint8_t> hash( - it->second, it->second + auth::hash_size_map[hash_algorithm]); - suffix_map[it->first] = {hash_algorithm, hash}; + Hash hash(it->second, Hash::getSize(hash_type), hash_type); + suffix_map[it->first] = hash; } } return suffix_map; } - static std::unordered_map<Suffix, HashEntry> getSuffixMap( + + static std::unordered_map<Suffix, Hash> getSuffixMap( ManifestInline *manifest) { return getSuffixMap(std::vector<ManifestInline *>{manifest}); } diff --git a/libtransport/src/core/memif_connector.cc b/libtransport/src/core/memif_connector.cc deleted file mode 100644 index 087e8cba8..000000000 --- a/libtransport/src/core/memif_connector.cc +++ /dev/null @@ -1,499 +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 <core/memif_connector.h> -#include <hicn/transport/errors/not_implemented_exception.h> - -#ifdef __vpp__ - -#include <sys/epoll.h> - -#include <cstdlib> - -extern "C" { -#include <memif/libmemif.h> -}; - -#define CANCEL_TIMER 1 - -namespace transport { - -namespace core { - -struct memif_connection { - uint16_t index; - /* memif conenction handle */ - memif_conn_handle_t conn; - /* transmit queue id */ - uint16_t tx_qid; - /* tx buffers */ - memif_buffer_t *tx_bufs; - /* allocated tx buffers counter */ - /* number of tx buffers pointing to shared memory */ - uint16_t tx_buf_num; - /* rx buffers */ - memif_buffer_t *rx_bufs; - /* allcoated rx buffers counter */ - /* number of rx buffers pointing to shared memory */ - uint16_t rx_buf_num; - /* interface ip address */ - uint8_t ip_addr[4]; -}; - -std::once_flag MemifConnector::flag_; -utils::EpollEventReactor MemifConnector::main_event_reactor_; - -MemifConnector::MemifConnector(PacketReceivedCallback &&receive_callback, - OnReconnect &&on_reconnect_callback, - asio::io_service &io_service, - std::string app_name) - : Connector(std::move(receive_callback), std::move(on_reconnect_callback)), - memif_worker_(nullptr), - timer_set_(false), - send_timer_(std::make_unique<utils::FdDeadlineTimer>(event_reactor_)), - disconnect_timer_( - std::make_unique<utils::FdDeadlineTimer>(event_reactor_)), - io_service_(io_service), - packet_counter_(0), - memif_connection_(std::make_unique<memif_connection_t>()), - tx_buf_counter_(0), - is_reconnection_(false), - data_available_(false), - app_name_(app_name), - socket_filename_("") { - std::call_once(MemifConnector::flag_, &MemifConnector::init, this); -} - -MemifConnector::~MemifConnector() { close(); } - -void MemifConnector::init() { - /* initialize memory interface */ - int err = memif_init(controlFdUpdate, const_cast<char *>(app_name_.c_str()), - nullptr, nullptr, nullptr); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_init: %s", memif_strerror(err)); - } -} - -void MemifConnector::connect(uint32_t memif_id, long memif_mode) { - state_ = ConnectorState::CONNECTING; - - memif_id_ = memif_id; - socket_filename_ = "/run/vpp/memif.sock"; - - createMemif(memif_id, memif_mode, nullptr); - - work_ = std::make_unique<asio::io_service::work>(io_service_); - - while (state_ != ConnectorState::CONNECTED) { - MemifConnector::main_event_reactor_.runOneEvent(); - } - - int err; - - /* get interrupt queue id */ - int fd = -1; - err = memif_get_queue_efd(memif_connection_->conn, 0, &fd); - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_get_queue_efd: %s", memif_strerror(err)); - return; - } - - // Remove fd from main epoll - main_event_reactor_.delFileDescriptor(fd); - - // Add fd to epoll of instance - event_reactor_.addFileDescriptor( - fd, EPOLLIN, [this](const utils::Event &evt) -> int { - return onInterrupt(memif_connection_->conn, this, 0); - }); - - memif_worker_ = std::make_unique<std::thread>( - std::bind(&MemifConnector::threadMain, this)); -} - -int MemifConnector::createMemif(uint32_t index, uint8_t mode, char *s) { - memif_connection_t *c = memif_connection_.get(); - - /* setting memif connection arguments */ - memif_conn_args_t args; - memset(&args, 0, sizeof(args)); - - args.is_master = mode; - args.log2_ring_size = MEMIF_LOG2_RING_SIZE; - args.buffer_size = MEMIF_BUF_SIZE; - args.num_s2m_rings = 1; - args.num_m2s_rings = 1; - strncpy((char *)args.interface_name, IF_NAME, strlen(IF_NAME) + 1); - args.mode = memif_interface_mode_t::MEMIF_INTERFACE_MODE_IP; - - int err; - - err = memif_create_socket(&args.socket, socket_filename_.c_str(), nullptr); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - throw errors::RuntimeException(memif_strerror(err)); - } - - args.interface_id = index; - /* last argument for memif_create (void * private_ctx) is used by user - to identify connection. this context is returned with callbacks */ - - /* default interrupt */ - if (s == nullptr) { - err = memif_create(&c->conn, &args, onConnect, onDisconnect, onInterrupt, - this); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - throw errors::RuntimeException(memif_strerror(err)); - } - } - - c->index = (uint16_t)index; - c->tx_qid = 0; - /* alloc memif buffers */ - c->rx_buf_num = 0; - c->rx_bufs = static_cast<memif_buffer_t *>( - malloc(sizeof(memif_buffer_t) * MAX_MEMIF_BUFS)); - c->tx_buf_num = 0; - c->tx_bufs = static_cast<memif_buffer_t *>( - malloc(sizeof(memif_buffer_t) * MAX_MEMIF_BUFS)); - - // memif_set_rx_mode (c->conn, MEMIF_RX_MODE_POLLING, 0); - - return 0; -} - -int MemifConnector::deleteMemif() { - memif_connection_t *c = memif_connection_.get(); - - if (c->rx_bufs) { - free(c->rx_bufs); - } - - c->rx_bufs = nullptr; - c->rx_buf_num = 0; - - if (c->tx_bufs) { - free(c->tx_bufs); - } - - c->tx_bufs = nullptr; - c->tx_buf_num = 0; - - int err; - /* disconenct then delete memif connection */ - err = memif_delete(&c->conn); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_delete: %s", memif_strerror(err)); - } - - if (TRANSPORT_EXPECT_FALSE(c->conn != nullptr)) { - TRANSPORT_LOGE("memif delete fail"); - } - - return 0; -} - -int MemifConnector::controlFdUpdate(int fd, uint8_t events, void *private_ctx) { - /* convert memif event definitions to epoll events */ - if (events & MEMIF_FD_EVENT_DEL) { - return MemifConnector::main_event_reactor_.delFileDescriptor(fd); - } - - uint32_t evt = 0; - - if (events & MEMIF_FD_EVENT_READ) { - evt |= EPOLLIN; - } - - if (events & MEMIF_FD_EVENT_WRITE) { - evt |= EPOLLOUT; - } - - if (events & MEMIF_FD_EVENT_MOD) { - return MemifConnector::main_event_reactor_.modFileDescriptor(fd, evt); - } - - return MemifConnector::main_event_reactor_.addFileDescriptor( - fd, evt, [](const utils::Event &evt) -> int { - uint32_t event = 0; - int memif_err = 0; - - if (evt.events & EPOLLIN) { - event |= MEMIF_FD_EVENT_READ; - } - - if (evt.events & EPOLLOUT) { - event |= MEMIF_FD_EVENT_WRITE; - } - - if (evt.events & EPOLLERR) { - event |= MEMIF_FD_EVENT_ERROR; - } - - memif_err = memif_control_fd_handler(evt.data.fd, event); - - if (TRANSPORT_EXPECT_FALSE(memif_err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_control_fd_handler: %s", - memif_strerror(memif_err)); - } - - return 0; - }); -} - -int MemifConnector::bufferAlloc(long n, uint16_t qid) { - memif_connection_t *c = memif_connection_.get(); - int err; - uint16_t r; - /* set data pointer to shared memory and set buffer_len to shared mmeory - * buffer len */ - err = memif_buffer_alloc(c->conn, qid, c->tx_bufs, n, &r, 2000); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_buffer_alloc: %s", memif_strerror(err)); - return -1; - } - - c->tx_buf_num += r; - return r; -} - -int MemifConnector::txBurst(uint16_t qid) { - memif_connection_t *c = memif_connection_.get(); - int err; - uint16_t r; - /* inform peer memif interface about data in shared memory buffers */ - /* mark memif buffers as free */ - err = memif_tx_burst(c->conn, qid, c->tx_bufs, c->tx_buf_num, &r); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_tx_burst: %s", memif_strerror(err)); - } - - // err = memif_refill_queue(c->conn, qid, r, 0); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_tx_burst: %s", memif_strerror(err)); - c->tx_buf_num -= r; - return -1; - } - - c->tx_buf_num -= r; - return 0; -} - -void MemifConnector::sendCallback(const std::error_code &ec) { - timer_set_ = false; - - if (TRANSPORT_EXPECT_TRUE(!ec && state_ == ConnectorState::CONNECTED)) { - doSend(); - } -} - -void MemifConnector::processInputBuffer(std::uint16_t total_packets) { - Packet::MemBufPtr ptr; - - for (; total_packets > 0; total_packets--) { - if (input_buffer_.pop(ptr)) { - receive_callback_(std::move(ptr)); - } - } -} - -/* informs user about connected status. private_ctx is used by user to identify - connection (multiple connections WIP) */ -int MemifConnector::onConnect(memif_conn_handle_t conn, void *private_ctx) { - MemifConnector *connector = (MemifConnector *)private_ctx; - connector->state_ = ConnectorState::CONNECTED; - memif_refill_queue(conn, 0, -1, 0); - - return 0; -} - -/* informs user about disconnected status. private_ctx is used by user to - identify connection (multiple connections WIP) */ -int MemifConnector::onDisconnect(memif_conn_handle_t conn, void *private_ctx) { - MemifConnector *connector = (MemifConnector *)private_ctx; - connector->state_ = ConnectorState::CLOSED; - return 0; -} - -void MemifConnector::threadMain() { event_reactor_.runEventLoop(1000); } - -int MemifConnector::onInterrupt(memif_conn_handle_t conn, void *private_ctx, - uint16_t qid) { - MemifConnector *connector = (MemifConnector *)private_ctx; - - memif_connection_t *c = connector->memif_connection_.get(); - int err = MEMIF_ERR_SUCCESS, ret_val; - uint16_t total_packets = 0; - uint16_t rx; - - do { - err = memif_rx_burst(conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &rx); - ret_val = err; - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS && - err != MEMIF_ERR_NOBUF)) { - TRANSPORT_LOGE("memif_rx_burst: %s", memif_strerror(err)); - goto error; - } - - c->rx_buf_num += rx; - - if (TRANSPORT_EXPECT_FALSE(connector->io_service_.stopped())) { - TRANSPORT_LOGE("socket stopped: ignoring %u packets", rx); - goto error; - } - - std::size_t packet_length; - for (int i = 0; i < rx; i++) { - auto packet = connector->getPacket(); - packet_length = (c->rx_bufs + i)->len; - std::memcpy(packet->writableData(), - reinterpret_cast<const uint8_t *>((c->rx_bufs + i)->data), - packet_length); - packet->append(packet_length); - - if (!connector->input_buffer_.push(std::move(packet))) { - TRANSPORT_LOGE("Error pushing packet. Ring buffer full."); - - // TODO Here we should consider the possibility to signal the congestion - // to the application, that would react properly (e.g. slow down - // message) - } - } - - /* mark memif buffers and shared memory buffers as free */ - /* free processed buffers */ - - err = memif_refill_queue(conn, qid, rx, 0); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_buffer_free: %s", memif_strerror(err)); - } - - c->rx_buf_num -= rx; - total_packets += rx; - - } while (ret_val == MEMIF_ERR_NOBUF); - - connector->io_service_.post( - std::bind(&MemifConnector::processInputBuffer, connector, total_packets)); - - return 0; - -error: - err = memif_refill_queue(c->conn, qid, rx, 0); - - if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) { - TRANSPORT_LOGE("memif_buffer_free: %s", memif_strerror(err)); - } - c->rx_buf_num -= rx; - - return 0; -} - -void MemifConnector::close() { - if (state_ != ConnectorState::CLOSED) { - disconnect_timer_->expiresFromNow(std::chrono::microseconds(50)); - disconnect_timer_->asyncWait([this](const std::error_code &ec) { - deleteMemif(); - event_reactor_.stop(); - work_.reset(); - }); - - if (memif_worker_ && memif_worker_->joinable()) { - memif_worker_->join(); - } - } -} - -void MemifConnector::send(const Packet::MemBufPtr &packet) { - { - utils::SpinLock::Acquire locked(write_msgs_lock_); - output_buffer_.push_back(packet); - } -#if CANCEL_TIMER - if (!timer_set_) { - timer_set_ = true; - send_timer_->expiresFromNow(std::chrono::microseconds(50)); - send_timer_->asyncWait( - std::bind(&MemifConnector::sendCallback, this, std::placeholders::_1)); - } -#endif -} - -int MemifConnector::doSend() { - std::size_t max = 0; - int32_t n = 0; - std::size_t size = 0; - - { - utils::SpinLock::Acquire locked(write_msgs_lock_); - size = output_buffer_.size(); - } - - do { - max = size < MAX_MEMIF_BUFS ? size : MAX_MEMIF_BUFS; - n = bufferAlloc(max, memif_connection_->tx_qid); - - if (TRANSPORT_EXPECT_FALSE(n < 0)) { - TRANSPORT_LOGE("Error allocating buffers."); - return -1; - } - - for (uint16_t i = 0; i < n; i++) { - utils::SpinLock::Acquire locked(write_msgs_lock_); - - auto packet = output_buffer_.front().get(); - const utils::MemBuf *current = packet; - std::size_t offset = 0; - uint8_t *shared_buffer = - reinterpret_cast<uint8_t *>(memif_connection_->tx_bufs[i].data); - do { - std::memcpy(shared_buffer + offset, current->data(), current->length()); - offset += current->length(); - current = current->next(); - } while (current != packet); - - memif_connection_->tx_bufs[i].len = uint32_t(offset); - - output_buffer_.pop_front(); - } - - txBurst(memif_connection_->tx_qid); - - utils::SpinLock::Acquire locked(write_msgs_lock_); - size = output_buffer_.size(); - } while (size > 0); - - return 0; -} - -void MemifConnector::send(const uint8_t *packet, std::size_t len, - const PacketSentCallback &packet_sent) { - throw errors::NotImplementedException(); -} - -} // end namespace core - -} // end namespace transport - -#endif // __vpp__ diff --git a/libtransport/src/core/memif_connector.h b/libtransport/src/core/memif_connector.h deleted file mode 100644 index 8a0e9efad..000000000 --- a/libtransport/src/core/memif_connector.h +++ /dev/null @@ -1,133 +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. - */ - -#pragma once - -#include <core/connector.h> -#include <hicn/transport/config.h> -#include <hicn/transport/portability/portability.h> -#include <hicn/transport/utils/ring_buffer.h> -//#include <hicn/transport/core/hicn_vapi.h> -#include <utils/epoll_event_reactor.h> -#include <utils/fd_deadline_timer.h> - -#include <asio.hpp> -#include <deque> -#include <mutex> -#include <thread> - -#ifdef __vpp__ - -#define _Static_assert static_assert - -namespace transport { - -namespace core { - -typedef struct memif_connection memif_connection_t; - -#define APP_NAME "libtransport" -#define IF_NAME "vpp_connection" - -#define MEMIF_BUF_SIZE 2048 -#define MEMIF_LOG2_RING_SIZE 13 -#define MAX_MEMIF_BUFS (1 << MEMIF_LOG2_RING_SIZE) - -class MemifConnector : public Connector { - typedef void *memif_conn_handle_t; - - public: - MemifConnector(PacketReceivedCallback &&receive_callback, - OnReconnect &&on_reconnect_callback, - asio::io_service &io_service, - std::string app_name = "Libtransport"); - - ~MemifConnector() override; - - void send(const Packet::MemBufPtr &packet) override; - - void send(const uint8_t *packet, std::size_t len, - const PacketSentCallback &packet_sent = 0) override; - - void close() override; - - void connect(uint32_t memif_id, long memif_mode); - - TRANSPORT_ALWAYS_INLINE uint32_t getMemifId() { return memif_id_; }; - - private: - void init(); - - int doSend(); - - int createMemif(uint32_t index, uint8_t mode, char *s); - - uint32_t getMemifConfiguration(); - - int deleteMemif(); - - static int controlFdUpdate(int fd, uint8_t events, void *private_ctx); - - static int onConnect(memif_conn_handle_t conn, void *private_ctx); - - static int onDisconnect(memif_conn_handle_t conn, void *private_ctx); - - static int onInterrupt(memif_conn_handle_t conn, void *private_ctx, - uint16_t qid); - - void threadMain(); - - int txBurst(uint16_t qid); - - int bufferAlloc(long n, uint16_t qid); - - void sendCallback(const std::error_code &ec); - - void processInputBuffer(std::uint16_t total_packets); - - private: - static utils::EpollEventReactor main_event_reactor_; - static std::unique_ptr<std::thread> main_worker_; - - int epfd; - std::unique_ptr<std::thread> memif_worker_; - utils::EpollEventReactor event_reactor_; - std::atomic_bool timer_set_; - std::unique_ptr<utils::FdDeadlineTimer> send_timer_; - std::unique_ptr<utils::FdDeadlineTimer> disconnect_timer_; - asio::io_service &io_service_; - std::unique_ptr<asio::io_service::work> work_; - uint32_t packet_counter_; - std::unique_ptr<memif_connection_t> memif_connection_; - uint16_t tx_buf_counter_; - - PacketRing input_buffer_; - bool is_reconnection_; - bool data_available_; - uint32_t memif_id_; - uint8_t memif_mode_; - std::string app_name_; - uint16_t transmission_index_; - utils::SpinLock write_msgs_lock_; - std::string socket_filename_; - - static std::once_flag flag_; -}; - -} // end namespace core - -} // end namespace transport - -#endif // __vpp__
\ No newline at end of file diff --git a/libtransport/src/core/memif_vapi.c b/libtransport/src/core/memif_vapi.c deleted file mode 100644 index ea3513306..000000000 --- a/libtransport/src/core/memif_vapi.c +++ /dev/null @@ -1,133 +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/transport/config.h> - -#ifdef __vpp__ - -#include <core/memif_vapi.h> - -#include <fcntl.h> -#include <inttypes.h> -#include <semaphore.h> -#include <string.h> -#include <sys/stat.h> -#include <vapi/vapi_safe.h> -#include <vppinfra/clib.h> - -DEFINE_VAPI_MSG_IDS_MEMIF_API_JSON - -static vapi_error_e memif_details_cb(vapi_ctx_t ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_memif_details *reply) { - uint32_t *last_memif_id = (uint32_t *)callback_ctx; - uint32_t current_memif_id = 0; - if (reply != NULL) { - current_memif_id = reply->id; - } else { - return rv; - } - - if (current_memif_id >= *last_memif_id) { - *last_memif_id = current_memif_id + 1; - } - - return rv; -} - -int memif_vapi_get_next_memif_id(vapi_ctx_t ctx, uint32_t *memif_id) { - vapi_lock(); - vapi_msg_memif_dump *msg = vapi_alloc_memif_dump(ctx); - int ret = vapi_memif_dump(ctx, msg, memif_details_cb, memif_id); - vapi_unlock(); - return ret; -} - -static vapi_error_e memif_create_cb(vapi_ctx_t ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_memif_create_reply *reply) { - memif_output_params_t *output_params = (memif_output_params_t *)callback_ctx; - - if (reply == NULL) return rv; - - output_params->sw_if_index = reply->sw_if_index; - - return rv; -} - -int memif_vapi_create_memif(vapi_ctx_t ctx, memif_create_params_t *input_params, - memif_output_params_t *output_params) { - vapi_lock(); - vapi_msg_memif_create *msg = vapi_alloc_memif_create(ctx); - - int ret = 0; - if (input_params->socket_id == ~0) { - // invalid socket-id - ret = -1; - goto END; - } - - if (!is_pow2(input_params->ring_size)) { - // ring size must be power of 2 - ret = -1; - goto END; - } - - if (input_params->rx_queues > 255 || input_params->rx_queues < 1) { - // rx queue must be between 1 - 255 - ret = -1; - goto END; - } - - if (input_params->tx_queues > 255 || input_params->tx_queues < 1) { - // tx queue must be between 1 - 255 - ret = -1; - goto END; - } - - msg->payload.role = input_params->role; - msg->payload.mode = input_params->mode; - msg->payload.rx_queues = input_params->rx_queues; - msg->payload.tx_queues = input_params->tx_queues; - msg->payload.id = input_params->id; - msg->payload.socket_id = input_params->socket_id; - msg->payload.ring_size = input_params->ring_size; - msg->payload.buffer_size = input_params->buffer_size; - - ret = vapi_memif_create(ctx, msg, memif_create_cb, output_params); -END: - vapi_unlock(); - return ret; -} - -static vapi_error_e memif_delete_cb(vapi_ctx_t ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_memif_delete_reply *reply) { - if (reply == NULL) return rv; - - return reply->retval; -} - -int memif_vapi_delete_memif(vapi_ctx_t ctx, uint32_t sw_if_index) { - vapi_lock(); - vapi_msg_memif_delete *msg = vapi_alloc_memif_delete(ctx); - - msg->payload.sw_if_index = sw_if_index; - - int ret = vapi_memif_delete(ctx, msg, memif_delete_cb, NULL); - vapi_unlock(); - return ret; -} - -#endif // __vpp__ diff --git a/libtransport/src/core/memif_vapi.h b/libtransport/src/core/memif_vapi.h deleted file mode 100644 index c045cf093..000000000 --- a/libtransport/src/core/memif_vapi.h +++ /dev/null @@ -1,60 +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. - */ - -#pragma once - -#include <hicn/transport/config.h> - -#ifdef __vpp__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <vapi/memif.api.vapi.h> -#include "stdint.h" - -typedef struct memif_create_params_s { - uint8_t role; - uint8_t mode; - uint8_t rx_queues; - uint8_t tx_queues; - uint32_t id; - uint32_t socket_id; - uint8_t secret[24]; - uint32_t ring_size; - uint16_t buffer_size; - uint8_t hw_addr[6]; -} memif_create_params_t; - -typedef struct memif_output_params_s { - uint32_t sw_if_index; -} memif_output_params_t; - -int memif_vapi_get_next_memif_id(vapi_ctx_t ctx, - uint32_t *memif_id); - -int memif_vapi_create_memif(vapi_ctx_t ctx, - memif_create_params_t *input_params, - memif_output_params_t *output_params); - -int memif_vapi_delete_memif(vapi_ctx_t ctx, - uint32_t sw_if_index); - -#ifdef __cplusplus -} -#endif - -#endif // __vpp__
\ No newline at end of file diff --git a/libtransport/src/core/packet.cc b/libtransport/src/core/packet.cc index 6f237729a..51337201f 100644 --- a/libtransport/src/core/packet.cc +++ b/libtransport/src/core/packet.cc @@ -13,10 +13,11 @@ * limitations under the License. */ +#include <glog/logging.h> +#include <hicn/transport/auth/crypto_hash.h> #include <hicn/transport/core/packet.h> #include <hicn/transport/errors/malformed_packet_exception.h> #include <hicn/transport/utils/hash.h> -#include <hicn/transport/utils/log.h> extern "C" { #ifndef _WIN32 @@ -250,7 +251,7 @@ Packet::Format Packet::getFormat() const { */ if (format_ == HF_UNSPEC && length()) { if (hicn_packet_get_format(packet_start_, &format_) < 0) { - TRANSPORT_LOGE("Unexpected packet format."); + LOG(ERROR) << "Unexpected packet format HF_UNSPEC."; } } @@ -262,12 +263,12 @@ std::shared_ptr<utils::MemBuf> Packet::acquireMemBufReference() { } void Packet::dump() const { - TRANSPORT_LOGI("HEADER -- Length: %zu", headerSize()); - TRANSPORT_LOGI("PAYLOAD -- Length: %zu", payloadSize()); + LOG(INFO) << "HEADER -- Length: " << headerSize(); + LOG(INFO) << "PAYLOAD -- Length: " << payloadSize(); const utils::MemBuf *current = this; do { - TRANSPORT_LOGI("MemBuf Length: %zu", current->length()); + LOG(INFO) << "MemBuf Length: " << current->length(); dump((uint8_t *)current->data(), current->length()); current = current->next(); } while (current != this); @@ -289,6 +290,19 @@ void Packet::setSignatureSize(std::size_t size_bytes) { } } +void Packet::setSignatureSizeGap(std::size_t size_bytes) { + if (!authenticationHeader()) { + throw errors::RuntimeException("Packet without Authentication Header."); + } + + int ret = hicn_packet_set_signature_gap(format_, packet_start_, + (uint8_t)size_bytes); + + if (ret < 0) { + throw errors::RuntimeException("Error setting signature size."); + } +} + uint8_t *Packet::getSignature() const { if (!authenticationHeader()) { throw errors::RuntimeException("Packet without Authentication Header."); @@ -392,8 +406,8 @@ auth::KeyId Packet::getKeyId() const { } auth::CryptoHash Packet::computeDigest(auth::CryptoHashType algorithm) const { - auth::CryptoHasher hasher(static_cast<auth::CryptoHashType>(algorithm)); - hasher.init(); + auth::CryptoHash hash; + hash.setType(algorithm); // Copy IP+TCP/ICMP header before zeroing them hicn_header_t header_copy; @@ -402,15 +416,10 @@ auth::CryptoHash Packet::computeDigest(auth::CryptoHashType algorithm) const { const_cast<Packet *>(this)->resetForHash(); - const utils::MemBuf *current = this; - do { - hasher.updateBytes(current->data(), current->length()); - current = current->next(); - } while (current != this); - + hash.computeDigest(this); hicn_packet_copy_header(format_, &header_copy, packet_start_, false); - return hasher.finalize(); + return hash; } bool Packet::checkIntegrity() const { diff --git a/libtransport/src/core/pending_interest.h b/libtransport/src/core/pending_interest.h index ca6411ddf..99a8bd327 100644 --- a/libtransport/src/core/pending_interest.h +++ b/libtransport/src/core/pending_interest.h @@ -16,6 +16,7 @@ #pragma once #include <hicn/transport/config.h> +#include <hicn/transport/core/asio_wrapper.h> #include <hicn/transport/core/content_object.h> #include <hicn/transport/core/interest.h> #include <hicn/transport/core/name.h> @@ -23,8 +24,6 @@ #include <hicn/transport/portability/portability.h> #include <utils/deadline_timer.h> -#include <asio/steady_timer.hpp> - namespace transport { namespace core { @@ -80,8 +79,8 @@ class PendingInterest { return std::move(interest_); } - TRANSPORT_ALWAYS_INLINE void setInterest(Interest::Ptr &&interest) { - interest_ = std::move(interest); + TRANSPORT_ALWAYS_INLINE void setInterest(Interest::Ptr &interest) { + interest_ = interest; } TRANSPORT_ALWAYS_INLINE const OnContentObjectCallback &getOnDataCallback() diff --git a/libtransport/src/core/portal.cc b/libtransport/src/core/portal.cc index 33335e542..c4c0cf8ba 100644 --- a/libtransport/src/core/portal.cc +++ b/libtransport/src/core/portal.cc @@ -72,7 +72,7 @@ std::string getIoModulePath(const std::string& name, #elif defined(MACINTOSH) std::string extension = ".dylib"; #elif defined(WINDOWS) - std::string extension = ".lib"; + std::string extension = ".lib"; #else #error "Platform not supported."; #endif @@ -88,8 +88,7 @@ std::string getIoModulePath(const std::string& name, for (auto& p : paths) { if (p.at(0) != '/') { - TRANSPORT_LOGW("Path %s is not an absolute path. Ignoring it.", - p.c_str()); + LOG(WARNING) << "Path " << p << " is not an absolute path. Ignoring it."; continue; } diff --git a/libtransport/src/core/portal.h b/libtransport/src/core/portal.h index 59254cf7b..f6a9ce85b 100644 --- a/libtransport/src/core/portal.h +++ b/libtransport/src/core/portal.h @@ -16,7 +16,9 @@ #pragma once #include <core/pending_interest.h> +#include <glog/logging.h> #include <hicn/transport/config.h> +#include <hicn/transport/core/asio_wrapper.h> #include <hicn/transport/core/content_object.h> #include <hicn/transport/core/interest.h> #include <hicn/transport/core/io_module.h> @@ -27,10 +29,7 @@ #include <hicn/transport/interfaces/portal.h> #include <hicn/transport/portability/portability.h> #include <hicn/transport/utils/fixed_block_allocator.h> -#include <hicn/transport/utils/log.h> -#include <asio.hpp> -#include <asio/steady_timer.hpp> #include <future> #include <memory> #include <queue> @@ -136,7 +135,7 @@ class CustomAllocatorHandler { } template <typename... Args> - void operator()(Args &&...args) { + void operator()(Args &&... args) { handler_(std::forward<Args>(args)...); } @@ -277,7 +276,8 @@ class Portal { if (!io_module_) { pending_interest_hash_table_.reserve(portal_details::pit_size); io_module_.reset(IoModule::load(io_module_path_.c_str())); - assert(io_module_); + + CHECK(io_module_); io_module_->init(std::bind(&Portal::processIncomingMessages, this, std::placeholders::_1, std::placeholders::_2, @@ -298,7 +298,7 @@ class Portal { * Compute name hash */ TRANSPORT_ALWAYS_INLINE uint32_t getHash(const Name &name) { - return name.getHash32() + name.getSuffix(); + return name.getHash32(false) + name.getSuffix(); } /** @@ -338,15 +338,16 @@ class Portal { interest->encodeSuffixes(); io_module_->send(*interest); - uint32_t initial_hash = interest->getName().getHash32(); + uint32_t initial_hash = interest->getName().getHash32(false); auto hash = initial_hash + interest->getName().getSuffix(); + uint32_t seq = interest->getName().getSuffix(); uint32_t *suffix = interest->firstSuffix(); auto n_suffixes = interest->numberOfSuffixes(); uint32_t counter = 0; // Set timers do { auto pending_interest = packet_pool_.getPendingInterest(); - pending_interest->setInterest(std::move(interest)); + pending_interest->setInterest(interest); pending_interest->setOnContentObjectCallback( std::move(on_content_object_callback)); pending_interest->setOnTimeoutCallback( @@ -354,8 +355,9 @@ class Portal { pending_interest->startCountdown( portal_details::makeCustomAllocatorHandler( - async_callback_memory_, std::bind(&Portal::timerHandler, this, - std::placeholders::_1, hash))); + async_callback_memory_, + std::bind(&Portal::timerHandler, this, std::placeholders::_1, + hash, seq))); auto it = pending_interest_hash_table_.find(hash); if (it != pending_interest_hash_table_.end()) { @@ -370,6 +372,7 @@ class Portal { if (suffix) { hash = initial_hash + *suffix; + seq = *suffix; suffix++; } @@ -385,7 +388,7 @@ class Portal { * @param hash - The index of the interest in the pending interest hash table. */ TRANSPORT_ALWAYS_INLINE void timerHandler(const std::error_code &ec, - uint32_t hash) { + uint32_t hash, uint32_t seq) { bool is_stopped = io_service_.stopped(); if (TRANSPORT_EXPECT_FALSE(is_stopped)) { return; @@ -398,11 +401,13 @@ class Portal { PendingInterest::Ptr ptr = std::move(it->second); pending_interest_hash_table_.erase(it); auto _int = ptr->getInterest(); + Name &name = const_cast<Name &>(_int->getName()); + name.setSuffix(seq); if (ptr->getOnTimeoutCallback() != UNSET_CALLBACK) { - ptr->on_interest_timeout_callback_(std::move(_int)); + ptr->on_interest_timeout_callback_(_int, name); } else if (consumer_callback_) { - consumer_callback_->onTimeout(std::move(_int)); + consumer_callback_->onTimeout(_int, name); } } } @@ -516,6 +521,15 @@ class Portal { } } + /** + * Check if the transport is connected to a forwarder or not + */ + TRANSPORT_ALWAYS_INLINE bool isConnectedToFwd() { + std::string mod = io_module_path_.substr(0, io_module_path_.find(".")); + if (mod == "forwarder_module") return false; + return true; + } + private: /** * Clear the pending interest hash table. @@ -578,7 +592,7 @@ class Portal { processInterest(static_cast<Interest &>(packet_buffer)); } } else { - TRANSPORT_LOGE("Received not supported packet. Ignoring it."); + LOG(ERROR) << "Received not supported packet. Ignoring it."; } } @@ -597,6 +611,7 @@ class Portal { TRANSPORT_ALWAYS_INLINE void processInterest(Interest &interest) { // Interest for a producer + DLOG_IF(INFO, VLOG_IS_ON(3)) << "processInterest " << interest.getName(); if (TRANSPORT_EXPECT_TRUE(producer_callback_ != nullptr)) { producer_callback_->onInterest(interest); } @@ -612,13 +627,13 @@ class Portal { */ TRANSPORT_ALWAYS_INLINE void processContentObject( ContentObject &content_object) { - TRANSPORT_LOGD("processContentObject %s", - content_object.getName().toString().c_str()); + DLOG_IF(INFO, VLOG_IS_ON(3)) + << "processContentObject " << content_object.getName(); uint32_t hash = getHash(content_object.getName()); auto it = pending_interest_hash_table_.find(hash); if (it != pending_interest_hash_table_.end()) { - TRANSPORT_LOGD("Found pending interest."); + DLOG_IF(INFO, VLOG_IS_ON(3)) << "Found pending interest."; PendingInterest::Ptr interest_ptr = std::move(it->second); pending_interest_hash_table_.erase(it); @@ -631,7 +646,8 @@ class Portal { consumer_callback_->onContentObject(*_int, content_object); } } else { - TRANSPORT_LOGD("No interest pending for received content object."); + DLOG_IF(INFO, VLOG_IS_ON(3)) + << "No interest pending for received content object."; } } diff --git a/libtransport/src/core/raw_socket_connector.cc b/libtransport/src/core/raw_socket_connector.cc deleted file mode 100644 index 4d780959b..000000000 --- a/libtransport/src/core/raw_socket_connector.cc +++ /dev/null @@ -1,203 +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/transport/utils/conversions.h> -#include <hicn/transport/utils/log.h> - -#include <core/raw_socket_connector.h> - -#include <net/if.h> -#include <netdb.h> -#include <stdio.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/socket.h> - -#define MY_DEST_MAC0 0x0a -#define MY_DEST_MAC1 0x7b -#define MY_DEST_MAC2 0x7c -#define MY_DEST_MAC3 0x1c -#define MY_DEST_MAC4 0x4a -#define MY_DEST_MAC5 0x14 - -namespace transport { - -namespace core { - -RawSocketConnector::RawSocketConnector( - PacketReceivedCallback &&receive_callback, - OnReconnect &&on_reconnect_callback, asio::io_service &io_service, - std::string app_name) - : Connector(std::move(receive_callback), std::move(on_reconnect_callback)), - io_service_(io_service), - socket_(io_service_, raw_protocol(PF_PACKET, SOCK_RAW)), - // resolver_(io_service_), - timer_(io_service_), - read_msg_(packet_pool_.makePtr(nullptr)), - data_available_(false), - app_name_(app_name) { - memset(&link_layer_address_, 0, sizeof(link_layer_address_)); -} - -RawSocketConnector::~RawSocketConnector() {} - -void RawSocketConnector::connect(const std::string &interface_name, - const std::string &mac_address_str) { - state_ = ConnectorState::CONNECTING; - memset(ðernet_header_, 0, sizeof(ethernet_header_)); - struct ifreq ifr; - struct ifreq if_mac; - uint8_t mac_address[6]; - - utils::convertStringToMacAddress(mac_address_str, mac_address); - - // Get interface mac address - int fd = static_cast<int>(socket_.native_handle()); - - /* Get the index of the interface to send on */ - memset(&ifr, 0, sizeof(struct ifreq)); - strncpy(ifr.ifr_name, interface_name.c_str(), interface_name.size()); - - // if (ioctl(fd, SIOCGIFINDEX, &if_idx) < 0) { - // perror("SIOCGIFINDEX"); - // } - - /* Get the MAC address of the interface to send on */ - memset(&if_mac, 0, sizeof(struct ifreq)); - strncpy(if_mac.ifr_name, interface_name.c_str(), interface_name.size()); - if (ioctl(fd, SIOCGIFHWADDR, &if_mac) < 0) { - perror("SIOCGIFHWADDR"); - throw errors::RuntimeException("Interface does not exist"); - } - - /* Ethernet header */ - for (int i = 0; i < 6; i++) { - ethernet_header_.ether_shost[i] = - ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[i]; - ethernet_header_.ether_dhost[i] = mac_address[i]; - } - - /* Ethertype field */ - ethernet_header_.ether_type = htons(ETH_P_IPV6); - - strcpy(ifr.ifr_name, interface_name.c_str()); - - if (0 == ioctl(fd, SIOCGIFHWADDR, &ifr)) { - memcpy(link_layer_address_.sll_addr, ifr.ifr_hwaddr.sa_data, 6); - } - - // memset(&ifr, 0, sizeof(ifr)); - // ioctl(fd, SIOCGIFFLAGS, &ifr); - // ifr.ifr_flags |= IFF_PROMISC; - // ioctl(fd, SIOCSIFFLAGS, &ifr); - - link_layer_address_.sll_family = AF_PACKET; - link_layer_address_.sll_protocol = htons(ETH_P_ALL); - link_layer_address_.sll_ifindex = if_nametoindex(interface_name.c_str()); - link_layer_address_.sll_hatype = 1; - link_layer_address_.sll_halen = 6; - - // startConnectionTimer(); - doConnect(); - doRecvPacket(); -} - -void RawSocketConnector::send(const uint8_t *packet, std::size_t len, - const PacketSentCallback &packet_sent) { - if (packet_sent != 0) { - socket_.async_send( - asio::buffer(packet, len), - [packet_sent](std::error_code ec, std::size_t /*length*/) { - packet_sent(); - }); - } else { - if (state_ == ConnectorState::CONNECTED) { - socket_.send(asio::buffer(packet, len)); - } - } -} - -void RawSocketConnector::send(const Packet::MemBufPtr &packet) { - io_service_.post([this, packet]() { - bool write_in_progress = !output_buffer_.empty(); - output_buffer_.push_back(std::move(packet)); - if (TRANSPORT_EXPECT_TRUE(state_ == ConnectorState::CONNECTED)) { - if (!write_in_progress) { - doSendPacket(); - } else { - // Tell the handle connect it has data to write - data_available_ = true; - } - } - }); -} - -void RawSocketConnector::close() { - io_service_.post([this]() { socket_.close(); }); -} - -void RawSocketConnector::doSendPacket() { - auto packet = output_buffer_.front().get(); - auto array = std::vector<asio::const_buffer>(); - - const utils::MemBuf *current = packet; - do { - array.push_back(asio::const_buffer(current->data(), current->length())); - current = current->next(); - } while (current != packet); - - socket_.async_send( - std::move(array), - [this /*, packet*/](std::error_code ec, std::size_t bytes_transferred) { - if (TRANSPORT_EXPECT_TRUE(!ec)) { - output_buffer_.pop_front(); - if (!output_buffer_.empty()) { - doSendPacket(); - } - } else { - TRANSPORT_LOGE("%d %s", ec.value(), ec.message().c_str()); - } - }); -} - -void RawSocketConnector::doRecvPacket() { - read_msg_ = getPacket(); - socket_.async_receive( - asio::buffer(read_msg_->writableData(), packet_size), - [this](std::error_code ec, std::size_t bytes_transferred) mutable { - if (!ec) { - // Ignore packets that are not for us - uint8_t *dst_mac_address = const_cast<uint8_t *>(read_msg_->data()); - if (!std::memcmp(dst_mac_address, ethernet_header_.ether_shost, - ETHER_ADDR_LEN)) { - read_msg_->append(bytes_transferred); - read_msg_->trimStart(sizeof(struct ether_header)); - receive_callback_(std::move(read_msg_)); - } - } else { - TRANSPORT_LOGE("%d %s", ec.value(), ec.message().c_str()); - } - doRecvPacket(); - }); -} - -void RawSocketConnector::doConnect() { - state_ = ConnectorState::CONNECTED; - socket_.bind(raw_endpoint(&link_layer_address_, sizeof(link_layer_address_))); -} - -} // end namespace core - -} // end namespace transport diff --git a/libtransport/src/core/raw_socket_connector.h b/libtransport/src/core/raw_socket_connector.h deleted file mode 100644 index 1d4e9cb39..000000000 --- a/libtransport/src/core/raw_socket_connector.h +++ /dev/null @@ -1,81 +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. - */ - -#pragma once - -#include <hicn/transport/config.h> -#include <hicn/transport/core/name.h> - -#include <core/connector.h> - -#include <linux/if_packet.h> -#include <net/ethernet.h> -#include <sys/socket.h> -#include <asio.hpp> -#include <asio/steady_timer.hpp> -#include <deque> - -namespace transport { - -namespace core { - -using asio::generic::raw_protocol; -using raw_endpoint = asio::generic::basic_endpoint<raw_protocol>; - -class RawSocketConnector : public Connector { - public: - RawSocketConnector(PacketReceivedCallback &&receive_callback, - OnReconnect &&reconnect_callback, - asio::io_service &io_service, - std::string app_name = "Libtransport"); - - ~RawSocketConnector() override; - - void send(const Packet::MemBufPtr &packet) override; - - void send(const uint8_t *packet, std::size_t len, - const PacketSentCallback &packet_sent = 0) override; - - void close() override; - - void connect(const std::string &interface_name, - const std::string &mac_address_str); - - private: - void doConnect(); - - void doRecvPacket(); - - void doSendPacket(); - - private: - asio::io_service &io_service_; - raw_protocol::socket socket_; - - struct ether_header ethernet_header_; - - struct sockaddr_ll link_layer_address_; - - asio::steady_timer timer_; - - utils::ObjectPool<utils::MemBuf>::Ptr read_msg_; - - bool data_available_; - std::string app_name_; -}; - -} // end namespace core - -} // end namespace transport diff --git a/libtransport/src/core/raw_socket_interface.cc b/libtransport/src/core/raw_socket_interface.cc deleted file mode 100644 index 7ee2a844d..000000000 --- a/libtransport/src/core/raw_socket_interface.cc +++ /dev/null @@ -1,57 +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/transport/utils/linux.h> - -#include <core/raw_socket_interface.h> - -#include <fstream> - -namespace transport { - -namespace core { - -static std::string config_folder_path = "/etc/transport/interface.conf.d"; - -RawSocketInterface::RawSocketInterface(RawSocketConnector &connector) - : ForwarderInterface<RawSocketInterface, RawSocketConnector>(connector) {} - -RawSocketInterface::~RawSocketInterface() {} - -void RawSocketInterface::connect(bool is_consumer) { - std::string complete_filename = - config_folder_path + std::string("/") + output_interface_; - - std::ifstream is(complete_filename); - std::string interface; - - if (is) { - is >> remote_mac_address_; - } - - // Get interface ip address - struct sockaddr_in6 address = {0}; - utils::retrieveInterfaceAddress(output_interface_, &address); - - std::memcpy(&inet6_address_.v6.as_u8, &address.sin6_addr, - sizeof(address.sin6_addr)); - connector_.connect(output_interface_, remote_mac_address_); -} - -void RawSocketInterface::registerRoute(Prefix &prefix) { return; } - -} // namespace core - -} // namespace transport diff --git a/libtransport/src/core/raw_socket_interface.h b/libtransport/src/core/raw_socket_interface.h deleted file mode 100644 index c06d14637..000000000 --- a/libtransport/src/core/raw_socket_interface.h +++ /dev/null @@ -1,62 +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. - */ - -#pragma once - -#include <hicn/transport/core/prefix.h> - -#include <core/forwarder_interface.h> -#include <core/raw_socket_connector.h> - -#include <atomic> -#include <deque> - -namespace transport { - -namespace core { - -class RawSocketInterface - : public ForwarderInterface<RawSocketInterface, RawSocketConnector> { - public: - typedef RawSocketConnector ConnectorType; - - RawSocketInterface(RawSocketConnector &connector); - - ~RawSocketInterface(); - - void connect(bool is_consumer); - - void registerRoute(Prefix &prefix); - - std::uint16_t getMtu() { return interface_mtu; } - - TRANSPORT_ALWAYS_INLINE static bool isControlMessageImpl( - const uint8_t *message) { - return false; - } - - TRANSPORT_ALWAYS_INLINE void processControlMessageReplyImpl( - Packet::MemBufPtr &&packet_buffer) {} - - TRANSPORT_ALWAYS_INLINE void closeConnection(){}; - - private: - static constexpr std::uint16_t interface_mtu = 1500; - std::string remote_mac_address_; -}; - -} // namespace core - -} // namespace transport diff --git a/libtransport/src/core/rs.cc b/libtransport/src/core/rs.cc deleted file mode 100644 index 33270736d..000000000 --- a/libtransport/src/core/rs.cc +++ /dev/null @@ -1,370 +0,0 @@ - -/* - * Copyright (c) 2021 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 <core/fec.h> -#include <core/rs.h> -#include <hicn/transport/core/global_object_pool.h> -#include <hicn/transport/utils/log.h> - -#include <cassert> - -namespace transport { -namespace core { -namespace fec { - -BlockCode::BlockCode(uint32_t k, uint32_t n, struct fec_parms *code) - : Packets(), - k_(k), - n_(n), - code_(code), - max_buffer_size_(0), - current_block_size_(0), - to_decode_(false) { - sorted_index_.reserve(n); -} - -bool BlockCode::addRepairSymbol(const fec::buffer &packet, uint32_t i) { - // Get index - to_decode_ = true; - TRANSPORT_LOGD("adding symbol of size %zu", packet->length()); - return addSymbol(packet, i, packet->length() - sizeof(fec_header)); -} - -bool BlockCode::addSourceSymbol(const fec::buffer &packet, uint32_t i) { - return addSymbol(packet, i, packet->length()); -} - -bool BlockCode::addSymbol(const fec::buffer &packet, uint32_t i, - std::size_t size) { - if (size > max_buffer_size_) { - max_buffer_size_ = size; - } - - operator[](current_block_size_++) = std::make_pair(i, packet); - - if (current_block_size_ >= k_) { - if (to_decode_) { - decode(); - } else { - encode(); - } - - clear(); - return false; - } - - return true; -} - -void BlockCode::encode() { - gf **data = new gf*[k_]; - uint32_t *old_values = new uint32_t[k_]; - uint32_t base = operator[](0).first; - - // Set packet length in first 2 bytes - for (uint32_t i = 0; i < k_; i++) { - auto &packet = operator[](i).second; - - TRANSPORT_LOGD("Current buffer size: %zu", packet->length()); - - auto ret = packet->ensureCapacityAndFillUnused(max_buffer_size_, 0); - if (TRANSPORT_EXPECT_FALSE(ret == false)) { - throw errors::RuntimeException( - "Provided packet is not suitable to be used as FEC source packet. " - "Aborting."); - } - - // Buffers should hold 2 bytes before the starting pointer, in order to be - // able to set the length for the encoding operation - packet->prepend(2); - uint16_t *length = reinterpret_cast<uint16_t *>(packet->writableData()); - - old_values[i] = *length; - *length = htons(u_short(packet->length() - LEN_SIZE_BYTES)); - - data[i] = packet->writableData(); - - } - - // Finish to fill source block with the buffers to hold the repair symbols - for (uint32_t i = k_; i < n_; i++) { - // For the moment we get a packet from the pool here.. later we'll need to - // require a packet from the caller with a callback. - auto packet = PacketManager<>::getInstance().getMemBuf(); - packet->append(max_buffer_size_ + sizeof(fec_header) + LEN_SIZE_BYTES); - fec_header *fh = reinterpret_cast<fec_header *>(packet->writableData()); - - fh->setSeqNumberBase(base); - fh->setNFecSymbols(n_ - k_); - fh->setEncodedSymbolId(i); - fh->setSourceBlockLen(n_); - - packet->trimStart(sizeof(fec_header)); - - data[i] = packet->writableData(); - operator[](i) = std::make_pair(i, std::move(packet)); - } - - // Generate repair symbols and put them in corresponding buffers - TRANSPORT_LOGD("Calling encode with max_buffer_size_ = %zu", - max_buffer_size_); - for (uint32_t i = k_; i < n_; i++) { - fec_encode(code_, data, data[i], i, (int)(max_buffer_size_ + LEN_SIZE_BYTES)); - } - - // Restore original content of buffer space used to store the length - for (uint32_t i = 0; i < k_; i++) { - auto &packet = operator[](i).second; - uint16_t *length = reinterpret_cast<uint16_t *>(packet->writableData()); - *length = old_values[i]; - packet->trimStart(2); - } - - // Re-include header in repair packets - for (uint32_t i = k_; i < n_; i++) { - auto &packet = operator[](i).second; - TRANSPORT_LOGD("Produced repair symbol of size = %zu", packet->length()); - packet->prepend(sizeof(fec_header)); - } - delete [] data; - delete [] old_values; -} - -void BlockCode::decode() { - gf **data = new gf*[k_]; - uint32_t *index = new uint32_t[k_]; - - for (uint32_t i = 0; i < k_; i++) { - auto &packet = operator[](i).second; - index[i] = operator[](i).first; - sorted_index_[i] = index[i]; - - if (index[i] < k_) { - TRANSPORT_LOGD("DECODE SOURCE - index %u - Current buffer size: %zu", - index[i], packet->length()); - // This is a source packet. We need to prepend the length and fill - // additional space to 0 - - // Buffers should hold 2 bytes before the starting pointer, in order to be - // able to set the length for the encoding operation - packet->prepend(LEN_SIZE_BYTES); - packet->ensureCapacityAndFillUnused(max_buffer_size_, 0); - uint16_t *length = reinterpret_cast<uint16_t *>(packet->writableData()); - - *length = htons(u_short(packet->length() - LEN_SIZE_BYTES)); - } else { - TRANSPORT_LOGD("DECODE SYMBOL - index %u - Current buffer size: %zu", - index[i], packet->length()); - packet->trimStart(sizeof(fec_header)); - } - - data[i] = packet->writableData(); - delete [] data; - delete [] index; - } - - // We decode the source block - TRANSPORT_LOGD("Calling decode with max_buffer_size_ = %zu", - max_buffer_size_); - fec_decode(code_, data, reinterpret_cast<int *>(index), (int)max_buffer_size_); - - // Find the index in the block for recovered packets - for (uint32_t i = 0; i < k_; i++) { - if (index[i] != i) { - for (uint32_t j = 0; j < k_; j++) - if (sorted_index_[j] == uint32_t(index[i])) { - sorted_index_[j] = i; - } - } - } - - // Reorder block by index with in-place sorting - for (uint32_t i = 0; i < k_; i++) { - for (uint32_t j = sorted_index_[i]; j != i; j = sorted_index_[i]) { - std::swap(sorted_index_[j], sorted_index_[i]); - std::swap(operator[](j), operator[](i)); - } - } - - // Adjust length according to the one written in the source packet - for (uint32_t i = 0; i < k_; i++) { - auto &packet = operator[](i).second; - uint16_t *length = reinterpret_cast<uint16_t *>(packet->writableData()); - packet->trimStart(2); - packet->setLength(ntohs(*length)); - } -} - -void BlockCode::clear() { - current_block_size_ = 0; - max_buffer_size_ = 0; - sorted_index_.clear(); - to_decode_ = false; -} - -void rs::MatrixDeleter::operator()(struct fec_parms *params) { - fec_free(params); -} - -rs::Codes rs::createCodes() { - Codes ret; - - ret.emplace(std::make_pair(1, 3), Matrix(fec_new(1, 3), MatrixDeleter())); - ret.emplace(std::make_pair(6, 10), Matrix(fec_new(6, 10), MatrixDeleter())); - ret.emplace(std::make_pair(8, 32), Matrix(fec_new(8, 32), MatrixDeleter())); - ret.emplace(std::make_pair(10, 30), Matrix(fec_new(10, 30), MatrixDeleter())); - ret.emplace(std::make_pair(16, 24), Matrix(fec_new(16, 24), MatrixDeleter())); - ret.emplace(std::make_pair(10, 40), Matrix(fec_new(10, 40), MatrixDeleter())); - ret.emplace(std::make_pair(10, 60), Matrix(fec_new(10, 60), MatrixDeleter())); - ret.emplace(std::make_pair(10, 90), Matrix(fec_new(10, 90), MatrixDeleter())); - - return ret; -} - -rs::Codes rs::codes_ = createCodes(); - -rs::rs(uint32_t k, uint32_t n) : k_(k), n_(n) {} - -void rs::setFECCallback(const PacketsReady &callback) { - fec_callback_ = callback; -} - -encoder::encoder(uint32_t k, uint32_t n) - : rs(k, n), - current_code_(codes_[std::make_pair(k, n)].get()), - source_block_(k_, n_, current_code_) {} - -void encoder::consume(const fec::buffer &packet, uint32_t index) { - if (!source_block_.addSourceSymbol(packet, index)) { - std::vector<buffer> repair_packets; - for (uint32_t i = k_; i < n_; i++) { - repair_packets.emplace_back(std::move(source_block_[i].second)); - } - fec_callback_(repair_packets); - } -} - -decoder::decoder(uint32_t k, uint32_t n) : rs(k, n) {} - -void decoder::recoverPackets(SourceBlocks::iterator &src_block_it) { - TRANSPORT_LOGD("recoverPackets for %u", k_); - auto &src_block = src_block_it->second; - std::vector<buffer> source_packets(k_); - for (uint32_t i = 0; i < src_block.getK(); i++) { - source_packets[i] = std::move(src_block[i].second); - } - - fec_callback_(source_packets); - processed_source_blocks_.emplace(src_block_it->first); - - auto it = parked_packets_.find(src_block_it->first); - if (it != parked_packets_.end()) { - parked_packets_.erase(it); - } - - src_blocks_.erase(src_block_it); -} - -void decoder::consume(const fec::buffer &packet, uint32_t index) { - // Normalize index - auto i = index % n_; - - // Get base - uint32_t base = index - i; - - TRANSPORT_LOGD( - "Decoder consume called for source symbol. BASE = %u, index = %u and i = " - "%u", - base, index, i); - - // check if a source block already exist for this symbol. If it does not - // exist, we lazily park this packet until we receive a repair symbol for the - // same block. This is done for 2 reason: - // 1) If we receive all the source packets of a block, we do not need to - // recover anything. - // 2) Sender may change n and k at any moment, so we construct the source - // block based on the (n, k) values written in the fec header. This is - // actually not used right now, since we use fixed value of n and k passed - // at construction time, but it paves the ground for a more dynamic - // protocol that may come in the future. - auto it = src_blocks_.find(base); - if (it != src_blocks_.end()) { - auto ret = it->second.addSourceSymbol(packet, i); - if (!ret) { - recoverPackets(it); - } - } else { - TRANSPORT_LOGD("Adding to parked source packets"); - auto ret = parked_packets_.emplace( - base, std::vector<std::pair<buffer, uint32_t> >()); - ret.first->second.emplace_back(packet, i); - } -} - -void decoder::consume(const fec::buffer &packet) { - // Repair symbol! Get index and base source block. - fec_header *h = reinterpret_cast<fec_header *>(packet->writableData()); - auto i = h->getEncodedSymbolId(); - auto base = h->getSeqNumberBase(); - auto n = h->getSourceBlockLen(); - auto k = n - h->getNFecSymbols(); - - TRANSPORT_LOGD( - "Decoder consume called for repair symbol. BASE = %u, index = %u and i = " - "%u", - base, base + i, i); - - // check if a source block already exist for this symbol - auto it = src_blocks_.find(base); - if (it == src_blocks_.end()) { - // Create new source block - auto code_it = codes_.find(std::make_pair(k, n)); - if (code_it == codes_.end()) { - TRANSPORT_LOGE("Code for k = %u and n = %u does not exist.", k_, n_); - return; - } - - auto emplace_result = - src_blocks_.emplace(base, BlockCode(k, n, code_it->second.get())); - it = emplace_result.first; - - // Check in the parked packets and insert any packet that is part of this - // source block - - auto it2 = parked_packets_.find(base); - if (it2 != parked_packets_.end()) { - for (auto &packet_index : it2->second) { - auto ret = - it->second.addSourceSymbol(packet_index.first, packet_index.second); - if (!ret) { - recoverPackets(it); - // Finish to delete packets in same source block that were - // eventually not used - return; - } - } - } - } - - auto ret = it->second.addRepairSymbol(packet, i); - if (!ret) { - recoverPackets(it); - } -} - -} // namespace fec -} // namespace core -} // namespace transport diff --git a/libtransport/src/core/rs.h b/libtransport/src/core/rs.h deleted file mode 100644 index 9a8c43e4d..000000000 --- a/libtransport/src/core/rs.h +++ /dev/null @@ -1,340 +0,0 @@ - -/* - * Copyright (c) 2021 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> -#endif -#include <hicn/transport/utils/membuf.h> -#include <protocols/fec_base.h> - -#include <array> -#include <cstdint> -#include <map> -#include <unordered_set> -#include <vector> - -namespace transport { -namespace core { - -namespace fec { - -static const constexpr uint16_t MAX_SOURCE_BLOCK_SIZE = 128; - -using buffer = typename utils::MemBuf::Ptr; -/** - * We use a std::array in place of std::vector to avoid to allocate a new vector - * in the heap every time we build a new source block, which would be bad if - * the decoder has to allocate several source blocks for many concurrent bases. - * std::array allows to be constructed in place, saving the allocation at the - * price os knowing in advance its size. - */ -using Packets = std::array<std::pair<uint32_t, buffer>, MAX_SOURCE_BLOCK_SIZE>; - -/** - * FEC Header, prepended to symbol packets. - */ -struct fec_header { - /** - * The base source packet seq_number this FES symbol refers to - */ - uint32_t seq_number; - - /** - * The index of the symbol inside the source block, between k and n - 1 - */ - uint8_t encoded_symbol_id; - - /** - * Total length of source block (n) - */ - uint8_t source_block_len; - - /** - * Total number of symbols (n - k) - */ - uint8_t n_fec_symbols; - - /** - * Align header to 64 bits - */ - uint8_t padding; - - void setSeqNumberBase(uint32_t suffix) { seq_number = htonl(suffix); } - uint32_t getSeqNumberBase() { return ntohl(seq_number); } - void setEncodedSymbolId(uint8_t esi) { encoded_symbol_id = esi; } - uint8_t getEncodedSymbolId() { return encoded_symbol_id; } - void setSourceBlockLen(uint8_t k) { source_block_len = k; } - uint8_t getSourceBlockLen() { return source_block_len; } - void setNFecSymbols(uint8_t n_r) { n_fec_symbols = n_r; } - uint8_t getNFecSymbols() { return n_fec_symbols; } -}; - -/** - * This class models the source block itself. - */ -class BlockCode : public Packets { - /** - * For variable length packet we need to prepend to the padded payload the - * real length of the packet. This is *not* sent over the network. - */ - static constexpr std::size_t LEN_SIZE_BYTES = 2; - - public: - BlockCode(uint32_t k, uint32_t n, struct fec_parms *code); - - /** - * Add a repair symbol to the dource block. - */ - bool addRepairSymbol(const fec::buffer &packet, uint32_t i); - - /** - * Add a source symbol to the source block. - */ - bool addSourceSymbol(const fec::buffer &packet, uint32_t i); - - /** - * Get current length of source block. - */ - std::size_t length() { return current_block_size_; } - - /** - * Get N - */ - uint32_t getN() { return n_; } - - /** - * Get K - */ - uint32_t getK() { return k_; } - - /** - * Clear source block - */ - void clear(); - - private: - /** - * Add symbol to source block - **/ - bool addSymbol(const fec::buffer &packet, uint32_t i, std::size_t size); - - /** - * Starting from k source symbols, get the n - k repair symbols - */ - void encode(); - - /** - * Starting from k symbols (mixed repair and source), get k source symbols. - * NOTE: It does not make sense to retrieve the k source symbols using the - * very same k source symbols. With the current implementation that case can - * never happen. - */ - void decode(); - - private: - uint32_t k_; - uint32_t n_; - struct fec_parms *code_; - std::size_t max_buffer_size_; - std::size_t current_block_size_; - std::vector<uint32_t> sorted_index_; - bool to_decode_; -}; - -/** - * This class contains common parameters between the fec encoder and decoder. - * In particular it contains: - * - The callback to be called when symbols are encoded / decoded - * - The reference to the static reed-solomon parameters, allocated at program - * startup - * - N and K. Ideally they are useful only for the encoder (the decoder can - * retrieve them from the FEC header). However right now we assume sender and - * receiver agreed on the parameters k and n to use. We will introduce a control - * message later to negotiate them, so that decoder cah dynamically change them - * during the download. - */ -class rs { - /** - * Deleter for static preallocated reed-solomon parameters. - */ - struct MatrixDeleter { - void operator()(struct fec_parms *params); - }; - - /** - * unique_ptr to reed-solomon parameters, with custom deleter to call fec_free - * at the end of the program - */ - using Matrix = std::unique_ptr<struct fec_parms, MatrixDeleter>; - - /** - * Key to retrieve static preallocated reed-solomon parameters. It is pair of - * k and n - */ - using Code = std::pair<std::uint32_t /* k */, std::uint32_t /* n */>; - - /** - * Custom hash function for (k, n) pair. - */ - struct CodeHasher { - std::size_t operator()(const transport::core::fec::rs::Code &code) const { - uint64_t ret = uint64_t(code.first) << 32 | uint64_t(code.second); - return std::hash<uint64_t>{}(ret); - } - }; - - protected: - /** - * Callback to be called after the encode or the decode operations. In the - * former case it will contain the symbols, while in the latter the sources. - */ - using PacketsReady = std::function<void(std::vector<buffer> &)>; - - /** - * The sequence number base. - */ - using SNBase = std::uint32_t; - - /** - * The map of source blocks, used at the decoder side. For the encoding - * operation we can use one source block only, since packet are produced in - * order. - */ - using SourceBlocks = std::unordered_map<SNBase, BlockCode>; - - /** - * Map (k, n) -> reed-solomon parameter - */ - using Codes = std::unordered_map<Code, Matrix, CodeHasher>; - - public: - rs(uint32_t k, uint32_t n); - ~rs() = default; - - /** - * Set callback to call after packet encoding / decoding - */ - void setFECCallback(const PacketsReady &callback); - - virtual void clear() { processed_source_blocks_.clear(); } - - private: - /** - * Create reed-solomon codes at program startup. - */ - static Codes createCodes(); - - protected: - bool processed(SNBase seq_base) { - return processed_source_blocks_.find(seq_base) != - processed_source_blocks_.end(); - } - - std::uint32_t k_; - std::uint32_t n_; - PacketsReady fec_callback_; - - /** - * Keep track of processed source blocks - */ - std::unordered_set<SNBase> processed_source_blocks_; - - static Codes codes_; -}; - -/** - * The reed-solomon encoder. It is feeded with source symbols and it provide - * repair-symbols through the fec_callback_ - */ -class encoder : public rs { - public: - encoder(uint32_t k, uint32_t n); - /** - * Always consume source symbols. - */ - void consume(const fec::buffer &packet, uint32_t index); - - void clear() override { - rs::clear(); - source_block_.clear(); - } - - private: - struct fec_parms *current_code_; - /** - * The source block. As soon as it is filled with k source symbols, the - * encoder calls the callback fec_callback_ and the resets the block 0, ready - * to accept another batch of k source symbols. - */ - BlockCode source_block_; -}; - -/** - * The reed-solomon encoder. It is feeded with source/repair symbols and it - * provides the original source symbols through the fec_callback_ - */ -class decoder : public rs { - public: - decoder(uint32_t k, uint32_t n); - - /** - * Consume source symbol - */ - void consume(const fec::buffer &packet, uint32_t i); - - /** - * Consume repair symbol - */ - void consume(const fec::buffer &packet); - - /** - * Clear decoder to reuse - */ - void clear() override { - rs::clear(); - src_blocks_.clear(); - parked_packets_.clear(); - } - - private: - void recoverPackets(SourceBlocks::iterator &src_block_it); - - private: - /** - * Map of source blocks. We use a map because we may receive symbols belonging - * to diffreent source blocks at the same time, so we need to be able to - * decode many source symbols at the same time. - */ - SourceBlocks src_blocks_; - - /** - * Unordered Map of source symbols for which we did not receive any repair - * symbol in the same source block. Notably this happens when: - * - * - We receive the source symbols first and the repair symbols after - * - We received only source symbols for a given block. In that case it does - * not make any sense to build the source block, since we received all the - * source packet of the block. - */ - std::unordered_map<uint32_t, std::vector<std::pair<buffer, uint32_t>>> - parked_packets_; -}; - -} // namespace fec - -} // namespace core - -} // namespace transport diff --git a/libtransport/src/core/tcp_socket_connector.cc b/libtransport/src/core/tcp_socket_connector.cc index fa029c6fc..a30264271 100644 --- a/libtransport/src/core/tcp_socket_connector.cc +++ b/libtransport/src/core/tcp_socket_connector.cc @@ -18,8 +18,8 @@ #include <hicn/transport/portability/win_portability.h> #endif +#include <glog/logging.h> #include <hicn/transport/errors/errors.h> -#include <hicn/transport/utils/log.h> #include <hicn/transport/utils/object_pool.h> #include <thread> @@ -162,7 +162,7 @@ void TcpSocketConnector::doWrite() { // The connection has been closed by the application. return; } else { - TRANSPORT_LOGE("%d %s", ec.value(), ec.message().c_str()); + LOG(ERROR) << ec.value() << ":" << ec.message(); tryReconnect(); } }); @@ -182,7 +182,7 @@ void TcpSocketConnector::doReadBody(std::size_t body_length) { // The connection has been closed by the application. return; } else { - TRANSPORT_LOGE("%d %s", ec.value(), ec.message().c_str()); + LOG(ERROR) << ec.value() << " " << ec.message(); tryReconnect(); } }); @@ -203,23 +203,23 @@ void TcpSocketConnector::doReadHeader() { 0) { doReadBody(body_length - length); } else { - TRANSPORT_LOGE("Decoding error. Ignoring packet."); + LOG(ERROR) << "Decoding error. Ignoring packet."; } } else if (ec.value() == static_cast<int>(std::errc::operation_canceled)) { // The connection has been closed by the application. return; } else { - TRANSPORT_LOGE("%d %s", ec.value(), ec.message().c_str()); + LOG(ERROR) << ec.value() << " " << ec.message(); tryReconnect(); } }); } void TcpSocketConnector::tryReconnect() { - if (state_ == ConnectorState::CONNECTED) { - TRANSPORT_LOGE("Connection lost. Trying to reconnect...\n"); - state_ = ConnectorState::CONNECTING; + if (state_ == Connector::State::CONNECTED) { + LOG(ERROR) << "Connection lost. Trying to reconnect..."; + state_ = Connector::State::CONNECTING; is_reconnection_ = true; io_service_.post([this]() { if (socket_.is_open()) { @@ -250,7 +250,7 @@ void TcpSocketConnector::doConnect() { if (is_reconnection_) { is_reconnection_ = false; - TRANSPORT_LOGI("Connection recovered!\n"); + LOG(INFO) << "Connection recovered!"; on_reconnect_callback_(); } } else { @@ -274,7 +274,7 @@ void TcpSocketConnector::handleDeadline(const std::error_code &ec) { if (!ec) { io_service_.post([this]() { socket_.close(); - TRANSPORT_LOGE("Error connecting. Is the forwarder running?\n"); + LOG(ERROR) << "Error connecting. Is the forwarder running?"; io_service_.stop(); }); } diff --git a/libtransport/src/core/tcp_socket_connector.h b/libtransport/src/core/tcp_socket_connector.h index 9dbd250d1..21db8301e 100644 --- a/libtransport/src/core/tcp_socket_connector.h +++ b/libtransport/src/core/tcp_socket_connector.h @@ -17,11 +17,10 @@ #include <core/connector.h> #include <hicn/transport/config.h> +#include <hicn/transport/core/asio_wrapper.h> #include <hicn/transport/core/name.h> #include <hicn/transport/utils/branch_prediction.h> -#include <asio.hpp> -#include <asio/steady_timer.hpp> #include <deque> namespace transport { diff --git a/libtransport/src/core/udp_socket_connector.cc b/libtransport/src/core/udp_socket_connector.cc deleted file mode 100644 index f5ddd6270..000000000 --- a/libtransport/src/core/udp_socket_connector.cc +++ /dev/null @@ -1,224 +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. - */ - -#ifdef _WIN32 -#include <hicn/transport/portability/win_portability.h> -#endif - -#include <hicn/transport/errors/errors.h> -#include <hicn/transport/utils/log.h> -#include <hicn/transport/utils/object_pool.h> - -#include <core/udp_socket_connector.h> - -#include <thread> -#include <vector> - -namespace transport { - -namespace core { - -UdpSocketConnector::UdpSocketConnector( - PacketReceivedCallback &&receive_callback, - OnReconnect &&on_reconnect_callback, asio::io_service &io_service, - std::string app_name) - : Connector(std::move(receive_callback), std::move(on_reconnect_callback)), - io_service_(io_service), - socket_(io_service_), - resolver_(io_service_), - connection_timer_(io_service_), - read_msg_(packet_pool_.makePtr(nullptr)), - is_reconnection_(false), - data_available_(false), - app_name_(app_name) {} - -UdpSocketConnector::~UdpSocketConnector() {} - -void UdpSocketConnector::connect(std::string ip_address, std::string port) { - endpoint_iterator_ = resolver_.resolve( - {ip_address, port, asio::ip::resolver_query_base::numeric_service}); - - state_ = ConnectorState::CONNECTING; - doConnect(); -} - -void UdpSocketConnector::send(const uint8_t *packet, std::size_t len, - const PacketSentCallback &packet_sent) { - if (packet_sent != 0) { - socket_.async_send( - asio::buffer(packet, len), - [packet_sent](std::error_code ec, std::size_t /*length*/) { - packet_sent(); - }); - } else { - if (state_ == ConnectorState::CONNECTED) { - try { - socket_.send(asio::buffer(packet, len)); - } catch (std::system_error &err) { - TRANSPORT_LOGE( - "Sending of disconnect message to forwarder failed. Reason: %s", - err.what()); - } - } - } -} - -void UdpSocketConnector::send(const Packet::MemBufPtr &packet) { - io_service_.post([this, packet]() { - bool write_in_progress = !output_buffer_.empty(); - output_buffer_.push_back(std::move(packet)); - if (TRANSPORT_EXPECT_TRUE(state_ == ConnectorState::CONNECTED)) { - if (!write_in_progress) { - doWrite(); - } - } else { - // Tell the handle connect it has data to write - data_available_ = true; - } - }); -} - -void UdpSocketConnector::close() { - if (io_service_.stopped()) { - doClose(); - } else { - io_service_.dispatch(std::bind(&UdpSocketConnector::doClose, this)); - } -} - -void UdpSocketConnector::doClose() { - if (state_ != ConnectorState::CLOSED) { - state_ = ConnectorState::CLOSED; - if (socket_.is_open()) { - socket_.shutdown(asio::ip::tcp::socket::shutdown_type::shutdown_both); - socket_.close(); - } - } -} - -void UdpSocketConnector::doWrite() { - auto packet = output_buffer_.front().get(); - auto array = std::vector<asio::const_buffer>(); - - const utils::MemBuf *current = packet; - do { - array.push_back(asio::const_buffer(current->data(), current->length())); - current = current->next(); - } while (current != packet); - - socket_.async_send(std::move(array), [this](std::error_code ec, - std::size_t length) { - if (TRANSPORT_EXPECT_TRUE(!ec)) { - output_buffer_.pop_front(); - if (!output_buffer_.empty()) { - doWrite(); - } - } else if (ec.value() == static_cast<int>(std::errc::operation_canceled)) { - // The connection has been closed by the application. - return; - } else { - TRANSPORT_LOGE("%d %s", ec.value(), ec.message().c_str()); - tryReconnect(); - } - }); -} - -void UdpSocketConnector::doRead() { - read_msg_ = getPacket(); - socket_.async_receive( - asio::buffer(read_msg_->writableData(), Connector::packet_size), - [this](std::error_code ec, std::size_t length) { - if (TRANSPORT_EXPECT_TRUE(!ec)) { - read_msg_->append(length); - receive_callback_(std::move(read_msg_)); - doRead(); - } else if (ec.value() == - static_cast<int>(std::errc::operation_canceled)) { - // The connection has been closed by the application. - return; - } else { - TRANSPORT_LOGE("%d %s", ec.value(), ec.message().c_str()); - tryReconnect(); - } - }); -} - -void UdpSocketConnector::tryReconnect() { - if (state_ == ConnectorState::CONNECTED) { - TRANSPORT_LOGE("Connection lost. Trying to reconnect...\n"); - state_ = ConnectorState::CONNECTING; - is_reconnection_ = true; - io_service_.post([this]() { - if (socket_.is_open()) { - socket_.shutdown(asio::ip::tcp::socket::shutdown_type::shutdown_both); - socket_.close(); - } - - doConnect(); - startConnectionTimer(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - }); - } -} - -void UdpSocketConnector::doConnect() { - asio::async_connect( - socket_, endpoint_iterator_, - [this](std::error_code ec, udp::resolver::iterator) { - if (!ec) { - connection_timer_.cancel(); - state_ = ConnectorState::CONNECTED; - doRead(); - - if (data_available_) { - data_available_ = false; - doWrite(); - } - - if (is_reconnection_) { - is_reconnection_ = false; - } - - on_reconnect_callback_(); - } else { - doConnect(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - }); -} - -bool UdpSocketConnector::checkConnected() { - return state_ == ConnectorState::CONNECTED; -} - -void UdpSocketConnector::startConnectionTimer() { - connection_timer_.expires_from_now(std::chrono::seconds(60)); - connection_timer_.async_wait(std::bind(&UdpSocketConnector::handleDeadline, - this, std::placeholders::_1)); -} - -void UdpSocketConnector::handleDeadline(const std::error_code &ec) { - if (!ec) { - io_service_.post([this]() { - socket_.close(); - TRANSPORT_LOGE("Error connecting. Is the forwarder running?\n"); - io_service_.stop(); - }); - } -} - -} // end namespace core - -} // end namespace transport diff --git a/libtransport/src/core/udp_socket_connector.h b/libtransport/src/core/udp_socket_connector.h deleted file mode 100644 index 5fdb6aeec..000000000 --- a/libtransport/src/core/udp_socket_connector.h +++ /dev/null @@ -1,85 +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. - */ - -#pragma once - -#include <hicn/transport/config.h> -#include <hicn/transport/core/name.h> -#include <hicn/transport/utils/branch_prediction.h> - -#include <core/connector.h> - -#include <asio.hpp> -#include <asio/steady_timer.hpp> -#include <deque> - -namespace transport { -namespace core { - -using asio::ip::udp; - -class UdpSocketConnector : public Connector { - public: - UdpSocketConnector(PacketReceivedCallback &&receive_callback, - OnReconnect &&reconnect_callback, - asio::io_service &io_service, - std::string app_name = "Libtransport"); - - ~UdpSocketConnector() override; - - void send(const Packet::MemBufPtr &packet) override; - - void send(const uint8_t *packet, std::size_t len, - const PacketSentCallback &packet_sent = 0) override; - - void close() override; - - void connect(std::string ip_address = "127.0.0.1", std::string port = "9695"); - - private: - void doConnect(); - - void doRead(); - - void doWrite(); - - void doClose(); - - bool checkConnected(); - - private: - void handleDeadline(const std::error_code &ec); - - void startConnectionTimer(); - - void tryReconnect(); - - asio::io_service &io_service_; - asio::ip::udp::socket socket_; - asio::ip::udp::resolver resolver_; - asio::ip::udp::resolver::iterator endpoint_iterator_; - asio::steady_timer connection_timer_; - - utils::ObjectPool<utils::MemBuf>::Ptr read_msg_; - - bool is_reconnection_; - bool data_available_; - - std::string app_name_; -}; - -} // end namespace core - -} // end namespace transport diff --git a/libtransport/src/core/vpp_forwarder_interface.cc b/libtransport/src/core/vpp_forwarder_interface.cc deleted file mode 100644 index 9f7beeb37..000000000 --- a/libtransport/src/core/vpp_forwarder_interface.cc +++ /dev/null @@ -1,226 +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/transport/config.h> - -#ifdef __vpp__ - -#include <core/hicn_vapi.h> -#include <core/memif_vapi.h> -#include <core/vpp_forwarder_interface.h> - -extern "C" { -#include <memif/libmemif.h> -}; - -typedef enum { MASTER = 0, SLAVE = 1 } memif_role_t; - -#define MEMIF_DEFAULT_RING_SIZE 2048 -#define MEMIF_DEFAULT_RX_QUEUES 1 -#define MEMIF_DEFAULT_TX_QUEUES 1 -#define MEMIF_DEFAULT_BUFFER_SIZE 2048 - -namespace transport { - -namespace core { - -VPPForwarderInterface::VPPForwarderInterface(MemifConnector &connector) - : ForwarderInterface<VPPForwarderInterface, MemifConnector>(connector), - sw_if_index_(~0), - face_id1_(~0), - face_id2_(~0), - is_consumer_(false) {} - -VPPForwarderInterface::~VPPForwarderInterface() {} - -/** - * @brief Create a memif interface in the local VPP forwarder. - */ -uint32_t VPPForwarderInterface::getMemifConfiguration() { - memif_create_params_t input_params = {0}; - - int ret = - memif_vapi_get_next_memif_id(VPPForwarderInterface::sock_, &memif_id_); - - if (ret < 0) { - throw errors::RuntimeException( - "Error getting next memif id. Could not create memif interface."); - } - - input_params.id = memif_id_; - input_params.role = memif_role_t::MASTER; - input_params.mode = memif_interface_mode_t::MEMIF_INTERFACE_MODE_IP; - input_params.rx_queues = MEMIF_DEFAULT_RX_QUEUES; - input_params.tx_queues = MEMIF_DEFAULT_TX_QUEUES; - input_params.ring_size = MEMIF_DEFAULT_RING_SIZE; - input_params.buffer_size = MEMIF_DEFAULT_BUFFER_SIZE; - - memif_output_params_t output_params = {0}; - - ret = memif_vapi_create_memif(VPPForwarderInterface::sock_, &input_params, - &output_params); - - if (ret < 0) { - throw errors::RuntimeException( - "Error creating memif interface in the local VPP forwarder."); - } - - return output_params.sw_if_index; -} - -void VPPForwarderInterface::consumerConnection() { - hicn_consumer_input_params input = {0}; - hicn_consumer_output_params output = {0}; - ip_address_t ip4_address; - ip_address_t ip6_address; - - output.src4 = &ip4_address; - output.src6 = &ip6_address; - input.swif = sw_if_index_; - - int ret = hicn_vapi_register_cons_app(VPPForwarderInterface::sock_, &input, - &output); - - if (ret < 0) { - throw errors::RuntimeException(hicn_vapi_get_error_string(ret)); - } - - face_id1_ = output.face_id1; - face_id2_ = output.face_id2; - - std::memcpy(inet_address_.v4.as_u8, output.src4->v4.as_u8, IPV4_ADDR_LEN); - - std::memcpy(inet6_address_.v6.as_u8, output.src6->v6.as_u8, IPV6_ADDR_LEN); -} - -void VPPForwarderInterface::producerConnection() { - // Producer connection will be set when we set the first route. -} - -void VPPForwarderInterface::connect(bool is_consumer) { - int retry = 20; - - TRANSPORT_LOGI("Connecting to VPP through vapi."); - vapi_error_e ret = vapi_connect_safe(&sock_, 0); - - while (ret != VAPI_OK && retry > 0) { - TRANSPORT_LOGE("Error connecting to VPP through vapi. Retrying.."); - --retry; - ret = vapi_connect_safe(&sock_, 0); - } - - if (ret != VAPI_OK) { - throw std::runtime_error( - "Impossible to connect to forwarder. Is VPP running?"); - } - - - TRANSPORT_LOGI("Connected to VPP through vapi."); - - sw_if_index_ = getMemifConfiguration(); - - is_consumer_ = is_consumer; - if (is_consumer_) { - consumerConnection(); - } - - connector_.connect(memif_id_, 0); -} - -void VPPForwarderInterface::registerRoute(Prefix &prefix) { - ip_prefix_t &addr = prefix.toIpPrefixStruct(); - - ip_prefix_t producer_prefix; - ip_address_t producer_locator; - - if (face_id1_ == uint32_t(~0)) { - hicn_producer_input_params input; - std::memset(&input, 0, sizeof(input)); - - hicn_producer_output_params output; - std::memset(&output, 0, sizeof(output)); - - input.prefix = &producer_prefix; - output.prod_addr = &producer_locator; - - // Here we have to ask to the actual connector what is the - // memif_id, since this function should be called after the - // memif creation. - input.swif = sw_if_index_; - input.prefix->address = addr.address; - input.prefix->family = addr.family; - input.prefix->len = addr.len; - input.cs_reserved = content_store_reserved_; - - int ret = hicn_vapi_register_prod_app(VPPForwarderInterface::sock_, &input, - &output); - - if (ret < 0) { - throw errors::RuntimeException(hicn_vapi_get_error_string(ret)); - } - - inet6_address_ = *output.prod_addr; - - face_id1_ = output.face_id; - } else { - hicn_producer_set_route_params params; - params.prefix = &producer_prefix; - params.prefix->address = addr.address; - params.prefix->family = addr.family; - params.prefix->len = addr.len; - params.prod_addr = &producer_locator; - - int ret = hicn_vapi_register_route(VPPForwarderInterface::sock_, ¶ms); - - if (ret < 0) { - throw errors::RuntimeException(hicn_vapi_get_error_string(ret)); - } - } -} - -void VPPForwarderInterface::closeConnection() { - if (VPPForwarderInterface::sock_) { - connector_.close(); - - if (is_consumer_) { - hicn_del_face_app_input_params params; - params.face_id = face_id1_; - hicn_vapi_face_cons_del(VPPForwarderInterface::sock_, ¶ms); - params.face_id = face_id2_; - hicn_vapi_face_cons_del(VPPForwarderInterface::sock_, ¶ms); - } else { - hicn_del_face_app_input_params params; - params.face_id = face_id1_; - hicn_vapi_face_prod_del(VPPForwarderInterface::sock_, ¶ms); - } - - if (sw_if_index_ != uint32_t(~0)) { - int ret = - memif_vapi_delete_memif(VPPForwarderInterface::sock_, sw_if_index_); - if (ret < 0) { - TRANSPORT_LOGE("Error deleting memif with sw idx %u.", sw_if_index_); - } - } - - vapi_disconnect_safe(); - VPPForwarderInterface::sock_ = nullptr; - } -} - -} // namespace core - -} // namespace transport - -#endif diff --git a/libtransport/src/core/vpp_forwarder_interface.h b/libtransport/src/core/vpp_forwarder_interface.h deleted file mode 100644 index 31d23b40d..000000000 --- a/libtransport/src/core/vpp_forwarder_interface.h +++ /dev/null @@ -1,88 +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. - */ - -#pragma once - -#include <hicn/transport/config.h> - -#ifdef __vpp__ - -#include <hicn/transport/core/prefix.h> - - -#ifdef always_inline -#undef always_inline -#endif -extern "C" { -#include <vapi/vapi_safe.h> -}; - -#include <core/forwarder_interface.h> -#include <core/memif_connector.h> - -#include <deque> - -namespace transport { - -namespace core { - -class VPPForwarderInterface - : public ForwarderInterface<VPPForwarderInterface, MemifConnector> { - static constexpr std::uint16_t interface_mtu = 1500; - - public: - VPPForwarderInterface(MemifConnector &connector); - - typedef MemifConnector ConnectorType; - - ~VPPForwarderInterface(); - - void connect(bool is_consumer); - - void registerRoute(Prefix &prefix); - - TRANSPORT_ALWAYS_INLINE std::uint16_t getMtu() { return interface_mtu; } - - TRANSPORT_ALWAYS_INLINE static bool isControlMessageImpl( - const uint8_t *message) { - return false; - } - - TRANSPORT_ALWAYS_INLINE void processControlMessageReplyImpl( - Packet::MemBufPtr &&packet_buffer) {} - - void closeConnection(); - - private: - uint32_t getMemifConfiguration(); - - void consumerConnection(); - - void producerConnection(); - - uint32_t memif_id_; - uint32_t sw_if_index_; - // A consumer socket in vpp has two faces (ipv4 and ipv6) - uint32_t face_id1_; - uint32_t face_id2_; - bool is_consumer_; - vapi_ctx_t sock_; -}; - -} // namespace core - -} // namespace transport - -#endif |