From d22d2b4785e2f4eafc8dda2ae032931f89c7e45f Mon Sep 17 00:00:00 2001 From: Mauro Sardara Date: Mon, 5 Jun 2017 16:48:29 +0200 Subject: - Added new interface between applications and library: - Application retrieve resources using the common HTTP url format. - Translation between network names and application names performed by the library - Added basic error handling - Added utils for http connections - Added support for differetn build types (DEBUG, RELEASE, RELEASE with debug symbols, RELEASE with min size executable) - Added support for iOS Change-Id: I8ba2a5d8bd70a4f7721e1bbc2efe3fb81ed2c98c Signed-off-by: Mauro Sardara --- .gitignore | 1 - CMakeLists.txt | 116 ++-- apps/CMakeLists.txt | 2 +- apps/consumers/CMakeLists.txt | 9 - apps/consumers/icnet_consumer_dash.cc | 217 ------ apps/consumers/icnet_consumer_test.cc | 70 +- apps/consumers/icnet_iget.cc | 159 ----- apps/general/icnet_general_test.cc | 2 +- apps/http/CMakeLists.txt | 31 + apps/http/icnet_http_dash_client.cc | 84 +++ apps/http/icnet_http_echo_server.cc | 53 ++ apps/http/icnet_iget.cc | 71 ++ apps/iping/iPing_Client.c | 11 +- apps/iping/iPing_Server.c | 6 +- apps/producers/icnet_producer_test.cc | 55 +- dockerfile.ubuntu.xenial | 19 + icnet/CMakeLists.txt | 156 ++++- icnet/ccnx/icnet_ccnx_content_object.cc | 4 +- icnet/ccnx/icnet_ccnx_content_object.h | 4 +- icnet/ccnx/icnet_ccnx_interest.cc | 12 +- icnet/ccnx/icnet_ccnx_interest.h | 9 +- icnet/ccnx/icnet_ccnx_local_connector.cc | 2 +- icnet/errors/icnet_errors.h | 21 + .../icnet_errors_malformed_name_exception.cc | 32 + .../errors/icnet_errors_malformed_name_exception.h | 32 + .../icnet_errors_malformed_packet_exception.cc | 32 + .../icnet_errors_malformed_packet_exception.h | 32 + .../icnet_errors_not_implemented_exception.cc | 33 + .../icnet_errors_not_implemented_exception.h | 32 + icnet/errors/icnet_errors_runtime_exception.cc | 32 + icnet/errors/icnet_errors_runtime_exception.h | 34 + icnet/errors/icnet_errors_tokenizer_exception.cc | 33 + icnet/errors/icnet_errors_tokenizer_exception.h | 32 + icnet/http/icnet_http_client_connection.cc | 119 ++++ icnet/http/icnet_http_client_connection.h | 56 ++ icnet/http/icnet_http_default_values.h | 30 + icnet/http/icnet_http_facade.h | 22 + icnet/http/icnet_http_request.cc | 101 +++ icnet/http/icnet_http_request.h | 71 ++ icnet/http/icnet_http_server_acceptor.cc | 171 +++++ icnet/http/icnet_http_server_acceptor.h | 62 ++ icnet/http/icnet_http_server_publisher.cc | 79 +++ icnet/http/icnet_http_server_publisher.h | 72 ++ icnet/transport/icnet_common.h | 50 -- icnet/transport/icnet_content_store.cc | 76 --- icnet/transport/icnet_content_store.h | 60 -- icnet/transport/icnet_download_observer.h | 32 - icnet/transport/icnet_rate_estimation.cc | 324 --------- icnet/transport/icnet_rate_estimation.h | 187 ------ icnet/transport/icnet_socket.h | 124 ---- icnet/transport/icnet_socket_consumer.cc | 614 ----------------- icnet/transport/icnet_socket_consumer.h | 161 ----- .../icnet_socket_options_default_values.h | 61 -- icnet/transport/icnet_socket_options_keys.h | 95 --- icnet/transport/icnet_socket_producer.cc | 720 -------------------- icnet/transport/icnet_socket_producer.h | 172 ----- icnet/transport/icnet_transport.cc | 32 - icnet/transport/icnet_transport.h | 43 -- icnet/transport/icnet_transport_common.h | 50 ++ icnet/transport/icnet_transport_content_store.cc | 80 +++ icnet/transport/icnet_transport_content_store.h | 64 ++ .../transport/icnet_transport_download_observer.h | 36 + icnet/transport/icnet_transport_protocol.cc | 36 + icnet/transport/icnet_transport_protocol.h | 47 ++ icnet/transport/icnet_transport_raaqm.cc | 4 + icnet/transport/icnet_transport_raaqm.h | 6 +- icnet/transport/icnet_transport_raaqm_data_path.cc | 4 + icnet/transport/icnet_transport_raaqm_data_path.h | 4 + icnet/transport/icnet_transport_rate_estimation.cc | 328 ++++++++++ icnet/transport/icnet_transport_rate_estimation.h | 191 ++++++ icnet/transport/icnet_transport_socket.h | 128 ++++ icnet/transport/icnet_transport_socket_consumer.cc | 618 +++++++++++++++++ icnet/transport/icnet_transport_socket_consumer.h | 165 +++++ ...icnet_transport_socket_options_default_values.h | 65 ++ .../icnet_transport_socket_options_keys.h | 99 +++ icnet/transport/icnet_transport_socket_producer.cc | 728 +++++++++++++++++++++ icnet/transport/icnet_transport_socket_producer.h | 178 +++++ icnet/transport/icnet_transport_vegas.cc | 17 +- icnet/transport/icnet_transport_vegas.h | 6 +- .../icnet_transport_vegas_rto_estimator.cc | 6 +- .../icnet_transport_vegas_rto_estimator.h | 6 +- icnet/utils/icnet_utils_array.cc | 52 ++ icnet/utils/icnet_utils_array.h | 45 ++ icnet/utils/icnet_utils_daemonizator.cc | 74 +++ icnet/utils/icnet_utils_daemonizator.h | 29 + icnet/utils/icnet_utils_hash.cc | 64 ++ icnet/utils/icnet_utils_hash.h | 42 ++ icnet/utils/icnet_utils_string_tokenizer.cc | 52 ++ icnet/utils/icnet_utils_string_tokenizer.h | 38 ++ icnet/utils/icnet_utils_uri.cc | 137 ++++ icnet/utils/icnet_utils_uri.h | 51 ++ 91 files changed, 5072 insertions(+), 3350 deletions(-) delete mode 100755 apps/consumers/icnet_consumer_dash.cc delete mode 100755 apps/consumers/icnet_iget.cc create mode 100644 apps/http/CMakeLists.txt create mode 100644 apps/http/icnet_http_dash_client.cc create mode 100644 apps/http/icnet_http_echo_server.cc create mode 100644 apps/http/icnet_iget.cc create mode 100644 dockerfile.ubuntu.xenial create mode 100644 icnet/errors/icnet_errors.h create mode 100644 icnet/errors/icnet_errors_malformed_name_exception.cc create mode 100644 icnet/errors/icnet_errors_malformed_name_exception.h create mode 100644 icnet/errors/icnet_errors_malformed_packet_exception.cc create mode 100644 icnet/errors/icnet_errors_malformed_packet_exception.h create mode 100644 icnet/errors/icnet_errors_not_implemented_exception.cc create mode 100644 icnet/errors/icnet_errors_not_implemented_exception.h create mode 100644 icnet/errors/icnet_errors_runtime_exception.cc create mode 100644 icnet/errors/icnet_errors_runtime_exception.h create mode 100644 icnet/errors/icnet_errors_tokenizer_exception.cc create mode 100644 icnet/errors/icnet_errors_tokenizer_exception.h create mode 100644 icnet/http/icnet_http_client_connection.cc create mode 100644 icnet/http/icnet_http_client_connection.h create mode 100644 icnet/http/icnet_http_default_values.h create mode 100644 icnet/http/icnet_http_facade.h create mode 100644 icnet/http/icnet_http_request.cc create mode 100644 icnet/http/icnet_http_request.h create mode 100644 icnet/http/icnet_http_server_acceptor.cc create mode 100644 icnet/http/icnet_http_server_acceptor.h create mode 100644 icnet/http/icnet_http_server_publisher.cc create mode 100644 icnet/http/icnet_http_server_publisher.h delete mode 100644 icnet/transport/icnet_common.h delete mode 100644 icnet/transport/icnet_content_store.cc delete mode 100644 icnet/transport/icnet_content_store.h delete mode 100644 icnet/transport/icnet_download_observer.h delete mode 100644 icnet/transport/icnet_rate_estimation.cc delete mode 100644 icnet/transport/icnet_rate_estimation.h delete mode 100644 icnet/transport/icnet_socket.h delete mode 100644 icnet/transport/icnet_socket_consumer.cc delete mode 100644 icnet/transport/icnet_socket_consumer.h delete mode 100644 icnet/transport/icnet_socket_options_default_values.h delete mode 100644 icnet/transport/icnet_socket_options_keys.h delete mode 100644 icnet/transport/icnet_socket_producer.cc delete mode 100644 icnet/transport/icnet_socket_producer.h delete mode 100644 icnet/transport/icnet_transport.cc delete mode 100644 icnet/transport/icnet_transport.h create mode 100644 icnet/transport/icnet_transport_common.h create mode 100644 icnet/transport/icnet_transport_content_store.cc create mode 100644 icnet/transport/icnet_transport_content_store.h create mode 100644 icnet/transport/icnet_transport_download_observer.h create mode 100644 icnet/transport/icnet_transport_protocol.cc create mode 100644 icnet/transport/icnet_transport_protocol.h create mode 100644 icnet/transport/icnet_transport_rate_estimation.cc create mode 100644 icnet/transport/icnet_transport_rate_estimation.h create mode 100644 icnet/transport/icnet_transport_socket.h create mode 100644 icnet/transport/icnet_transport_socket_consumer.cc create mode 100644 icnet/transport/icnet_transport_socket_consumer.h create mode 100644 icnet/transport/icnet_transport_socket_options_default_values.h create mode 100644 icnet/transport/icnet_transport_socket_options_keys.h create mode 100644 icnet/transport/icnet_transport_socket_producer.cc create mode 100644 icnet/transport/icnet_transport_socket_producer.h create mode 100644 icnet/utils/icnet_utils_array.cc create mode 100644 icnet/utils/icnet_utils_array.h create mode 100644 icnet/utils/icnet_utils_daemonizator.cc create mode 100644 icnet/utils/icnet_utils_daemonizator.h create mode 100644 icnet/utils/icnet_utils_hash.cc create mode 100644 icnet/utils/icnet_utils_hash.h create mode 100644 icnet/utils/icnet_utils_string_tokenizer.cc create mode 100644 icnet/utils/icnet_utils_string_tokenizer.h create mode 100644 icnet/utils/icnet_utils_uri.cc create mode 100644 icnet/utils/icnet_utils_uri.h diff --git a/.gitignore b/.gitignore index b354d71a..fe47da41 100644 --- a/.gitignore +++ b/.gitignore @@ -27,5 +27,4 @@ Makefile *.swp libtool *~ -*.pyc .idea diff --git a/CMakeLists.txt b/CMakeLists.txt index e166c4cf..e5ed91f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,14 +15,16 @@ cmake_minimum_required(VERSION 3.2) project(Libicnet) set(CMAKE_CXX_STANDARD 11) -## Set build folders -#set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) -#set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) -#set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) +if (NOT CMAKE_BUILD_TYPE) + message(STATUS "No build type selected, default to Release") + set(CMAKE_BUILD_TYPE "Release") +endif () set(CCNX_API icnet/ccnx) set(CP_API icnet/transport) -set(COMMON_INCLUDES icnet/common-includes) +set(ERRORS icnet/errors) +set(UTILS icnet/utils) +set(HTTP icnet/http) set(APPS apps) option(BUILD_APPS "Build apps" ON) @@ -40,62 +42,88 @@ include_directories( ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/${CP_API} ${PROJECT_SOURCE_DIR}/${CCNX_API} - ${PROJECT_SOURCE_DIR}/${COMMON_INCLUDES} + ${PROJECT_SOURCE_DIR}/${ERRORS} + ${PROJECT_SOURCE_DIR}/${UTILS} + ${PROJECT_SOURCE_DIR}/${HTTP} ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") -find_package(LongBow REQUIRED) -include_directories(${LONGBOW_INCLUDE_DIRS}) +set(CMAKE_VERBOSE_MAKEFILE on) -find_package(Libparc REQUIRED) -include_directories(${LIBPARC_INCLUDE_DIRS}) +if(COMPILE_FOR_IOS) + set(OPENSSL_ROOT_DIR $ENV{CCNX_DEPENDENCIES}) + find_host_package ( OpenSSL REQUIRED ) -find_package(CCNX_Common REQUIRED) -include_directories(${CCNX_COMMON_INCLUDE_DIRS}) - -find_package(CCNX_Transport_Rta REQUIRED) -include_directories(${CCNX_TRANSPORT_RTA_INCLUDE_DIRS}) + set(BOOST_ROOT $ENV{CCNX_DEPENDENCIES}) + find_host_package(Boost 1.53.0 COMPONENTS system REQUIRED) + include_directories(SYSTEM ${Boost_INCLUDE_DIR}) -find_package(CCNX_Portal REQUIRED) -include_directories(${CCNX_PORTAL_INCLUDE_DIRS}) + find_host_package(LongBow REQUIRED) + include_directories(${LONGBOW_INCLUDE_DIRS}) -find_package(Threads REQUIRED) -include_directories(${CMAKE_THREADS_INCLUDE_DIRS}) + find_host_package(Libparc REQUIRED) + include_directories(${LIBPARC_INCLUDE_DIRS}) -find_package(Threads REQUIRED) + find_host_package(CCNX_Common REQUIRED) + include_directories(${CCNX_COMMON_INCLUDE_DIRS}) -set(CMAKE_VERBOSE_MAKEFILE off) + find_host_package(CCNX_Transport_Rta REQUIRED) + include_directories(${CCNX_TRANSPORT_RTA_INCLUDE_DIRS}) -if(ANDROID_API) - include_directories(${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.9/include) - include_directories(${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/include) - set(CCNX_PORTAL_LIBRARIES "$ENV{CCNX_DEPENDENCIES}/lib/libccnx_api_portal.a" ) - set(CCNX_TRANSPORT_RTA_LIBRARIES "$ENV{CCNX_DEPENDENCIES}/lib/libccnx_api_notify.a" "$ENV{CCNX_DEPENDENCIES}/lib/libccnx_api_control.a" "$ENV{CCNX_DEPENDENCIES}/lib/libccnx_transport_rta.a") - set(CCNX_COMMON_LIBRARIES "$ENV{CCNX_DEPENDENCIES}/lib/libccnx_common.a") - set(LIBPARC_LIBRARIES "$ENV{CCNX_DEPENDENCIES}/lib/libparc.a") - set(LONGBOW_LIBRARIES "$ENV{CCNX_DEPENDENCIES}/lib/liblongbow.a" "$ENV{CCNX_DEPENDENCIES}/lib/liblongbow-ansiterm.a" "$ENV{CCNX_DEPENDENCIES}/lib/liblongbow-textplain.a" "$ENV{CCNX_DEPENDENCIES}/lib/libcrypto.a" "$ENV{CCNX_DEPENDENCIES}/lib/libssl.a") - set(Boost_LIBRARIES $ENV{CCNX_DEPENDENCIES}/lib/libboost_regex.a $ENV{CCNX_DEPENDENCIES}/lib/libboost_system.a $ENV{CCNX_DEPENDENCIES}/lib/libboost_thread.a $ENV{CCNX_DEPENDENCIES}/lib/libboost_filesystem.a $ENV{CCNX_DEPENDENCIES}/lib/libboost_date_time.a $ENV{CCNX_DEPENDENCIES}/lib/libboost_chrono.a) - set(ANDROID_LIBRARIES "${ANDROID_NDK}/platforms/android-23/arch-arm/usr/lib/libz.a" "${ANDROID_NDK}/platforms/android-23/arch-arm/usr/lib/liblog.so" "$ENV{NDK}/sources/cxx-stl/gnu-libstdc++/4.9/libs/$ENV{ABI}/libgnustl_shared.so" "$ENV{CCNX_DEPENDENCIES}/lib/libcrystax.a" "$ENV{CCNX_DEPENDENCIES}/lib/libevent.a") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} ${ANDROID_C_FLAGS} -std=c++11 -Wall -fpermissive -O3") + find_host_package(CCNX_Portal REQUIRED) + include_directories(${CCNX_PORTAL_INCLUDE_DIRS}) else () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -fpermissive -O3") + find_package(LongBow REQUIRED) + include_directories(${LONGBOW_INCLUDE_DIRS}) + + find_package(Libparc REQUIRED) + include_directories(${LIBPARC_INCLUDE_DIRS}) + + find_package(CCNX_Common REQUIRED) + include_directories(${CCNX_COMMON_INCLUDE_DIRS}) + + find_package(CCNX_Transport_Rta REQUIRED) + include_directories(${CCNX_TRANSPORT_RTA_INCLUDE_DIRS}) + + find_package(CCNX_Portal REQUIRED) + include_directories(${CCNX_PORTAL_INCLUDE_DIRS}) + + find_package(Threads REQUIRED) + include_directories(${CMAKE_THREADS_INCLUDE_DIRS}) + find_package(Boost 1.53.0 COMPONENTS system REQUIRED) include_directories(SYSTEM ${Boost_INCLUDE_DIR}) - if (BUILD_APPS) - set(SUBFOLDERS ${APPS}) - endif (BUILD_APPS) +endif() + +if(ANDROID_API) + include_directories(${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/include) + include_directories(${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.9/include) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ANDROID_C_FLAGS} -Wall") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + + if (NOT COMPILE_FOR_IOS) + if (BUILD_APPS) + set(SUBFOLDERS ${APPS}) + endif (BUILD_APPS) + endif() + endif (ANDROID_API) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS} -fpermissive") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CMAKE_CXX_FLAGS} -fpermissive") +set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${CMAKE_CXX_FLAGS} -fpermissive") + set(LIBRARIES - ${CCNX_PORTAL_LIBRARIES} - ${CCNX_TRANSPORT_RTA_LIBRARIES} - ${CCNX_COMMON_LIBRARIES} - ${LIBPARC_LIBRARIES} - ${Boost_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - ${LONGBOW_LIBRARIES} - ${ANDROID_LIBRARIES}) + ${CCNX_PORTAL_LIBRARIES} + ${CCNX_TRANSPORT_RTA_LIBRARIES} + ${CCNX_COMMON_LIBRARIES} + ${LIBPARC_LIBRARIES} + ${Boost_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ${LONGBOW_LIBRARIES}) set(SUBFOLDERS ${SUBFOLDERS} icnet) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 6708f3b3..a661847f 100755 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -14,4 +14,4 @@ cmake_minimum_required(VERSION 3.2) #include( CTest ) -subdirs(consumers producers general iping) +subdirs(consumers producers general iping http) diff --git a/apps/consumers/CMakeLists.txt b/apps/consumers/CMakeLists.txt index 68e79834..86752da7 100755 --- a/apps/consumers/CMakeLists.txt +++ b/apps/consumers/CMakeLists.txt @@ -14,17 +14,8 @@ cmake_minimum_required(VERSION 3.2) set(CONSUMER_SOURCE_FILES icnet_consumer_test.cc) -set(IGET_SOURCE_FILES icnet_iget.cc) -set(CONSUMERDASH_SOURCE_FILES icnet_consumer_dash.cc) add_executable(consumer-test ${CONSUMER_SOURCE_FILES}) -add_executable(iget ${IGET_SOURCE_FILES}) -add_executable(consumer-dash ${CONSUMERDASH_SOURCE_FILES}) target_link_libraries(consumer-test icnet ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(iget icnet ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(consumer-dash icnet ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) - install(TARGETS consumer-test DESTINATION ${CMAKE_INSTALL_PREFIX}/bin COMPONENT library) -install(TARGETS iget DESTINATION ${CMAKE_INSTALL_PREFIX}/bin COMPONENT library) -install(TARGETS consumer-dash DESTINATION ${CMAKE_INSTALL_PREFIX}/bin COMPONENT library) diff --git a/apps/consumers/icnet_consumer_dash.cc b/apps/consumers/icnet_consumer_dash.cc deleted file mode 100755 index 4ec4a2c9..00000000 --- a/apps/consumers/icnet_consumer_dash.cc +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2017 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 "icnet_socket_consumer.h" - -#define DEFAULT_BETA 0.99 -#define DEFAULT_GAMMA 0.07 - -namespace icnet { - -class CallbackContainer { - public: - CallbackContainer() - : work_(new boost::asio::io_service::work(io_service_)), - handler_(std::async(std::launch::async, [this]() { io_service_.run(); })) { - seen_manifest_segments_ = 0; - seen_data_segments_ = 0; - byte_counter_ = 0; - } - - ~CallbackContainer() { - work_.reset(); - } - - void processPayload(ConsumerSocket &c, const uint8_t *buffer, size_t bufferSize) { - std::cout << "Content retrieved!! Size: " << bufferSize << std::endl; - } - - bool verifyData(ConsumerSocket &c, const ContentObject &contentObject) { - if (contentObject.getContentType() == PayloadType::DATA) { - std::cout << "VERIFY CONTENT" << std::endl; - } else if (contentObject.getContentType() == PayloadType::MANIFEST) { - std::cout << "VERIFY MANIFEST" << std::endl; - } - - return true; - } - - void processLeavingInterest(ConsumerSocket &c, const Interest &interest) { - // std::cout << "LEAVES " << interest.getName().toUri() << std::endl; - } - - private: - int seen_manifest_segments_; - int seen_data_segments_; - int byte_counter_; - boost::asio::io_service io_service_; - std::shared_ptr work_; - std::future handler_; -}; - -class Verificator { - public: - Verificator() { - }; - - ~Verificator() { - } - - bool onPacket(ConsumerSocket &c, const ContentObject &contentObject) { - return true; - } - -}; - -void becomeDaemon() { - pid_t process_id = 0; - pid_t sid = 0; - - // Create child process - process_id = fork(); - - // Indication of fork() failure - if (process_id < 0) { - printf("fork failed!\n"); - // Return failure in exit status - exit(EXIT_FAILURE); - } - - // PARENT PROCESS. Need to kill it. - if (process_id > 0) { - printf("process_id of child process %d \n", process_id); - // return success in exit status - exit(EXIT_SUCCESS); - } - - //unmask the file mode - umask(0); - - //set new session - sid = setsid(); - if (sid < 0) { - // Return failure - exit(EXIT_FAILURE); - } - - // Change the current working directory to root. - chdir("/"); - - // Close stdin. stdout and stderr - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - - // Really start application -} - -int main(int argc, char **argv) { - double beta = DEFAULT_BETA; - double drop_factor = DEFAULT_GAMMA; - bool daemon = false; - bool rtt_stats = false; - int n_segment = 427; - bool looping = false; - - int opt; - while ((opt = getopt(argc, argv, "b:d:DRn:l")) != -1) { - switch (opt) { - case 'b': - beta = std::stod(optarg); - break; - case 'd': - drop_factor = std::stod(optarg); - break; - case 'D': - daemon = true; - break; - case 'R': - rtt_stats = true; - break; - case 'n': - n_segment = std::stoi(optarg); - break; - case 'l': - looping = true; - break; - default: - exit(EXIT_FAILURE); - } - } - - std::string name = "ccnx:/webserver/get/sintel/18000"; - - if (argv[optind] == 0) { - std::cerr << "Using default name ccnx:/webserver/sintel/18000" << std::endl; - } else { - name = argv[optind]; - } - - if (daemon) { - becomeDaemon(); - } - - ConsumerSocket c(Name(name.c_str()), TransportProtocolAlgorithms::RAAQM); - - CallbackContainer stubs; - Verificator verificator; - - c.setSocketOption(GeneralTransportOptions::INTEREST_LIFETIME, 1001); - c.setSocketOption(RaaqmTransportOptions::BETA_VALUE, beta); - c.setSocketOption(RaaqmTransportOptions::DROP_FACTOR, drop_factor); - c.setSocketOption(GeneralTransportOptions::MAX_INTEREST_RETX, 10); - c.setSocketOption(OtherOptions::VIRTUAL_DOWNLOAD, true); - c.setSocketOption(RaaqmTransportOptions::RTT_STATS, rtt_stats); - - c.setSocketOption(ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY, - (ConsumerContentObjectVerificationCallback) std::bind(&Verificator::onPacket, - &verificator, - std::placeholders::_1, - std::placeholders::_2)); - - c.setSocketOption(ConsumerCallbacksOptions::CONTENT_RETRIEVED, - (ConsumerContentCallback) std::bind(&CallbackContainer::processPayload, - &stubs, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3)); - - c.setSocketOption(ConsumerCallbacksOptions::INTEREST_OUTPUT, - (ConsumerInterestCallback) std::bind(&CallbackContainer::processLeavingInterest, - &stubs, - std::placeholders::_1, - std::placeholders::_2)); - - do { - std::stringstream ss; - for (int i = 1; i < n_segment; i++) { - ss << "ccnx:/seg_" << i << ".m4s"; - auto str = ss.str(); - c.consume(Name(str)); - ss.str(""); - } - } while (looping); - - c.stop(); - - return 0; - -} - -} // end namespace icnet - -int main(int argc, char **argv) { - return icnet::main(argc, argv); -} diff --git a/apps/consumers/icnet_consumer_test.cc b/apps/consumers/icnet_consumer_test.cc index d5b57d6f..5c7eecb0 100755 --- a/apps/consumers/icnet_consumer_test.cc +++ b/apps/consumers/icnet_consumer_test.cc @@ -13,13 +13,16 @@ * limitations under the License. */ -#include "icnet_socket_consumer.h" +#include "icnet_transport_socket_consumer.h" +#include "icnet_utils_daemonizator.h" #define DEFAULT_BETA 0.99 #define DEFAULT_GAMMA 0.07 namespace icnet { +namespace transport { + class CallbackContainer { public: CallbackContainer() @@ -34,20 +37,20 @@ class CallbackContainer { work_.reset(); } - void processPayload(ConsumerSocket &c, const uint8_t *buffer, size_t bufferSize) { - std::cout << "Content retrieved!! Size: " << bufferSize << std::endl; + void processPayload(ConsumerSocket &c, std::vector &&payload) { + std::cout << "Content retrieved!! Size: " << payload.size() << std::endl; - io_service_.dispatch([buffer, bufferSize]() { - std::ofstream file("ciao.txt", std::ofstream::binary); - file.write((char *) buffer, bufferSize); + io_service_.dispatch([payload]() { + std::ofstream file("consumer_test_file", std::ofstream::binary); + file.write((char *) payload.data(), payload.size()); file.close(); }); } bool verifyData(ConsumerSocket &c, const ContentObject &contentObject) { - if (contentObject.getContentType() == PayloadType::DATA) { + if (contentObject.getPayloadType() == PayloadType::DATA) { std::cout << "VERIFY CONTENT" << std::endl; - } else if (contentObject.getContentType() == PayloadType::MANIFEST) { + } else if (contentObject.getPayloadType() == PayloadType::MANIFEST) { std::cout << "VERIFY MANIFEST" << std::endl; } @@ -82,48 +85,6 @@ class Verificator { } }; -void becomeDaemon() { - pid_t process_id = 0; - pid_t sid = 0; - - // Create child process - process_id = fork(); - - // Indication of fork() failure - if (process_id < 0) { - printf("fork failed!\n"); - // Return failure in exit status - exit(EXIT_FAILURE); - } - - // PARENT PROCESS. Need to kill it. - if (process_id > 0) { - printf("process_id of child process %d \n", process_id); - // return success in exit status - exit(EXIT_SUCCESS); - } - - //unmask the file mode - umask(0); - - //set new session - sid = setsid(); - if (sid < 0) { - // Return failure - exit(EXIT_FAILURE); - } - - // Change the current working directory to root. - chdir("/"); - - // Close stdin. stdout and stderr - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - - // Really start application -} - int main(int argc, char *argv[]) { double beta = DEFAULT_BETA; double dropFactor = DEFAULT_GAMMA; @@ -159,7 +120,7 @@ int main(int argc, char *argv[]) { } if (daemon) { - becomeDaemon(); + utils::Daemonizator::daemonize(); } ConsumerSocket c(Name(name.c_str()), TransportProtocolAlgorithms::RAAQM); @@ -184,8 +145,7 @@ int main(int argc, char *argv[]) { (ConsumerContentCallback) std::bind(&CallbackContainer::processPayload, &stubs, std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3)); + std::placeholders::_2)); c.setSocketOption(ConsumerCallbacksOptions::INTEREST_OUTPUT, (ConsumerInterestCallback) std::bind(&CallbackContainer::processLeavingInterest, @@ -203,6 +163,8 @@ int main(int argc, char *argv[]) { } // end namespace icnet +} // end namespace transport + int main(int argc, char *argv[]) { - return icnet::main(argc, argv); + return icnet::transport::main(argc, argv); } diff --git a/apps/consumers/icnet_iget.cc b/apps/consumers/icnet_iget.cc deleted file mode 100755 index db5ef173..00000000 --- a/apps/consumers/icnet_iget.cc +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2017 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 "icnet_socket_consumer.h" - -typedef std::chrono::time_point Time; -typedef std::chrono::milliseconds TimeDuration; - -Time t1 = std::chrono::system_clock::now(); - -#define DEFAULT_BETA 0.99 -#define DEFAULT_GAMMA 0.07 - -namespace icnet { - -class CallbackContainer { - public: - CallbackContainer() - : work_(new boost::asio::io_service::work(io_service_)), - handler_(std::async(std::launch::async, [this]() { io_service_.run(); })) { - seen_manifest_segments_ = 0; - seen_data_segments_ = 0; - byte_counter_ = 0; - } - - ~CallbackContainer() { - work_.reset(); - } - - void processPayload(ConsumerSocket &c, const uint8_t *buffer, size_t buffer_size) { - Name m_name; - c.getSocketOption(GeneralTransportOptions::NAME_PREFIX, m_name); - std::string filename = m_name.toString().substr(1 + m_name.toString().find_last_of("/")); - io_service_.dispatch([buffer, buffer_size, filename]() { - std::cout << "Saving to: " << filename << " " << buffer_size / 1024 << "kB" << std::endl; - Time t3 = std::chrono::system_clock::now();; - std::ofstream file(filename.c_str(), std::ofstream::binary); - file.write((char *) buffer, buffer_size); - file.close(); - Time t2 = std::chrono::system_clock::now();; - TimeDuration dt = std::chrono::duration_cast(t2 - t1); - TimeDuration dt3 = std::chrono::duration_cast(t3 - t1); - long msec = dt.count(); - long msec3 = dt3.count(); - std::cout << "Elapsed Time: " << msec / 1000.0 << " seconds -- " << buffer_size * 8 / msec / 1000.0 - << "[Mbps] -- " << buffer_size * 8 / msec3 / 1000.0 << "[Mbps]" << std::endl; - }); - } - - bool verifyData(ConsumerSocket &c, const ContentObject &content_object) { - if (content_object.getContentType() == PayloadType::DATA) { - std::cout << "VERIFY CONTENT" << std::endl; - } else if (content_object.getContentType() == PayloadType::MANIFEST) { - std::cout << "VERIFY MANIFEST" << std::endl; - } - - return true; - } - - void processLeavingInterest(ConsumerSocket &c, const Interest &interest) { - // std::cout << "OUTPUT: " << interest.getName() << std::endl; - } - - private: - int seen_manifest_segments_; - int seen_data_segments_; - int byte_counter_; - boost::asio::io_service io_service_; - std::shared_ptr work_; - std::future handler_; -}; - -/* - * The client signature verification is currently being reworked with the new API. - * The implementation is disabled for the moment. - */ - -class Verificator { - public: - Verificator() { - }; - - ~Verificator() { - // m_keyChain.deleteIdentity(Name(IDENTITY_NAME)); - } - - bool onPacket(ConsumerSocket &c, const ContentObject &contentObject) { - return true; - } -}; - -int main(int argc, char **argv) { - - std::string url = ""; - std::string locator = ""; - std::string path = ""; - std::string name = "ccnx:/locator/get/path"; - size_t found = 0; - size_t path_begin = 0; - - if (argv[optind] == 0) { - std::cerr << "Missing URL" << std::endl; - return 0; - } else { - url = argv[optind]; - std::cout << "Iget " << url << std::endl; - } - - found = url.find("//"); - path_begin = url.find('/', found + 2); - locator = url.substr(found + 2, path_begin - (found + 2)); - path = url.substr(path_begin, std::string::npos); - std::cout << "locator " << locator << std::endl; - std::cout << "path " << path << std::endl; - name = "ccnx:/" + locator + "/get" + path; - std::cout << "Iget ccnx name: " << name << std::endl; - - ConsumerSocket c(Name(name.c_str()), TransportProtocolAlgorithms::RAAQM); - CallbackContainer stubs; - Verificator verificator; - - c.setSocketOption(ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY, - (ConsumerContentObjectVerificationCallback) std::bind(&Verificator::onPacket, - &verificator, - std::placeholders::_1, - std::placeholders::_2)); - c.setSocketOption(ConsumerCallbacksOptions::CONTENT_RETRIEVED, - (ConsumerContentCallback) std::bind(&CallbackContainer::processPayload, - &stubs, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3)); - c.setSocketOption(ConsumerCallbacksOptions::INTEREST_OUTPUT, - (ConsumerInterestCallback) std::bind(&CallbackContainer::processLeavingInterest, - &stubs, - std::placeholders::_1, - std::placeholders::_2)); - c.consume(Name()); - c.stop(); - return 0; -} - -} // end namespace icnet - -int main(int argc, char **argv) { - return icnet::main(argc, argv); -} diff --git a/apps/general/icnet_general_test.cc b/apps/general/icnet_general_test.cc index 88b0203d..e60cb887 100755 --- a/apps/general/icnet_general_test.cc +++ b/apps/general/icnet_general_test.cc @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "icnet_socket.h" +#include "icnet_transport_socket.h" namespace icnet { diff --git a/apps/http/CMakeLists.txt b/apps/http/CMakeLists.txt new file mode 100644 index 00000000..931fe840 --- /dev/null +++ b/apps/http/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright (c) 2017 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. + +cmake_minimum_required(VERSION 3.2) + +set(HTTP_CLIENT_SOURCE_FILES icnet_http_dash_client.cc) +set(HTTP_SERVER_SOURCE_FILES icnet_http_echo_server.cc) +set(IGET_SOURCE_FILES icnet_iget.cc) + +add_executable(http-dash-client ${HTTP_CLIENT_SOURCE_FILES}) +add_executable(http-echo-server ${HTTP_SERVER_SOURCE_FILES}) +add_executable(iget ${IGET_SOURCE_FILES}) + + +target_link_libraries(http-dash-client icnet ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(http-echo-server icnet ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(iget icnet ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) + +install(TARGETS http-dash-client DESTINATION bin COMPONENT library) +install(TARGETS iget DESTINATION bin COMPONENT library) +install(TARGETS http-echo-server DESTINATION bin COMPONENT library) \ No newline at end of file diff --git a/apps/http/icnet_http_dash_client.cc b/apps/http/icnet_http_dash_client.cc new file mode 100644 index 00000000..f34b8503 --- /dev/null +++ b/apps/http/icnet_http_dash_client.cc @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2017 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 "icnet_http_client_connection.h" +#include "icnet_utils_daemonizator.h" + +namespace icnet { + +namespace http { + +void usage(int argc, char **argv) { + std::cout << "Usage:" << std::endl; + std::cout << argv[0] << " [-D] " << "[URL]" << std::endl; + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) { + + std::string name("http://webserver/sintel/18000"); + uint32_t n_segment = 300; + bool daemon = false; + + int opt; + while ((opt = getopt(argc, argv, "Dh")) != -1) { + switch (opt) { + case 'D': + daemon = true; + break; + case 'n': + n_segment = (uint32_t) atoi(optarg); + break; + case 'h': + default: + usage(argc, argv); + } + } + + if (argv[optind] == 0) { + std::cerr << "Using default name " << name << std::endl; + } else { + name = argv[optind]; + } + + if (daemon) { + utils::Daemonizator::daemonize(); + } + + HTTPClientConnection connection; + HTTPResponse response; + + std::stringstream ss; + for (uint32_t i = 1; i < n_segment; i++) { + ss << name; + ss << "/seg_" << i << ".m4s"; + auto str = ss.str(); + connection.get(str); + response = connection.response(); + std::cout << "SIZE: " << response.size() << std::endl; + std::cout << (char *) response.data() << std::endl; + ss.str(""); + } + + return EXIT_SUCCESS; +} + +} + +} + +int main(int argc, char **argv) { + return icnet::http::main(argc, argv); +} \ No newline at end of file diff --git a/apps/http/icnet_http_echo_server.cc b/apps/http/icnet_http_echo_server.cc new file mode 100644 index 00000000..17bdb693 --- /dev/null +++ b/apps/http/icnet_http_echo_server.cc @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017 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 "icnet_http_server_acceptor.h" + +namespace icnet { + +namespace http { + +void onPayload(std::shared_ptr &publisher, const uint8_t *buffer, std::size_t size) { + + char *string = (char *) buffer; + std::cout << "Received this content:" << std::endl; + std::cout << string << std::endl; + + std::stringstream response; + response << "HTTP/1.0 200 OK\r\n" << "Content-Length: " << size << "\r\n\r\n" << string; + std::string response_string = response.str(); + + std::thread t([publisher, response_string]() { + publisher->publishContent((uint8_t *) response_string.data(), response_string.size(), 0, true); + publisher->serveClients(); + }); + + t.detach(); +} + +int main(int argc, char **argv) { + HTTPServerAcceptor connection(std::string("http://webserver"), onPayload); + connection.listen(false); + + return EXIT_SUCCESS; +} + +} + +} + +int main(int argc, char **argv) { + return icnet::http::main(argc, argv); +} \ No newline at end of file diff --git a/apps/http/icnet_iget.cc b/apps/http/icnet_iget.cc new file mode 100644 index 00000000..d322cc35 --- /dev/null +++ b/apps/http/icnet_iget.cc @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017 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 "icnet_http_client_connection.h" + +typedef std::chrono::time_point Time; +typedef std::chrono::milliseconds TimeDuration; + +Time t1 = std::chrono::system_clock::now(); + +#define DEFAULT_BETA 0.99 +#define DEFAULT_GAMMA 0.07 + +namespace icnet { + +namespace http { + +void processResponse(std::string &name, HTTPResponse &&response) { + + std::string filename = name.substr(1 + name.find_last_of("/")); + std::cout << "Saving to: " << filename << " " << response.size() / 1024 << "kB" << std::endl; + Time t3 = std::chrono::system_clock::now();; + std::ofstream file(filename.c_str(), std::ofstream::binary); + file.write((char *) response.data(), response.size()); + file.close(); + Time t2 = std::chrono::system_clock::now();; + TimeDuration dt = std::chrono::duration_cast(t2 - t1); + TimeDuration dt3 = std::chrono::duration_cast(t3 - t1); + long msec = dt.count(); + long msec3 = dt3.count(); + std::cout << "Elapsed Time: " << msec / 1000.0 << " seconds -- " << response.size() * 8 / msec / 1000.0 + << "[Mbps] -- " << response.size() * 8 / msec3 / 1000.0 << "[Mbps]" << std::endl; + +} + +int main(int argc, char **argv) { + + std::string name("http://webserver/sintel/mpd"); + + if (argv[optind] == 0) { + std::cerr << "Using default name http://webserver/sintel/mpd" << std::endl; + } else { + name = argv[optind]; + } + + HTTPClientConnection connection; + connection.get(name); + processResponse(name, connection.response()); + + return EXIT_SUCCESS; +} + +} // end namespace http + +} // end namespace hicnet + +int main(int argc, char **argv) { + return icnet::http::main(argc, argv); +} \ No newline at end of file diff --git a/apps/iping/iPing_Client.c b/apps/iping/iPing_Client.c index 85d92eb0..ea6b0711 100644 --- a/apps/iping/iPing_Client.c +++ b/apps/iping/iPing_Client.c @@ -315,12 +315,11 @@ static bool _ccnxPingClient_ParseCommandline(CCNxPingClient *client, int argc, c static struct option longopts[] = {{"ping", no_argument, NULL, 'p'}, {"flood", no_argument, NULL, 'f'}, {"count", required_argument, NULL, 'c'}, { "size", required_argument, NULL, 's' - }, {"interval", required_argument, NULL, 'i'}, {"locator", required_argument, NULL, 'l'}, {"outstanding" - , required_argument - , NULL, 'o' - }, {"help", no_argument, NULL, 'h'}, {"timeout", required_argument, NULL, 't'}, {"lifetime", required_argument - , NULL, 'e' - }, {NULL, 0, NULL, 0}}; + }, {"interval", required_argument, NULL, 'i'}, {"locator", required_argument, NULL, 'l'}, + {"outstanding", required_argument, NULL, 'o' + }, {"help", no_argument, NULL, 'h'}, {"timeout", required_argument, NULL, 't'}, + {"lifetime", required_argument, NULL, 'e' + }, {NULL, 0, NULL, 0}}; client->payloadSize = ccnxPing_DefaultPayloadSize; diff --git a/apps/iping/iPing_Server.c b/apps/iping/iPing_Server.c index d3e5211c..eb9543a3 100644 --- a/apps/iping/iPing_Server.c +++ b/apps/iping/iPing_Server.c @@ -167,9 +167,9 @@ static void _displayUsage(char *progName) { */ static bool _ccnxPingServer_ParseCommandline(CCNxPingServer *server, int argc, char *argv[argc]) { static struct option longopts[] = - {{"locator", required_argument, NULL, 'l'}, {"size", required_argument, NULL, 's'}, {"help", no_argument, NULL - , 'h' - }, {NULL, 0, NULL, 0}}; + {{"locator", required_argument, NULL, 'l'}, {"size", required_argument, NULL, 's'}, + {"help", no_argument, NULL, 'h' + }, {NULL, 0, NULL, 0}}; // Default value server->payloadSize = ccnxPing_MaxPayloadSize; diff --git a/apps/producers/icnet_producer_test.cc b/apps/producers/icnet_producer_test.cc index c122090a..f35d082a 100755 --- a/apps/producers/icnet_producer_test.cc +++ b/apps/producers/icnet_producer_test.cc @@ -13,19 +13,22 @@ * limitations under the License. */ -#include "icnet_socket_producer.h" +#include "icnet_transport_socket_producer.h" +#include "icnet_utils_daemonizator.h" #define IDENTITY_NAME "cisco" namespace icnet { +namespace transport { + class CallbackContainer { public: CallbackContainer(unsigned long download_size = 0) : buffer_(1400, 'X'), final_chunk_number_(0) { content_object_.setContent((uint8_t *) buffer_.c_str(), 1400); if (download_size > 0) { - final_chunk_number_ = static_cast(std::ceil(download_size / 1400.0)); + final_chunk_number_ = static_cast (std::ceil(download_size / 1400.0)); } } @@ -66,48 +69,6 @@ class Signer { Name identity_name_; }; -void becomeDaemon() { - pid_t process_id = 0; - pid_t sid = 0; - - // Create child process - process_id = fork(); - - // Indication of fork() failure - if (process_id < 0) { - printf("fork failed!\n"); - // Return failure in exit status - exit(EXIT_FAILURE); - } - - // PARENT PROCESS. Need to kill it. - if (process_id > 0) { - printf("process_id of child process %d \n", process_id); - // return success in exit status - exit(EXIT_SUCCESS); - } - - //unmask the file mode - umask(0); - - //set new session - sid = setsid(); - if (sid < 0) { - // Return failure - exit(EXIT_FAILURE); - } - - // Change the current working directory to root. - chdir("/"); - - // Close stdin. stdout and stderr - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - - // Really start application -} - int main(int argc, char **argv) { std::string name = "ccnx:/ccnxtest"; unsigned long download_size = 0; @@ -135,7 +96,7 @@ int main(int argc, char **argv) { } if (daemon) { - becomeDaemon(); + utils::Daemonizator::daemonize(); } CallbackContainer stubs(download_size); @@ -168,9 +129,11 @@ int main(int argc, char **argv) { return 0; } +} // end namespace transport + } // end namespace icnet int main(int argc, char **argv) { - return icnet::main(argc, argv); + return icnet::transport::main(argc, argv); } diff --git a/dockerfile.ubuntu.xenial b/dockerfile.ubuntu.xenial new file mode 100644 index 00000000..182d19da --- /dev/null +++ b/dockerfile.ubuntu.xenial @@ -0,0 +1,19 @@ +# +# Ubuntu Dockerfile +# +# https://github.com/dockerfile/ubuntu +# + +# Pull base image. +FROM ubuntu:xenial + +# Install. +RUN \ + sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \ + apt-get update && \ + apt-get -y upgrade && \ + apt-get install -y build-essential cmake software-properties-common apt-transport-https && \ + echo "deb [trusted=yes] http://nexus.fd.io/content/repositories/fd.io.master.ubuntu.xenial.main ./" | tee /etc/apt/sources.list.d/99fd.io.master.list && \ + apt-get update && \ + apt-get install -y libevent-dev libssl-dev longbow libparc libccnx-common libccnx-transport-rta libccnx-portal libboost-system-dev && \ + rm -rf /var/lib/apt/lists/* diff --git a/icnet/CMakeLists.txt b/icnet/CMakeLists.txt index fae22d61..427a3d9f 100644 --- a/icnet/CMakeLists.txt +++ b/icnet/CMakeLists.txt @@ -13,65 +13,149 @@ cmake_minimum_required(VERSION 3.2) -file(GLOB HEADER_FILES "ccnx/*.h") -file(GLOB SOURCE_FILES "ccnx/*.cc") +set(CCNX_HEADER_FILES + ccnx/icnet_ccnx_common.h + ccnx/icnet_ccnx_content_object.h + ccnx/icnet_ccnx_facade.h + ccnx/icnet_ccnx_interest.h + ccnx/icnet_ccnx_key_locator.h + ccnx/icnet_ccnx_key_locator_type.h + ccnx/icnet_ccnx_local_connector.h + ccnx/icnet_ccnx_manifest.h + ccnx/icnet_ccnx_name.h + ccnx/icnet_ccnx_network_message.h + ccnx/icnet_ccnx_payload_type.h + ccnx/icnet_ccnx_pending_interest.h + ccnx/icnet_ccnx_portal.h + ccnx/icnet_ccnx_segment.h) -set(ICNET_HEADER_FILES +set(CCNX_SOURCE_FILES + ccnx/icnet_ccnx_segment.cc + ccnx/icnet_ccnx_portal.cc + ccnx/icnet_ccnx_pending_interest.cc + ccnx/icnet_ccnx_network_message.cc + ccnx/icnet_ccnx_name.cc + ccnx/icnet_ccnx_manifest.cc + ccnx/icnet_ccnx_local_connector.cc + ccnx/icnet_ccnx_key_locator.cc + ccnx/icnet_ccnx_interest.cc + ccnx/icnet_ccnx_content_object.cc) + +set(TRANSPORT_HEADER_FILES ${CMAKE_BINARY_DIR}/config.hpp - transport/icnet_rate_estimation.h - transport/icnet_download_observer.h - transport/icnet_socket_consumer.h - transport/icnet_socket.h - transport/icnet_socket_options_default_values.h - transport/icnet_socket_options_keys.h - transport/icnet_common.h - transport/icnet_socket_producer.h - transport/icnet_content_store.h + transport/icnet_transport_rate_estimation.h + transport/icnet_transport_download_observer.h + transport/icnet_transport_socket_consumer.h + transport/icnet_transport_socket.h + transport/icnet_transport_socket_options_default_values.h + transport/icnet_transport_socket_options_keys.h + transport/icnet_transport_common.h + transport/icnet_transport_socket_producer.h + transport/icnet_transport_content_store.h transport/icnet_transport_vegas.h - transport/icnet_transport.h + transport/icnet_transport_protocol.h transport/icnet_transport_raaqm.h transport/icnet_transport_vegas_rto_estimator.h transport/icnet_transport_raaqm_data_path.h) -set(ICNET_SOURCE_FILES - transport/icnet_socket_producer.cc - transport/icnet_socket_consumer.cc +set(TRANSPORT_SOURCE_FILES + transport/icnet_transport_socket_producer.cc + transport/icnet_transport_socket_consumer.cc transport/icnet_transport_vegas.cc - transport/icnet_transport.cc - transport/icnet_content_store.cc + transport/icnet_transport_protocol.cc + transport/icnet_transport_content_store.cc transport/icnet_transport_raaqm.cc transport/icnet_transport_vegas_rto_estimator.cc - transport/icnet_rate_estimation.cc + transport/icnet_transport_rate_estimation.cc transport/icnet_transport_raaqm_data_path.cc) +set(ERRORS_HEADER_FILES + errors/icnet_errors_tokenizer_exception.h + errors/icnet_errors.h + errors/icnet_errors_malformed_name_exception.h + errors/icnet_errors_not_implemented_exception.h + errors/icnet_errors_runtime_exception.h + errors/icnet_errors_malformed_packet_exception.h) + +set(ERRORS_SOURCE_FILES + errors/icnet_errors_tokenizer_exception.cc + errors/icnet_errors_malformed_name_exception.cc + errors/icnet_errors_not_implemented_exception.cc + errors/icnet_errors_runtime_exception.cc + errors/icnet_errors_malformed_packet_exception.cc) + +set(HTTP_HEADER_FILES + http/icnet_http_default_values.h + http/icnet_http_client_connection.h + http/icnet_http_server_acceptor.h + http/icnet_http_server_publisher.h + http/icnet_http_request.h + http/icnet_http_facade.h) + +set(HTTP_SOURCE_FILES + http/icnet_http_client_connection.cc + http/icnet_http_server_acceptor.cc + http/icnet_http_server_publisher.cc + http/icnet_http_request.cc) + +set(UTILS_HEADER_FILES + utils/icnet_utils_array.h + utils/icnet_utils_uri.h + utils/icnet_utils_daemonizator.h + utils/icnet_utils_hash.h + utils/icnet_utils_string_tokenizer.h) + +set(UTILS_SOURCE_FILES + utils/icnet_utils_array.cc + utils/icnet_utils_uri.cc + utils/icnet_utils_daemonizator.cc + utils/icnet_utils_hash.cc + utils/icnet_utils_string_tokenizer.cc) + set(ICNET_CONFIG transport/consumer.conf) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") -add_library(icnet STATIC ${SOURCE_FILES} ${ICNET_SOURCE_FILES} ${HEADER_FILES} ${ICNET_HEADER_FILES}) -add_library(icnet.shared SHARED ${SOURCE_FILES} ${ICNET_SOURCE_FILES}) -if(ANDROID_API) - target_link_libraries(icnet.shared ${LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${CCNX_COMMON_LIBRARIES} ${CCNX_TRANSPORT_RTA_LIBRARIES} ${CCNX_PORTAL_LIBRARIES} ${LIBPARC_LIBRARIES} ${LONGBOW_LIBRARIES}) - target_link_libraries(icnet ${LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${CCNX_COMMON_LIBRARIES} ${CCNX_TRANSPORT_RTA_LIBRARIES} ${CCNX_PORTAL_LIBRARIES} ${LIBPARC_LIBRARIES} ${LONGBOW_LIBRARIES}) -else () - target_link_libraries(icnet.shared ${LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +add_library(icnet STATIC + ${CCNX_SOURCE_FILES} + ${TRANSPORT_SOURCE_FILES} + ${ERRORS_SOURCE_FILES} + ${HTTP_SOURCE_FILES} + ${UTILS_SOURCE_FILES}) + +if (COMPILE_FOR_IOS OR ANDROID_API) target_link_libraries(icnet ${LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -endif (ANDROID_API) + set(libicnet_libraries + icnet) +else() -set_target_properties(icnet.shared PROPERTIES - SOVERSION 1 - VERSION 1.0 - OUTPUT_NAME icnet) + add_library(icnet.shared SHARED + ${CCNX_SOURCE_FILES} + ${TRANSPORT_SOURCE_FILES} + ${ERRORS_SOURCE_FILES} + ${HTTP_SOURCE_FILES} + ${UTILS_SOURCE_FILES}) + + target_link_libraries(icnet.shared ${LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) + target_link_libraries(icnet ${LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) + set_target_properties(icnet.shared PROPERTIES + SOVERSION 1 + VERSION 1.0 + OUTPUT_NAME icnet) -set(libicnet_libraries - icnet - icnet.shared) + set(libicnet_libraries + icnet + icnet.shared) +endif() foreach(lib ${libicnet_libraries}) install(TARGETS ${lib} COMPONENT library LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) endforeach() -install(FILES ${HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/icnet COMPONENT headers) -install(FILES ${ICNET_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/icnet COMPONENT headers) +install(FILES ${CCNX_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/icnet COMPONENT headers) +install(FILES ${TRANSPORT_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/icnet COMPONENT headers) +install(FILES ${HTTP_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/icnet COMPONENT headers) +install(FILES ${ERRORS_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/icnet COMPONENT headers) +install(FILES ${UTILS_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/icnet COMPONENT headers) install(FILES ${ICNET_CONFIG} DESTINATION ${CMAKE_INSTALL_PREFIX}/etc/ COMPONENT library) diff --git a/icnet/ccnx/icnet_ccnx_content_object.cc b/icnet/ccnx/icnet_ccnx_content_object.cc index 03875724..e4070194 100644 --- a/icnet/ccnx/icnet_ccnx_content_object.cc +++ b/icnet/ccnx/icnet_ccnx_content_object.cc @@ -63,11 +63,11 @@ bool ContentObject::operator==(const ContentObject &content_object) { return ccnxContentObject_Equals(ccnx_content_object_, content_object.ccnx_content_object_); } -PayloadType ContentObject::getContentType() const { +PayloadType ContentObject::getPayloadType() const { return (PayloadType) ccnxContentObject_GetPayloadType(ccnx_content_object_); } -void ContentObject::setContentType(PayloadType payload_type) { +void ContentObject::setPayloadType(PayloadType payload_type) { content_type_ = payload_type; } diff --git a/icnet/ccnx/icnet_ccnx_content_object.h b/icnet/ccnx/icnet_ccnx_content_object.h index 148587bb..e7e641e6 100644 --- a/icnet/ccnx/icnet_ccnx_content_object.h +++ b/icnet/ccnx/icnet_ccnx_content_object.h @@ -71,13 +71,13 @@ class ContentObject : public std::enable_shared_from_this { bool operator==(const ContentObject &content_object); - PayloadType getContentType() const; + PayloadType getPayloadType() const; bool setContent(PayloadType content_type, const uint8_t *buffer, size_t buffer_size); bool setContent(const uint8_t *buffer, size_t buffer_size); - void setContentType(PayloadType payload_type); + void setPayloadType(PayloadType payload_type); Array getContent() const; diff --git a/icnet/ccnx/icnet_ccnx_interest.cc b/icnet/ccnx/icnet_ccnx_interest.cc index 6b0f92cb..d578d550 100644 --- a/icnet/ccnx/icnet_ccnx_interest.cc +++ b/icnet/ccnx/icnet_ccnx_interest.cc @@ -117,6 +117,13 @@ bool Interest::setPayload(const PARCBuffer *payload) { return ccnxInterest_SetPayload(interest_, payload); } +bool Interest::setPayload(const uint8_t *buffer, std::size_t size) { + PARCBuffer *pbuffer = parcBuffer_CreateFromArray(buffer, size); + bool ret = setPayload(pbuffer); + parcBuffer_Release(&pbuffer); + return ret; +} + bool Interest::setPayloadAndId(const PARCBuffer *payload) { return ccnxInterest_SetPayloadAndId(interest_, payload); } @@ -125,8 +132,9 @@ bool Interest::setPayloadWithId(const PARCBuffer *payload, const CCNxInterestPay return ccnxInterest_SetPayloadWithId(interest_, payload, payload_id); } -PARCBuffer *Interest::getPayload() { - return ccnxInterest_GetPayload(interest_); +utils::Array Interest::getPayload() const { + PARCBuffer *buffer = ccnxInterest_GetPayload(interest_); + return utils::Array(parcBuffer_Overlay(buffer, 0), parcBuffer_Remaining(buffer)); } void Interest::setHopLimit(uint32_t hop_limit) { diff --git a/icnet/ccnx/icnet_ccnx_interest.h b/icnet/ccnx/icnet_ccnx_interest.h index 2156b56f..47af3f68 100644 --- a/icnet/ccnx/icnet_ccnx_interest.h +++ b/icnet/ccnx/icnet_ccnx_interest.h @@ -17,14 +17,13 @@ #define ICNET_CCNX_INTEREST_H_ #include "icnet_ccnx_common.h" +#include "icnet_utils_array.h" +#include "icnet_ccnx_name.h" extern "C" { #include }; -//#include "interest.hpp" -#include "icnet_ccnx_name.h" - namespace icnet { namespace ccnx { @@ -67,11 +66,13 @@ class Interest : public std::enable_shared_from_this { bool setPayload(const PARCBuffer *payload); + bool setPayload(const uint8_t *buffer, std::size_t size); + bool setPayloadAndId(const PARCBuffer *payload); bool setPayloadWithId(const PARCBuffer *payload, const CCNxInterestPayloadId *payload_id); - PARCBuffer *getPayload(); + utils::Array getPayload() const; void setHopLimit(uint32_t hop_limit); diff --git a/icnet/ccnx/icnet_ccnx_local_connector.cc b/icnet/ccnx/icnet_ccnx_local_connector.cc index cd828b08..75691979 100644 --- a/icnet/ccnx/icnet_ccnx_local_connector.cc +++ b/icnet/ccnx/icnet_ccnx_local_connector.cc @@ -136,7 +136,7 @@ void LocalConnector::doReadHeader() { void LocalConnector::tryReconnect() { if (!is_connecting_) { #ifdef __ANDROID__ - __android_log_print(ANDROID_LOG_DEBUG, "libICNet", "Connection lost. Trying to reconnect...\n"); + __android_log_print(ANDROID_LOG_DEBUG, "libICNet", "Connection lost. Trying to reconnect...\n"); #else std::cerr << "Connection lost. Trying to reconnect..." << std::endl; #endif diff --git a/icnet/errors/icnet_errors.h b/icnet/errors/icnet_errors.h new file mode 100644 index 00000000..34ba11af --- /dev/null +++ b/icnet/errors/icnet_errors.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2017 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 "icnet_errors_malformed_name_exception.h" +#include "icnet_errors_not_implemented_exception.h" +#include "icnet_errors_malformed_packet_exception.h" +#include "icnet_errors_runtime_exception.h" diff --git a/icnet/errors/icnet_errors_malformed_name_exception.cc b/icnet/errors/icnet_errors_malformed_name_exception.cc new file mode 100644 index 00000000..361c211a --- /dev/null +++ b/icnet/errors/icnet_errors_malformed_name_exception.cc @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 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 "icnet_errors.h" + +namespace icnet { + +namespace errors { + +MalformedNameException::MalformedNameException() + : std::runtime_error("") { +} + +char const *MalformedNameException::what() const noexcept { + return "Malformed IP address."; +} + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_malformed_name_exception.h b/icnet/errors/icnet_errors_malformed_name_exception.h new file mode 100644 index 00000000..f714d2b0 --- /dev/null +++ b/icnet/errors/icnet_errors_malformed_name_exception.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 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 + +namespace icnet { + +namespace errors { + +class MalformedNameException : public std::runtime_error { + public: + MalformedNameException(); + virtual char const *what() const noexcept override; +}; + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_malformed_packet_exception.cc b/icnet/errors/icnet_errors_malformed_packet_exception.cc new file mode 100644 index 00000000..962a6582 --- /dev/null +++ b/icnet/errors/icnet_errors_malformed_packet_exception.cc @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 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 "icnet_errors_malformed_packet_exception.h" + +namespace icnet { + +namespace errors { + +MalformedPacketException::MalformedPacketException() + : std::runtime_error("") { +} + +char const *MalformedPacketException::what() const noexcept { + return "Malformed IP packet."; +} + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_malformed_packet_exception.h b/icnet/errors/icnet_errors_malformed_packet_exception.h new file mode 100644 index 00000000..0420d5c1 --- /dev/null +++ b/icnet/errors/icnet_errors_malformed_packet_exception.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 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 + +namespace icnet { + +namespace errors { + +class MalformedPacketException : public std::runtime_error { + public: + MalformedPacketException(); + virtual char const *what() const noexcept override; +}; + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_not_implemented_exception.cc b/icnet/errors/icnet_errors_not_implemented_exception.cc new file mode 100644 index 00000000..c58039c9 --- /dev/null +++ b/icnet/errors/icnet_errors_not_implemented_exception.cc @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017 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 "icnet_errors_not_implemented_exception.h" + +namespace icnet { + +namespace errors { + +NotImplementedException::NotImplementedException() + : std::logic_error("") { + +} + +char const *NotImplementedException::what() const noexcept { + return "Function not yet implemented."; +} + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_not_implemented_exception.h b/icnet/errors/icnet_errors_not_implemented_exception.h new file mode 100644 index 00000000..980ae99f --- /dev/null +++ b/icnet/errors/icnet_errors_not_implemented_exception.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 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 + +namespace icnet { + +namespace errors { + +class NotImplementedException : public std::logic_error { + public: + NotImplementedException(); + virtual char const *what() const noexcept override; +}; + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_runtime_exception.cc b/icnet/errors/icnet_errors_runtime_exception.cc new file mode 100644 index 00000000..4853f25c --- /dev/null +++ b/icnet/errors/icnet_errors_runtime_exception.cc @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 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 "icnet_errors_runtime_exception.h" + +namespace icnet { + +namespace errors { + +RuntimeException::RuntimeException() + : std::runtime_error("") { +} + +//char const *Runtime::what() const { +// return "Function not yet implemented."; +//} + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_runtime_exception.h b/icnet/errors/icnet_errors_runtime_exception.h new file mode 100644 index 00000000..37c6bcb6 --- /dev/null +++ b/icnet/errors/icnet_errors_runtime_exception.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017 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 +#include + +namespace icnet { + +namespace errors { + +class RuntimeException : public std::runtime_error { + public: + RuntimeException(); + RuntimeException(std::string what) + : runtime_error(what) {}; +}; + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_tokenizer_exception.cc b/icnet/errors/icnet_errors_tokenizer_exception.cc new file mode 100644 index 00000000..1b5e8438 --- /dev/null +++ b/icnet/errors/icnet_errors_tokenizer_exception.cc @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017 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 "icnet_errors_tokenizer_exception.h" + +namespace icnet { + +namespace errors { + +TokenizerException::TokenizerException() + : std::logic_error("") { + +} + +char const *TokenizerException::what() const noexcept { + return "No more tokens available."; +} + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/errors/icnet_errors_tokenizer_exception.h b/icnet/errors/icnet_errors_tokenizer_exception.h new file mode 100644 index 00000000..bae9d82a --- /dev/null +++ b/icnet/errors/icnet_errors_tokenizer_exception.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 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 + +namespace icnet { + +namespace errors { + +class TokenizerException : public std::logic_error { + public: + TokenizerException(); + virtual char const *what() const noexcept override; +}; + +} // end namespace errors + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/http/icnet_http_client_connection.cc b/icnet/http/icnet_http_client_connection.cc new file mode 100644 index 00000000..1f0d8fd8 --- /dev/null +++ b/icnet/http/icnet_http_client_connection.cc @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2017 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 "icnet_http_client_connection.h" + +#define DEFAULT_BETA 0.99 +#define DEFAULT_GAMMA 0.07 + +namespace icnet { + +namespace http { + +using namespace transport; + +HTTPClientConnection::HTTPClientConnection() + : consumer_(Name("ccnx:"), transport::TransportProtocolAlgorithms::RAAQM) { + + consumer_.setSocketOption(GeneralTransportOptions::INTEREST_LIFETIME, 1001); + consumer_.setSocketOption(RaaqmTransportOptions::BETA_VALUE, DEFAULT_BETA); + consumer_.setSocketOption(RaaqmTransportOptions::DROP_FACTOR, DEFAULT_GAMMA); + consumer_.setSocketOption(GeneralTransportOptions::MAX_INTEREST_RETX, 200); + + consumer_.setSocketOption(ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY, + (ConsumerContentObjectVerificationCallback) std::bind(&HTTPClientConnection::verifyData, + this, + std::placeholders::_1, + std::placeholders::_2)); + + consumer_.setSocketOption(ConsumerCallbacksOptions::CONTENT_RETRIEVED, + (ConsumerContentCallback) std::bind(&HTTPClientConnection::processPayload, + this, + std::placeholders::_1, + std::placeholders::_2)); +} + +HTTPClientConnection &HTTPClientConnection::get(std::string &url, HTTPHeaders headers, HTTPPayload payload) { + + HTTPRequest request(GET, url, headers, payload); + + std::string &request_string = request.getRequestString(); + std::string &locator = request.getLocator(); + std::string &path = request.getPath(); + + consumer_.setSocketOption(ConsumerCallbacksOptions::INTEREST_OUTPUT, + (ConsumerInterestCallback) std::bind(&HTTPClientConnection::processLeavingInterest, + this, + std::placeholders::_1, + std::placeholders::_2, + request_string)); + + // Send content to producer piggybacking it through first interest (to fix) + + response_.clear(); + + // Factor icn name + + std::stringstream stream; + + stream << "ccnx:/"; + stream << locator << "/get"; + stream << path; + + consumer_.consume(Name(stream.str())); + + consumer_.stop(); + + return *this; +} + +HTTPResponse &&HTTPClientConnection::response() { + return std::move(response_); +} + +void HTTPClientConnection::processPayload(transport::ConsumerSocket &c, + std::vector &&payload) { + response_ = std::move(payload); +} + +bool HTTPClientConnection::verifyData(transport::ConsumerSocket &c, const ContentObject &contentObject) { + if (contentObject.getPayloadType() == PayloadType::DATA) { + std::cout << "VERIFY CONTENT" << std::endl; + } else if (contentObject.getPayloadType() == PayloadType::MANIFEST) { + std::cout << "VERIFY MANIFEST" << std::endl; + } + + return true; +} + +void HTTPClientConnection::processLeavingInterest(transport::ConsumerSocket &c, + const Interest &interest, + std::string &payload) { + if (interest.getName().get(-1).toSegment() == 0) { + Interest &int2 = const_cast(interest); + int2.setPayload((const uint8_t *) payload.data(), payload.size()); + } +} + +HTTPClientConnection& HTTPClientConnection::stop() { + // This is thread safe and can be called from another thread + consumer_.stop(); + + return *this; +} + +} + +} \ No newline at end of file diff --git a/icnet/http/icnet_http_client_connection.h b/icnet/http/icnet_http_client_connection.h new file mode 100644 index 00000000..5a009d88 --- /dev/null +++ b/icnet/http/icnet_http_client_connection.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 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 "icnet_transport_socket_consumer.h" +#include "icnet_transport_socket_producer.h" +#include "icnet_utils_uri.h" +#include "icnet_http_request.h" +#include "icnet_http_default_values.h" + +#include + +#define HTTP_VERSION "1.0" + +namespace icnet { + +namespace http { + +class HTTPClientConnection { + public: + HTTPClientConnection(); + + HTTPClientConnection &get(std::string &url, HTTPHeaders headers = {}, HTTPPayload payload = {}); + + HTTPResponse &&response(); + + HTTPClientConnection &stop(); + + private: + + void processPayload(transport::ConsumerSocket &c, std::vector &&payload); + + bool verifyData(transport::ConsumerSocket &c, const transport::ContentObject &contentObject); + + void processLeavingInterest(transport::ConsumerSocket &c, const transport::Interest &interest, std::string &payload); + + HTTPResponse response_; + transport::ConsumerSocket consumer_; +}; + +} // end namespace http + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/http/icnet_http_default_values.h b/icnet/http/icnet_http_default_values.h new file mode 100644 index 00000000..5aaf60d8 --- /dev/null +++ b/icnet/http/icnet_http_default_values.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 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 + +namespace hicnet { + +namespace http { + +namespace default_values { + +const uint16_t ipv6_first_word = 0xb001; // Network byte order + +} // end namespace transport + +} // end namespace default_values + +} // end namespace hicnet diff --git a/icnet/http/icnet_http_facade.h b/icnet/http/icnet_http_facade.h new file mode 100644 index 00000000..f32eff73 --- /dev/null +++ b/icnet/http/icnet_http_facade.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017 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 "icnet_http_server_acceptor.h" +#include "icnet_http_server_publisher.h" +#include "icnet_http_client_connection.h" + +namespace libl4 = icnet; \ No newline at end of file diff --git a/icnet/http/icnet_http_request.cc b/icnet/http/icnet_http_request.cc new file mode 100644 index 00000000..cd0c512f --- /dev/null +++ b/icnet/http/icnet_http_request.cc @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017 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 "icnet_http_request.h" +#include "icnet_utils_uri.h" + +namespace icnet { + +namespace http { + +static std::map method_map = { + {GET, "GET"}, + {POST, "POST"}, + {PUT, "PUT"}, + {PATCH, "PATCH"}, + {DELETE, "DELETE"}, +}; + +//std::map method_map + +HTTPRequest::HTTPRequest(HTTPMethod method, std::string &url, HTTPHeaders &headers, HTTPPayload &payload) { + utils::Uri uri; + uri.parse(url); + + path_ = uri.getPath(); + query_string_ = uri.getQueryString(); + protocol_ = uri.getProtocol(); + locator_ = uri.getLocator(); + port_ = uri.getPort(); + + headers_ = headers; + payload_ = payload; + + std::transform(locator_.begin(), + locator_.end(), + locator_.begin(), + ::tolower); + + std::transform(protocol_.begin(), + protocol_.end(), + protocol_.begin(), + ::tolower); + + std::stringstream stream; + stream << method_map[method] << " " << uri.getPath() << " HTTP/" << HTTP_VERSION << "\r\n"; + for (auto &item : headers) { + stream << item.first << ": " << item.second << "\r\n"; + } + stream << "\r\n"; + stream << payload.data(); + + request_string_ = stream.str(); +} + +std::string &HTTPRequest::getPort() { + return port_; +} + +std::string &HTTPRequest::getLocator() { + return locator_; +} + +std::string &HTTPRequest::getProtocol() { + return protocol_; +} + +std::string &HTTPRequest::getPath() { + return path_; +} + +std::string &HTTPRequest::getQueryString() { + return query_string_; +} + +HTTPHeaders &HTTPRequest::getHeaders() { + return headers_; +} + +HTTPPayload &HTTPRequest::getPayload() { + return payload_; +} + +std::string &HTTPRequest::getRequestString() { + return request_string_; +} + +} + +} \ No newline at end of file diff --git a/icnet/http/icnet_http_request.h b/icnet/http/icnet_http_request.h new file mode 100644 index 00000000..985d7628 --- /dev/null +++ b/icnet/http/icnet_http_request.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017 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 +#include +#include + +#define HTTP_VERSION "1.0" + +namespace icnet { + +namespace http { + +typedef enum { + GET, + POST, + PUT, + PATCH, + DELETE +} HTTPMethod; + +typedef std::map HTTPHeaders; +typedef std::vector HTTPPayload; +typedef std::vector HTTPResponse; + +class HTTPRequest { + public: + + HTTPRequest(HTTPMethod method, + std::string &url, HTTPHeaders &headers, HTTPPayload &payload); + + std::string &getQueryString(); + + std::string &getPath(); + + std::string &getProtocol(); + + std::string &getLocator(); + + std::string &getPort(); + + std::string &getRequestString(); + + HTTPHeaders &getHeaders(); + + HTTPPayload &getPayload(); + + private: + std::string query_string_, path_, protocol_, locator_, port_; + std::string request_string_; + HTTPHeaders headers_; + HTTPPayload payload_; +}; + +} // end namespace http + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/http/icnet_http_server_acceptor.cc b/icnet/http/icnet_http_server_acceptor.cc new file mode 100644 index 00000000..9406955d --- /dev/null +++ b/icnet/http/icnet_http_server_acceptor.cc @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2017 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 "icnet_http_server_acceptor.h" +#include "icnet_http_request.h" +#include "icnet_errors.h" +#include "icnet_utils_uri.h" +#include "icnet_utils_hash.h" + +namespace icnet { + +namespace http { + +HTTPServerAcceptor::HTTPServerAcceptor(std::string &&server_locator, OnHttpRequest callback) + : HTTPServerAcceptor(server_locator, callback) { +} + +HTTPServerAcceptor::HTTPServerAcceptor(std::string &server_locator, OnHttpRequest callback) + : callback_(callback) { + utils::Uri uri; + + uri.parseProtocolAndLocator(server_locator); + std::string protocol = uri.getProtocol(); + std::string locator = uri.getLocator(); + + std::transform(locator.begin(), + locator.end(), + locator.begin(), + ::tolower); + + std::transform(protocol.begin(), + protocol.end(), + protocol.begin(), + ::tolower); + + if (protocol != "http") { + throw errors::RuntimeException("Malformed server_locator. The locator format should be in the form http://locator"); + } + + std::stringstream ss; + + ss << "ccnx:/"; + ss << locator; + + acceptor_producer_ = std::make_shared(ss.str()); +} + +void HTTPServerAcceptor::listen(bool async) { + acceptor_producer_->setSocketOption(icnet::transport::ProducerCallbacksOptions::INTEREST_INPUT, + (icnet::transport::ProducerInterestCallback) bind(&HTTPServerAcceptor::processIncomingInterest, + this, + std::placeholders::_1, + std::placeholders::_2)); + acceptor_producer_->dispatch(); + + if (!async) { + acceptor_producer_->serveForever(); + } +} + +HttpRequest &&HTTPServerAcceptor::request() { + return std::move(request_); +} + +void HTTPServerAcceptor::processIncomingInterest(transport::ProducerSocket &p, const transport::Interest &interest) { + // Temporary solution + + transport::Name complete_name = interest.getName(); + + transport::Name request_name = complete_name.get(-1).isSegment() ? complete_name.getPrefix(-1) : complete_name; + transport::Name prefix; + acceptor_producer_->getSocketOption(transport::GeneralTransportOptions::NAME_PREFIX, prefix); + + // Get the name of the HTTP method to compute + std::string method = request_name.get(prefix.getSegmentCount()).toString(); + std::transform(method.begin(), method.end(), method.begin(), ::toupper); + std::string path; + std::string url_begin; + + // This is done for getting rid of useless name components such as ccnx: or ndn: + if (request_name.getSegmentCount() > 2) { + std::string raw_path = request_name.getSubName(prefix.getSegmentCount() + 1).toString(); + std::size_t pos = raw_path.find("/"); + path = raw_path.substr(pos); + url_begin = prefix.getSubName(0).toString().substr(pos); + } + + std::stringstream ss; + ss << "http:/" << url_begin << path; + + std::string url = ss.str(); + HTTPHeaders headers = {}; + HTTPPayload payload = {}; + + if (method == "GET") { + HTTPRequest request(GET, url, headers, payload); + auto publisher = std::make_shared(request_name); + callback_(publisher, (uint8_t *) request.getRequestString().data(), request.getRequestString().size()); + } +} + +//void HTTPServerConnection::sendResponse() { +// +// std::thread t([]() { +// +// // Get the name of the HTTP method to compute +// std::string method = request_name.get(1).toString(); +// std::transform(method.begin(), method.end(), method.begin(), ::toupper); +// std::string path; +// +// // This is done for getting rid of useless name components such as ccnx: or ndn: +// if (request_name.getSegmentCount() > 2) { +// std::string rawPath = request_name.getSubName(2).toString(); +// std::size_t pos = rawPath.find("/"); +// path = rawPath.substr(pos); +// } +// +// // Create new producer +// +// // Create timer for response availability +// std::shared_ptr portal; +// po->getSocketOption(icnet::GeneralTransportOptions::PORTAL, portal); +// boost::asio::io_service &ioService = portal->getIoService(); +// +// boost::asio::deadline_timer t(ioService, boost::posix_time::seconds(5)); +// +// std::function +// wait_callback = [&ioService](const boost::system::error_code e) { +// if (!e) { +// // Be sure to delete the timer before the io_service, otherwise we'll get some strange behavior! +// ioService.stop(); +// } +// }; +// +// std::function +// interest_enter_callback = [this, &wait_callback, &t] +// (transport::ProducerSocket &p, const core::Interest &interest) { +// t.cancel(); +// t.expires_from_now(boost::posix_time::seconds(5)); +// t.async_wait(wait_callback); +// }; +// +// p->setSocketOption(transport::ProducerCallbacksOptions::INTEREST_INPUT, +// (transport::ProducerInterestCallback) interest_enter_callback); +// +// t.async_wait(wait_callback); +// +// p->serveForever(); +// +// std::unique_lock lock(thread_list_mtx_); +// icn_producers_.erase(request_name); +// }); +// +// t.detach(); +//} + +} + +} \ No newline at end of file diff --git a/icnet/http/icnet_http_server_acceptor.h b/icnet/http/icnet_http_server_acceptor.h new file mode 100644 index 00000000..2d0b7f25 --- /dev/null +++ b/icnet/http/icnet_http_server_acceptor.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017 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 "icnet_transport_socket_consumer.h" +#include "icnet_transport_socket_producer.h" +#include "icnet_http_default_values.h" +#include "icnet_http_server_publisher.h" + +#include +#include + +#define HTTP_VERSION "1.0" + +namespace icnet { + +namespace http { + +//typedef std::vector HTTPResponse; +typedef std::vector HttpRequest; +typedef std::function &, const uint8_t *, std::size_t)> OnHttpRequest; + +class HTTPServerAcceptor { + public: + HTTPServerAcceptor(std::string &&server_locator, OnHttpRequest callback); + HTTPServerAcceptor(std::string &server_locator, OnHttpRequest callback); + + void listen(bool async); + + HttpRequest &&request(); + +// void asyncSendResponse(); + +// HTTPClientConnection& get(std::string &url, HTTPHeaders headers = {}, HTTPPayload payload = {}); +// +// HTTPResponse&& response(); + + private: + + void processIncomingInterest(transport::ProducerSocket &p, const transport::Interest &interest); + + OnHttpRequest callback_; + HttpRequest request_; + std::shared_ptr acceptor_producer_; +}; + +} // end namespace http + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/http/icnet_http_server_publisher.cc b/icnet/http/icnet_http_server_publisher.cc new file mode 100644 index 00000000..8ff86459 --- /dev/null +++ b/icnet/http/icnet_http_server_publisher.cc @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 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 "icnet_http_server_publisher.h" + +namespace icnet { + +namespace http { + +HTTPServerPublisher::HTTPServerPublisher(const transport::Name &content_name) + : content_name_(content_name) { + // Create a new publisher + producer_ = std::unique_ptr(new transport::ProducerSocket(content_name)); + producer_->attach(); +} + +HTTPServerPublisher::~HTTPServerPublisher() { + this->timer_->cancel(); +} + +HTTPServerPublisher &HTTPServerPublisher::setTimeout(uint32_t timeout) { + std::shared_ptr portal; + producer_->getSocketOption(transport::GeneralTransportOptions::PORTAL, portal); + timer_ = std::unique_ptr(new boost::asio::deadline_timer(portal->getIoService(), + boost::posix_time::seconds( + timeout))); + + wait_callback_ = [this](const boost::system::error_code e) { + if (!e) { + producer_->stop(); + } + }; + + interest_enter_callback_ = [this, timeout](transport::ProducerSocket &p, const transport::Interest &interest) { + this->timer_->cancel(); + this->timer_->expires_from_now(boost::posix_time::seconds(timeout)); + this->timer_->async_wait(wait_callback_); + }; + + producer_->setSocketOption(transport::ProducerCallbacksOptions::INTEREST_INPUT, + (transport::ProducerInterestCallback) interest_enter_callback_); + + timer_->async_wait(wait_callback_); + + return *this; +} + +void HTTPServerPublisher::publishContent(const uint8_t *buf, size_t buffer_size, const int response_id, bool is_last) { + if (producer_) { + std::cout << "Replying to " << content_name_ << std::endl; + producer_->produce(content_name_, buf, buffer_size, response_id, is_last); + } +} + +void HTTPServerPublisher::serveClients() { + producer_->serveForever(); +} + +void HTTPServerPublisher::stop() { + std::shared_ptr portal_ptr; + producer_->getSocketOption(transport::GeneralTransportOptions::PORTAL, portal_ptr); + portal_ptr->getIoService().stop(); +} + +} + +} \ No newline at end of file diff --git a/icnet/http/icnet_http_server_publisher.h b/icnet/http/icnet_http_server_publisher.h new file mode 100644 index 00000000..933d20c8 --- /dev/null +++ b/icnet/http/icnet_http_server_publisher.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017 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 "icnet_transport_socket_consumer.h" +#include "icnet_transport_socket_producer.h" +#include "icnet_http_default_values.h" + +#include +#include + +#define HTTP_VERSION "1.0" + +namespace icnet { + +namespace http { + +typedef std::vector HttpRequest; +typedef std::function DeadlineTimerCallback; + +class HTTPServerPublisher { + public: + HTTPServerPublisher(const transport::Name &content_name); + + ~HTTPServerPublisher(); + + void publishContent(const uint8_t *buf, + size_t buffer_size, + const int response_id, + bool is_last); + + void serveClients(); + + void stop(); + + HTTPServerPublisher &setTimeout(uint32_t timeout); + +// HttpRequest&& request(); + +// void sendResponse(); + +// HTTPClientConnection& get(std::string &url, HTTPHeaders headers = {}, HTTPPayload payload = {}); +// +// HTTPResponse&& response(); + + private: + + void processIncomingInterest(transport::ProducerSocket &p, const transport::Interest &interest); + + transport::Name content_name_; + std::unique_ptr timer_; + std::unique_ptr producer_; + transport::ProducerInterestCallback interest_enter_callback_; + DeadlineTimerCallback wait_callback_; +}; + +} // end namespace http + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/transport/icnet_common.h b/icnet/transport/icnet_common.h deleted file mode 100644 index d507b324..00000000 --- a/icnet/transport/icnet_common.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_COMMON_H_ -#define ICNET_COMMON_H_ - -// require C++11 -#if __cplusplus < 201103L && !defined(__GXX_EXPERIMENTAL_CXX0X__) -#error "icnet needs to be compiled using the C++11 standard" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.hpp" -#include "icnet_ccnx_facade.h" - -#if defined(__GNUC__) || defined(__clang__) -# define DEPRECATED(func) func __attribute__ ((deprecated)) -#elif defined(_MSC_VER) -# define DEPRECATED(func) __declspec(deprecated) func -#else -# pragma message("DEPRECATED not implemented") -# define DEPRECATED(func) func -#endif - -#endif // ICNET_COMMON_H_ diff --git a/icnet/transport/icnet_content_store.cc b/icnet/transport/icnet_content_store.cc deleted file mode 100644 index 64694b20..00000000 --- a/icnet/transport/icnet_content_store.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2017 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 "icnet_content_store.h" - -namespace icnet { - -ContentStore::ContentStore(std::size_t max_packets) - : max_content_store_size_(max_packets) { -} - -ContentStore::~ContentStore() { - content_store_hash_table_.clear(); -} - -void ContentStore::insert(const std::shared_ptr &content_object) { - std::unique_lock lock(cs_mutex_); - if (content_store_hash_table_.size() >= max_content_store_size_) { - // Evict item - content_store_hash_table_.erase(lru_list_.back()); - lru_list_.pop_back(); - } - - // Insert new item - lru_list_.push_back(std::cref(content_object->getName())); - LRUList::iterator pos = lru_list_.end(); - content_store_hash_table_[content_object->getName()] = CcnxContentStoreEntry(content_object, pos); - -} - -const std::shared_ptr &ContentStore::find(const Interest &interest) { - std::unique_lock lock(cs_mutex_); - ContentStoreHashTable::iterator it = content_store_hash_table_.find(interest.getName()); - if (it != content_store_hash_table_.end()) { - if (it->second.second != lru_list_.begin()) { - // Move element to the top of the LRU list - lru_list_.splice(lru_list_.begin(), lru_list_, it->second.second); - } - return it->second.first; - } else { - return empty_reference_; - } -} - -void ContentStore::erase(const Name &exact_name) { - std::unique_lock lock(cs_mutex_); - ContentStoreHashTable::iterator it = content_store_hash_table_.find(exact_name); - lru_list_.erase(it->second.second); - content_store_hash_table_.erase(exact_name); -} - -void ContentStore::setLimit(size_t max_packets) { - max_content_store_size_ = max_packets; -} - -std::size_t ContentStore::getLimit() const { - return max_content_store_size_; -} - -std::size_t ContentStore::size() const { - return content_store_hash_table_.size(); -} - -} // end namespace icnet \ No newline at end of file diff --git a/icnet/transport/icnet_content_store.h b/icnet/transport/icnet_content_store.h deleted file mode 100644 index a626055d..00000000 --- a/icnet/transport/icnet_content_store.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_CONTENT_STORE_H_ -#define ICNET_CONTENT_STORE_H_ - -#include "icnet_socket.h" - -#include - -namespace icnet { - -typedef std::pair, std::list>::iterator> - CcnxContentStoreEntry; -typedef std::list> LRUList; -typedef std::unordered_map ContentStoreHashTable; - -class ContentStore { - public: - - explicit ContentStore(std::size_t max_packets = 65536); - - ~ContentStore(); - - void insert(const std::shared_ptr &content_object); - - const std::shared_ptr &find(const Interest &interest); - - void erase(const Name &exact_name); - - void setLimit(size_t max_packets); - - size_t getLimit() const; - - size_t size() const; - - private: - ContentStoreHashTable content_store_hash_table_; - LRUList lru_list_; - std::shared_ptr empty_reference_; - std::size_t max_content_store_size_; - std::mutex cs_mutex_; -}; - -} // end namespace icnet - - -#endif // ICNET_CONTENT_STORE_H_ diff --git a/icnet/transport/icnet_download_observer.h b/icnet/transport/icnet_download_observer.h deleted file mode 100644 index 7b640a1c..00000000 --- a/icnet/transport/icnet_download_observer.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_DOWNLOAD_OBSERVER_H_ -#define ICNET_DOWNLOAD_OBSERVER_H_ - -namespace icnet { - -class IcnObserver { - public: - virtual ~IcnObserver() { - }; - - virtual void notifyStats(double throughput) = 0; -}; - -} // end namespace icnet - -#endif // ICNET_DOWNLOAD_OBSERVER_H_ - diff --git a/icnet/transport/icnet_rate_estimation.cc b/icnet/transport/icnet_rate_estimation.cc deleted file mode 100644 index b378da06..00000000 --- a/icnet/transport/icnet_rate_estimation.cc +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (c) 2017 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 "icnet_rate_estimation.h" - -namespace icnet { - -void *Timer(void *data) { - InterRttEstimator *estimator = (InterRttEstimator *) data; - - double dat_rtt, my_avg_win, my_avg_rtt; - int my_win_change, number_of_packets, max_packet_size; - - pthread_mutex_lock(&(estimator->mutex_)); - dat_rtt = estimator->rtt_; - pthread_mutex_unlock(&(estimator->mutex_)); - - while (estimator->is_running_) { - usleep(KV * dat_rtt); - - pthread_mutex_lock(&(estimator->mutex_)); - - dat_rtt = estimator->rtt_; - my_avg_win = estimator->avg_win_; - my_avg_rtt = estimator->avg_rtt_; - my_win_change = estimator->win_change_; - number_of_packets = estimator->number_of_packets_; - max_packet_size = estimator->max_packet_size_; - estimator->avg_rtt_ = estimator->rtt_; - estimator->avg_win_ = 0; - estimator->win_change_ = 0; - estimator->number_of_packets_ = 1; - - pthread_mutex_unlock(&(estimator->mutex_)); - - if (number_of_packets == 0 || my_win_change == 0) { - continue; - } - if (estimator->estimation_ == 0) { - estimator->estimation_ = (my_avg_win * 8.0 * max_packet_size * 1000000.0 / (1.0 * my_win_change)) - / (my_avg_rtt / (1.0 * number_of_packets)); - } - - estimator->estimation_ = estimator->alpha_ * estimator->estimation_ + (1 - estimator->alpha_) - * ((my_avg_win * 8.0 * max_packet_size * 1000000.0 / (1.0 * my_win_change)) - / (my_avg_rtt / (1.0 * number_of_packets))); - - if (estimator->observer_) { - estimator->observer_->notifyStats(estimator->estimation_); - } - } - - return nullptr; -} - -InterRttEstimator::InterRttEstimator(double alpha_arg) { - this->estimated_ = false; - this->observer_ = NULL; - this->alpha_ = alpha_arg; - this->thread_is_running_ = false; - this->my_th_ = NULL; - this->is_running_ = true; - this->avg_rtt_ = 0.0; - this->estimation_ = 0.0; - this->avg_win_ = 0.0; - this->rtt_ = 0.0; - this->win_change_ = 0; - this->number_of_packets_ = 0; - this->max_packet_size_ = 0; - this->win_current_ = 1.0; - - pthread_mutex_init(&(this->mutex_), NULL); - gettimeofday(&(this->begin_), 0); -} - -InterRttEstimator::~InterRttEstimator() { - this->is_running_ = false; - if (this->my_th_) { - pthread_join(*(this->my_th_), NULL); - } - this->my_th_ = NULL; - pthread_mutex_destroy(&(this->mutex_)); -} - -void InterRttEstimator::onRttUpdate(double rtt) { - pthread_mutex_lock(&(this->mutex_)); - this->rtt_ = rtt; - this->number_of_packets_++; - this->avg_rtt_ += rtt; - pthread_mutex_unlock(&(this->mutex_)); - - if (!thread_is_running_) { - my_th_ = (pthread_t *) malloc(sizeof(pthread_t)); - if (!my_th_) { - std::cerr << "Error allocating thread." << std::endl; - my_th_ = NULL; - } - if (/*int err = */pthread_create(my_th_, NULL, icnet::Timer, (void *) this)) { - std::cerr << "Error creating the thread" << std::endl; - my_th_ = NULL; - } - thread_is_running_ = true; - } -} - -void InterRttEstimator::onWindowIncrease(double win_current) { - timeval end; - gettimeofday(&end, 0); - double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); - - pthread_mutex_lock(&(this->mutex_)); - this->avg_win_ += this->win_current_ * delay; - this->win_current_ = win_current; - this->win_change_ += delay; - pthread_mutex_unlock(&(this->mutex_)); - - gettimeofday(&(this->begin_), 0); -} - -void InterRttEstimator::onWindowDecrease(double win_current) { - timeval end; - gettimeofday(&end, 0); - double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); - - pthread_mutex_lock(&(this->mutex_)); - this->avg_win_ += this->win_current_ * delay; - this->win_current_ = win_current; - this->win_change_ += delay; - pthread_mutex_unlock(&(this->mutex_)); - - gettimeofday(&(this->begin_), 0); -} - -ALaTcpEstimator::ALaTcpEstimator() { - this->estimation_ = 0.0; - this->observer_ = NULL; - gettimeofday(&(this->begin_), 0); - this->totalSize_ = 0.0; -} - -void ALaTcpEstimator::onStart() { - this->totalSize_ = 0.0; - gettimeofday(&(this->begin_), 0); -} - -void ALaTcpEstimator::onDownloadFinished() { - timeval end; - gettimeofday(&end, 0); - double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); - this->estimation_ = this->totalSize_ * 8 * 1000000 / delay; - if (observer_) { - observer_->notifyStats(this->estimation_); - } -} - -void ALaTcpEstimator::onDataReceived(int packet_size) { - this->totalSize_ += packet_size; -} - -SimpleEstimator::SimpleEstimator(double alphaArg, int batching_param) { - this->estimation_ = 0.0; - this->estimated_ = false; - this->observer_ = NULL; - this->batching_param_ = batching_param; - this->total_size_ = 0.0; - this->number_of_packets_ = 0; - this->base_alpha_ = alphaArg; - this->alpha_ = alphaArg; - gettimeofday(&(this->begin_), 0); -} - -void SimpleEstimator::onStart() { - this->estimated_ = false; - this->number_of_packets_ = 0; - this->total_size_ = 0.0; - gettimeofday(&(this->begin_), 0); -} - -void SimpleEstimator::onDownloadFinished() { - if (!this->estimated_) { - timeval end; - gettimeofday(&end, 0); - double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); - - //Assuming all packets carry max_packet_size_ bytes of data (8*max_packet_size_ bits); 1000000 factor to convert us to seconds - if (this->estimation_) { - this->estimation_ = alpha_ * this->estimation_ + (1 - alpha_) * (total_size_ * 8 * 1000000.0 / (delay)); - } else { - this->estimation_ = total_size_ * 8 * 1000000.0 / (delay); - } - if (observer_) { - observer_->notifyStats(this->estimation_); - } - this->alpha_ = this->base_alpha_ * (((double) this->number_of_packets_) / ((double) this->batching_param_)); - this->number_of_packets_ = 0; - this->total_size_ = 0.0; - gettimeofday(&(this->begin_), 0); - } else { - if (this->number_of_packets_ >= (int) (75.0 * (double) this->batching_param_ / 100.0)) { - timeval end; - gettimeofday(&end, 0); - double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); - - //Assuming all packets carry max_packet_size_ bytes of data (8*max_packet_size_ bits); 1000000 factor to convert us to seconds - if (this->estimation_) { - this->estimation_ = alpha_ * this->estimation_ + (1 - alpha_) * (total_size_ * 8 * 1000000.0 / (delay)); - } else { - this->estimation_ = total_size_ * 8 * 1000000.0 / (delay); - } - if (observer_) { - observer_->notifyStats(this->estimation_); - } - this->alpha_ = this->base_alpha_ * (((double) this->number_of_packets_) / ((double) this->batching_param_)); - this->number_of_packets_ = 0; - this->total_size_ = 0.0; - - gettimeofday(&(this->begin_), 0); - - } - } -} - -void SimpleEstimator::onDataReceived(int packet_size) { - this->total_size_ += packet_size; -} - -void SimpleEstimator::onRttUpdate(double rtt) { - this->number_of_packets_++; - - if (number_of_packets_ == this->batching_param_) { - timeval end; - gettimeofday(&end, 0); - double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); - //Assuming all packets carry max_packet_size_ bytes of data (8*max_packet_size_ bits); 1000000 factor to convert us to seconds - if (this->estimation_) { - this->estimation_ = alpha_ * this->estimation_ + (1 - alpha_) * (total_size_ * 8 * 1000000.0 / (delay)); - } else { - this->estimation_ = total_size_ * 8 * 1000000.0 / (delay); - } - if (observer_) { - observer_->notifyStats(this->estimation_); - } - this->alpha_ = this->base_alpha_; - this->number_of_packets_ = 0; - this->total_size_ = 0.0; - gettimeofday(&(this->begin_), 0); - } -} - -BatchingPacketsEstimator::BatchingPacketsEstimator(double alpha_arg, int param) { - this->estimated_ = false; - this->observer_ = NULL; - this->alpha_ = alpha_arg; - this->batching_param_ = param; - this->number_of_packets_ = 0; - this->avg_win_ = 0.0; - this->avg_rtt_ = 0.0; - this->win_change_ = 0.0; - this->max_packet_size_ = 0; - this->estimation_ = 0.0; - this->win_current_ = 1.0; - gettimeofday(&(this->begin_), 0); -} - -void BatchingPacketsEstimator::onRttUpdate(double rtt) { - this->number_of_packets_++; - this->avg_rtt_ += rtt; - - if (number_of_packets_ == this->batching_param_) { - if (estimation_ == 0) { - estimation_ = (avg_win_ * 8.0 * max_packet_size_ * 1000000.0 / (1.0 * win_change_)) - / (avg_rtt_ / (1.0 * number_of_packets_)); - } else { - estimation_ = alpha_ * estimation_ + (1 - alpha_) - * ((avg_win_ * 8.0 * max_packet_size_ * 1000000.0 / (1.0 * win_change_)) - / (avg_rtt_ / (1.0 * number_of_packets_))); - } - - if (observer_) { - observer_->notifyStats(estimation_); - } - - this->number_of_packets_ = 0; - this->avg_win_ = 0.0; - this->avg_rtt_ = 0.0; - this->win_change_ = 0.0; - } -} - -void BatchingPacketsEstimator::onWindowIncrease(double win_current) { - timeval end; - gettimeofday(&end, 0); - double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); - this->avg_win_ += this->win_current_ * delay; - this->win_current_ = win_current; - this->win_change_ += delay; - gettimeofday(&(this->begin_), 0); -} - -void BatchingPacketsEstimator::onWindowDecrease(double win_current) { - timeval end; - gettimeofday(&end, 0); - double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); - this->avg_win_ += this->win_current_ * delay; - this->win_current_ = win_current; - this->win_change_ += delay; - gettimeofday(&(this->begin_), 0); -} - -} // end namespace icnet - diff --git a/icnet/transport/icnet_rate_estimation.h b/icnet/transport/icnet_rate_estimation.h deleted file mode 100644 index 86b879c2..00000000 --- a/icnet/transport/icnet_rate_estimation.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_RATE_ESTIMATION_H_ -#define ICNET_RATE_ESTIMATION_H_ - -#include - -#include "icnet_transport_raaqm_data_path.h" -#include "icnet_download_observer.h" - -#define BATCH 50 -#define KV 20 -#define ALPHA 0.8 -#define RATE_CHOICE 0 - -namespace icnet { - -class IcnRateEstimator { - public: - IcnRateEstimator() { - }; - - virtual ~IcnRateEstimator() { - }; - - virtual void onRttUpdate(double rtt) { - }; - - virtual void onDataReceived(int packetSize) { - }; - - virtual void onWindowIncrease(double winCurrent) { - }; - - virtual void onWindowDecrease(double winCurrent) { - }; - - virtual void onStart() { - }; - - virtual void onDownloadFinished() { - }; - - virtual void setObserver(IcnObserver *observer) { - this->observer_ = observer; - }; - IcnObserver *observer_; - struct timeval begin_; - double base_alpha_; - double alpha_; - double estimation_; - int number_of_packets_; - // this boolean is to make sure at least one estimation of the BW is done - bool estimated_; -}; - -// A rate estimator RTT-based. Computes EWMA(WinSize)/EWMA(RTT) - -class InterRttEstimator : public IcnRateEstimator { - public: - InterRttEstimator(double alpha_arg); - - ~InterRttEstimator(); - - void onRttUpdate(double rtt); - - void onDataReceived(int packet_size) { - if (packet_size > this->max_packet_size_) { - this->max_packet_size_ = packet_size; - } - }; - - void onWindowIncrease(double win_current); - - void onWindowDecrease(double win_current); - - void onStart() { - }; - - void onDownloadFinished() { - }; - - // private: should be done by using getters - pthread_t *my_th_; - bool thread_is_running_; - double rtt_; - bool is_running_; - pthread_mutex_t mutex_; - double avg_rtt_; - double avg_win_; - int max_packet_size_; - double win_change_; - double win_current_; -}; - -// A rate estimator, Batching Packets based. Computes EWMA(WinSize)/EWMA(RTT) - -class BatchingPacketsEstimator : public IcnRateEstimator { - public: - BatchingPacketsEstimator(double alpha_arg, int batchingParam); - - void onRttUpdate(double rtt); - - void onDataReceived(int packet_size) { - if (packet_size > this->max_packet_size_) { - this->max_packet_size_ = packet_size; - } - }; - - void onWindowIncrease(double win_current); - - void onWindowDecrease(double win_current); - - void onStart() { - }; - - void onDownloadFinished() { - }; - - private: - int batching_param_; - double avg_rtt_; - double avg_win_; - double win_change_; - int max_packet_size_; - double win_current_; -}; - -//Segment Estimator - -class ALaTcpEstimator : public IcnRateEstimator { - public: - ALaTcpEstimator(); - - void onDataReceived(int packet_size); - void onStart(); - void onDownloadFinished(); - - private: - double totalSize_; -}; - -// A Rate estimator, this one is the simplest: counting batching_param_ packets and then divide the sum of the size of these packets by the time taken to DL them. -// Should be the one used - -class SimpleEstimator : public IcnRateEstimator { - public: - SimpleEstimator(double alpha, int batching_param); - - void onRttUpdate(double rtt); - - void onDataReceived(int packet_size); - - void onWindowIncrease(double win_current) { - }; - - void onWindowDecrease(double win_current) { - }; - - void onStart(); - - void onDownloadFinished(); - - private: - int batching_param_; - double total_size_; -}; - -void *Timer(void *data); - -}// end namespace icnet - -#endif // ICNET_RATE_ESTIMATION_H_ - diff --git a/icnet/transport/icnet_socket.h b/icnet/transport/icnet_socket.h deleted file mode 100644 index f1ce8da0..00000000 --- a/icnet/transport/icnet_socket.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_SOCKET_H_ -#define ICNET_SOCKET_H_ - -#include "icnet_common.h" -#include "icnet_socket_options_keys.h" -#include "icnet_socket_options_default_values.h" -#include "icnet_download_observer.h" - -#define SOCKET_OPTION_GET 0 -#define SOCKET_OPTION_NOT_GET 1 -#define SOCKET_OPTION_SET 2 -#define SOCKET_OPTION_NOT_SET 3 -#define SOCKET_OPTION_DEFAULT 12345 - -#define VOID_HANDLER 0 - -namespace icnet { - -class ConsumerSocket; -class ProducerSocket; - -typedef ccnx::Interest Interest; -typedef ccnx::ContentObject ContentObject; -typedef ccnx::Name Name; -typedef ccnx::Manifest Manifest; -typedef ccnx::Portal Portal; -typedef ccnx::KeyLocator KeyLocator; -typedef ccnx::Segment Segment; -typedef ccnx::PayloadType PayloadType; -typedef ccnx::Array Array; - -typedef std::function ConsumerInterestCallback; -typedef std::function ConsumerContentCallback; -typedef std::function ConsumerContentObjectCallback; -typedef std::function ConsumerContentObjectVerificationCallback; -typedef std::function ConsumerManifestCallback; -typedef std::function ProducerContentObjectCallback; -typedef std::function ProducerInterestCallback; - -class Socket { - public: - - virtual int setSocketOption(int socket_option_key, int socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, double socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, size_t socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, bool socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, Name socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, KeyLocator socket_option_value) = 0; - - virtual int setSocketOption(int socket_option_key, IcnObserver *socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, int &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, double &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, size_t &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, bool &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, Name &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, - ConsumerContentObjectVerificationCallback &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, KeyLocator &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value) = 0; - - virtual int getSocketOption(int socket_option_key, IcnObserver **socket_option_value) = 0; - - protected: - virtual ~Socket() { - }; -}; - -} // namespace icnet - -#endif // ICNET_SOCKET_H_ diff --git a/icnet/transport/icnet_socket_consumer.cc b/icnet/transport/icnet_socket_consumer.cc deleted file mode 100644 index 2aec571b..00000000 --- a/icnet/transport/icnet_socket_consumer.cc +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (c) 2017 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 "icnet_socket_consumer.h" - -namespace icnet { - -ConsumerSocket::ConsumerSocket(Name prefix, int protocol) - : is_running_(false), - name_prefix_(prefix), - interest_lifetime_(default_values::interest_lifetime), - min_window_size_(default_values::min_window_size), - max_window_size_(default_values::max_window_size), - current_window_size_(-1), - max_retransmissions_(default_values::transport_protocol_max_retransmissions), - /****** RAAQM Parameters ******/ - minimum_drop_probability_(default_values::minimum_drop_probability), - sample_number_(default_values::sample_number), - gamma_(default_values::gamma_value), - beta_(default_values::beta_value), - drop_factor_(default_values::drop_factor), - /****** END RAAQM Parameters ******/ - rate_estimation_alpha_(default_values::rate_alpha), - rate_estimation_observer_(NULL), - is_async_(false), - on_interest_output_(VOID_HANDLER), - on_interest_timeout_(VOID_HANDLER), - on_interest_satisfied_(VOID_HANDLER), - on_content_object_input_(VOID_HANDLER), - on_content_object_verification_(VOID_HANDLER), - on_content_object_(VOID_HANDLER), - on_manifest_(VOID_HANDLER), - on_payload_retrieved_(VOID_HANDLER), - virtual_download_(false), - rtt_stats_(false) { - - portal_ = std::make_shared(); - - switch (protocol) { - case TransportProtocolAlgorithms::VEGAS: { - transport_protocol_ = std::make_shared(this); - break; - } - case TransportProtocolAlgorithms::RAAQM: { - transport_protocol_ = std::make_shared(this); - break; - } - } -} - -ConsumerSocket::~ConsumerSocket() { - stop(); - transport_protocol_.reset(); - portal_.reset(); -} - -int ConsumerSocket::consume(Name suffix) { - if (is_running_) { - portal_->getIoService().post(std::bind(&ConsumerSocket::postponedConsume, this, suffix)); - return CONSUMER_BUSY; - } - - if (is_async_) { - portal_ = std::make_shared(); - transport_protocol_->updatePortal(); - } - - name_suffix_ = suffix; - is_async_ = false; - transport_protocol_->start(); - is_running_ = false; - return CONSUMER_READY; -} - -void ConsumerSocket::postponedConsume(Name name_suffix) { - if (is_async_) { - portal_ = std::make_shared(); - transport_protocol_->updatePortal(); - } - - name_suffix_ = name_suffix; - is_async_ = false; - transport_protocol_->start(); -} - -int ConsumerSocket::asyncConsume(Name suffix) { - if (transport_protocol_->isRunning()) { - return CONSUMER_BUSY; - } - - name_suffix_ = suffix; - is_async_ = true; - transport_protocol_->start(); - return CONSUMER_READY; -} - -void ConsumerSocket::stop() { - if (transport_protocol_->isRunning()) { - transport_protocol_->stop(); - } - - is_running_ = false; -} - -int ConsumerSocket::setSocketOption(int socket_option_key, double socket_option_value) { - switch (socket_option_key) { - case MIN_WINDOW_SIZE: - min_window_size_ = socket_option_value; - return SOCKET_OPTION_SET; - - case MAX_WINDOW_SIZE: - max_window_size_ = socket_option_value; - return SOCKET_OPTION_SET; - - case CURRENT_WINDOW_SIZE: - current_window_size_ = socket_option_value; - return SOCKET_OPTION_SET; - - case GAMMA_VALUE: - gamma_ = socket_option_value; - return SOCKET_OPTION_SET; - - case BETA_VALUE: - beta_ = socket_option_value; - return SOCKET_OPTION_SET; - - case DROP_FACTOR: - drop_factor_ = socket_option_value; - return SOCKET_OPTION_SET; - - case MINIMUM_DROP_PROBABILITY: - minimum_drop_probability_ = socket_option_value; - return SOCKET_OPTION_SET; - - case RATE_ESTIMATION_ALPHA: - if (socket_option_value >= 0 && socket_option_value < 1) { - rate_estimation_alpha_ = socket_option_value; - } else { - rate_estimation_alpha_ = ALPHA; - } - return SOCKET_OPTION_SET; - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, int socket_option_value) { - switch (socket_option_key) { - - case GeneralTransportOptions::INPUT_BUFFER_SIZE: - input_buffer_size_ = socket_option_value; - return SOCKET_OPTION_SET; - - case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: - output_buffer_size_ = socket_option_value; - return SOCKET_OPTION_SET; - - case GeneralTransportOptions::MAX_INTEREST_RETX: - max_retransmissions_ = socket_option_value; - return SOCKET_OPTION_SET; - - case GeneralTransportOptions::INTEREST_LIFETIME: - interest_lifetime_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ConsumerCallbacksOptions::INTEREST_RETRANSMISSION: - if (socket_option_value == VOID_HANDLER) { - on_interest_retransmission_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ConsumerCallbacksOptions::INTEREST_EXPIRED: - if (socket_option_value == VOID_HANDLER) { - on_interest_timeout_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ConsumerCallbacksOptions::INTEREST_SATISFIED: - if (socket_option_value == VOID_HANDLER) { - on_interest_satisfied_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ConsumerCallbacksOptions::INTEREST_OUTPUT: - if (socket_option_value == VOID_HANDLER) { - on_interest_output_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ConsumerCallbacksOptions::CONTENT_OBJECT_INPUT: - if (socket_option_value == VOID_HANDLER) { - on_content_object_input_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY: - if (socket_option_value == VOID_HANDLER) { - on_content_object_verification_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ConsumerCallbacksOptions::CONTENT_RETRIEVED: - if (socket_option_value == VOID_HANDLER) { - on_payload_retrieved_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case RateEstimationOptions::RATE_ESTIMATION_BATCH_PARAMETER: - if (socket_option_value > 0) { - rate_estimation_batching_parameter_ = socket_option_value; - } else { - rate_estimation_batching_parameter_ = BATCH; - } - return SOCKET_OPTION_SET; - - case RateEstimationOptions::RATE_ESTIMATION_CHOICE: - if (socket_option_value > 0) { - rate_estimation_choice_ = socket_option_value; - } else { - rate_estimation_choice_ = RATE_CHOICE; - } - return SOCKET_OPTION_SET; - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, size_t socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::INPUT_BUFFER_SIZE: - input_buffer_size_ = socket_option_value; - return SOCKET_OPTION_SET; - - case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: - output_buffer_size_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, bool socket_option_value) { - switch (socket_option_key) { - - case GeneralTransportOptions::RUNNING: - is_running_ = socket_option_value; - return SOCKET_OPTION_SET; - - case OtherOptions::VIRTUAL_DOWNLOAD: - virtual_download_ = socket_option_value; - return SOCKET_OPTION_SET; - - case RaaqmTransportOptions::RTT_STATS: - rtt_stats_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, Name socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::NAME_PREFIX: - name_prefix_ = socket_option_value;; - return SOCKET_OPTION_SET; - - case GeneralTransportOptions::NAME_SUFFIX: - name_suffix_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::CONTENT_OBJECT_INPUT: - on_content_object_input_ = socket_option_value;; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ConsumerSocket::setSocketOption(int socket_option_key, - ConsumerContentObjectVerificationCallback socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY: - on_content_object_verification_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::INTEREST_RETRANSMISSION: - on_interest_retransmission_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ConsumerCallbacksOptions::INTEREST_OUTPUT: - on_interest_output_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ConsumerCallbacksOptions::INTEREST_EXPIRED: - on_interest_timeout_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ConsumerCallbacksOptions::INTEREST_SATISFIED: - on_interest_satisfied_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ConsumerSocket::setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::CONTENT_RETRIEVED: - on_payload_retrieved_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::MANIFEST_INPUT: - on_manifest_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::setSocketOption(int socket_option_key, KeyLocator socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ConsumerSocket::setSocketOption(int socket_option_key, IcnObserver *socket_option_value) { - if (socket_option_key == RateEstimationOptions::RATE_ESTIMATION_OBSERVER) { - rate_estimation_observer_ = socket_option_value; - return SOCKET_OPTION_SET; - } else { - return SOCKET_OPTION_NOT_SET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, double &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::MIN_WINDOW_SIZE: - socket_option_value = min_window_size_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::MAX_WINDOW_SIZE: - socket_option_value = max_window_size_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::CURRENT_WINDOW_SIZE: - socket_option_value = current_window_size_; - return SOCKET_OPTION_GET; - - // RAAQM parameters - - case RaaqmTransportOptions::GAMMA_VALUE: - socket_option_value = gamma_; - return SOCKET_OPTION_GET; - - case RaaqmTransportOptions::BETA_VALUE: - socket_option_value = beta_; - return SOCKET_OPTION_GET; - - case RaaqmTransportOptions::DROP_FACTOR: - socket_option_value = drop_factor_; - return SOCKET_OPTION_GET; - - case RaaqmTransportOptions::MINIMUM_DROP_PROBABILITY: - socket_option_value = minimum_drop_probability_; - return SOCKET_OPTION_GET; - - case RateEstimationOptions::RATE_ESTIMATION_ALPHA: - socket_option_value = rate_estimation_alpha_; - return SOCKET_OPTION_GET; - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, int &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::INPUT_BUFFER_SIZE: - socket_option_value = input_buffer_size_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: - socket_option_value = output_buffer_size_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::MAX_INTEREST_RETX: - socket_option_value = max_retransmissions_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::INTEREST_LIFETIME: - socket_option_value = interest_lifetime_; - return SOCKET_OPTION_GET; - - case RaaqmTransportOptions::SAMPLE_NUMBER: - socket_option_value = sample_number_; - return SOCKET_OPTION_GET; - - case RateEstimationOptions::RATE_ESTIMATION_BATCH_PARAMETER: - socket_option_value = rate_estimation_batching_parameter_; - return SOCKET_OPTION_GET; - - case RateEstimationOptions::RATE_ESTIMATION_CHOICE: - socket_option_value = rate_estimation_choice_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, size_t &socket_option_value) { - switch (socket_option_key) { - case INPUT_BUFFER_SIZE: - socket_option_value = input_buffer_size_; - return SOCKET_OPTION_GET; - - case OUTPUT_BUFFER_SIZE: - socket_option_value = output_buffer_size_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, bool &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::ASYNC_MODE: - socket_option_value = is_async_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::RUNNING: - socket_option_value = is_running_; - return SOCKET_OPTION_GET; - - case OtherOptions::VIRTUAL_DOWNLOAD: - socket_option_value = virtual_download_; - return SOCKET_OPTION_GET; - - case RaaqmTransportOptions::RTT_STATS: - socket_option_value = rtt_stats_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, Name &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::NAME_PREFIX: - socket_option_value = name_prefix_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::NAME_SUFFIX: - socket_option_value = name_suffix_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::CONTENT_OBJECT_INPUT: - socket_option_value = on_content_object_input_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ConsumerSocket::getSocketOption(int socket_option_key, - ConsumerContentObjectVerificationCallback &socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY: - socket_option_value = on_content_object_verification_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::INTEREST_RETRANSMISSION: - socket_option_value = on_interest_retransmission_; - return SOCKET_OPTION_GET; - - case ConsumerCallbacksOptions::INTEREST_OUTPUT: - socket_option_value = on_interest_output_; - return SOCKET_OPTION_GET; - - case ConsumerCallbacksOptions::INTEREST_EXPIRED: - socket_option_value = on_interest_timeout_; - return SOCKET_OPTION_GET; - - case ConsumerCallbacksOptions::INTEREST_SATISFIED: - socket_option_value = on_interest_satisfied_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ConsumerSocket::getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::CONTENT_RETRIEVED: - socket_option_value = on_payload_retrieved_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value) { - switch (socket_option_key) { - case ConsumerCallbacksOptions::MANIFEST_INPUT: - socket_option_value = on_manifest_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, KeyLocator &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::KEY_LOCATOR: - socket_option_value = key_locator_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value) { - switch (socket_option_key) { - case PORTAL: - socket_option_value = portal_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ConsumerSocket::getSocketOption(int socket_option_key, IcnObserver **socket_option_value) { - if (socket_option_key == RATE_ESTIMATION_OBSERVER) { - *socket_option_value = (rate_estimation_observer_); - return SOCKET_OPTION_GET; - } else { - return SOCKET_OPTION_NOT_GET; - } -} - -} // end namespace icnet diff --git a/icnet/transport/icnet_socket_consumer.h b/icnet/transport/icnet_socket_consumer.h deleted file mode 100644 index 6b9ec811..00000000 --- a/icnet/transport/icnet_socket_consumer.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_CONSUMER_SOCKET_H_ -#define ICNET_CONSUMER_SOCKET_H_ - -#include "icnet_common.h" -#include "icnet_socket.h" -#include "icnet_transport.h" -#include "icnet_transport_raaqm.h" -#include "icnet_transport_vegas.h" - -#define CONSUMER_READY 0 -#define CONSUMER_BUSY 1 - -namespace icnet { - -class ConsumerSocket : public Socket { - public: - explicit ConsumerSocket(const Name prefix, int protocol); - - ~ConsumerSocket(); - - int consume(Name suffix); - - int asyncConsume(Name suffix); - - void stop(); - - int setSocketOption(int socket_option_key, int socket_option_value); - - int setSocketOption(int socket_option_key, double socket_option_value); - - int setSocketOption(int socket_option_key, bool socket_option_value); - - int setSocketOption(int socket_option_key, size_t socket_option_value); - - int setSocketOption(int socket_option_key, Name socket_option_value); - - int setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value); - - int setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value); - - int setSocketOption(int socket_option_key, KeyLocator socket_option_value); - - int setSocketOption(int socket_option_key, IcnObserver *socket_option_value); - - int getSocketOption(int socket_option_key, int &socket_option_value); - - int getSocketOption(int socket_option_key, double &socket_option_value); - - int getSocketOption(int socket_option_key, size_t &socket_option_value); - - int getSocketOption(int socket_option_key, bool &socket_option_value); - - int getSocketOption(int socket_option_key, Name &socket_option_value); - - int getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value); - - int getSocketOption(int socket_option_key, KeyLocator &socket_option_value); - - int getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value); - - int getSocketOption(int socket_option_key, IcnObserver **socket_option_value); - - private: - - void postponedConsume(Name name_suffix); - - private: - // context inner state variables - bool is_running_; - std::shared_ptr portal_; - std::shared_ptr transport_protocol_; - - Name name_prefix_; - Name name_suffix_; - - int interest_lifetime_; - - double min_window_size_; - double max_window_size_; - double current_window_size_; - int max_retransmissions_; - size_t output_buffer_size_; - size_t input_buffer_size_; - - // RAAQM Parameters - - double minimum_drop_probability_; - unsigned int sample_number_; - double gamma_; - double beta_; - double drop_factor_; - - //Rate estimation parameters - double rate_estimation_alpha_; - IcnObserver *rate_estimation_observer_; - int rate_estimation_batching_parameter_; - int rate_estimation_choice_; - - bool is_async_; - - KeyLocator key_locator_; - - ConsumerInterestCallback on_interest_retransmission_; - ConsumerInterestCallback on_interest_output_; - ConsumerInterestCallback on_interest_timeout_; - ConsumerInterestCallback on_interest_satisfied_; - - ConsumerContentObjectCallback on_content_object_input_; - ConsumerContentObjectVerificationCallback on_content_object_verification_; - - ConsumerContentObjectCallback on_content_object_; - ConsumerManifestCallback on_manifest_; - - ConsumerContentCallback on_payload_retrieved_; - - // Virtual download for traffic generator - - bool virtual_download_; - bool rtt_stats_; -}; - -} // end namespace icnet - -#endif // ICNET_CONSUMER_SOCKET_H_ diff --git a/icnet/transport/icnet_socket_options_default_values.h b/icnet/transport/icnet_socket_options_default_values.h deleted file mode 100644 index 4f6d68e9..00000000 --- a/icnet/transport/icnet_socket_options_default_values.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_SOCKET_OPTIONS_DEFAULT_VALUES_H_ -#define ICNET_SOCKET_OPTIONS_DEFAULT_VALUES_H_ - -namespace icnet { - -namespace default_values { - -const int interest_lifetime = 1000; // milliseconds -const int content_object_expiry_time = 50000; // milliseconds -> 50 seconds -const int content_object_packet_size = 1500; // The ethernet MTU -const int producer_socket_input_buffer_size = 150000; // Interests -const int producer_socket_output_buffer_size = 150000; // Content Object -const int default_buffer_size = 8096 * 8 * 2; -const int signature_size = 260; // bytes -const int key_locator_size = 60; // bytes -const int limit_guard = 80; // bytes -const int min_window_size = 1; // Interests -const int max_window_size = 128000; // Interests -const int digest_size = 34; // bytes -const int max_out_of_order_segments = 3; // content object - -// RAAQM -const int sample_number = 30; -const double gamma_value = 1; -const double beta_value = 0.8; -const double drop_factor = 0.2; -const double minimum_drop_probability = 0.00001; -const int path_id = 0; -const double rate_alpha = 0.8; - -// Vegas -const double alpha = 1 / 8; -const double beta = 1 / 4; -const uint16_t k = 4; -const std::chrono::milliseconds clock_granularity = std::chrono::milliseconds(100); - -// maximum allowed values -const int transport_protocol_min_retransmissions = 0; -const int transport_protocol_max_retransmissions = 128; -const int max_content_object_size = 8096; - -} // end namespace default_values - -} // end namespace icnet - -#endif // ICNET_SOCKET_OPTIONS_DEFAULT_VALUES_H_ diff --git a/icnet/transport/icnet_socket_options_keys.h b/icnet/transport/icnet_socket_options_keys.h deleted file mode 100644 index 4b82f67a..00000000 --- a/icnet/transport/icnet_socket_options_keys.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_TRANSPORT_OPTIONS_KEYS_H_ -#define ICNET_TRANSPORT_OPTIONS_KEYS_H_ - -namespace icnet { - -typedef enum { - RAAQM = 0, VEGAS = 1 -} TransportProtocolAlgorithms; - -typedef enum { - INPUT_BUFFER_SIZE = 101, - OUTPUT_BUFFER_SIZE = 102, - NAME_PREFIX = 103, - NAME_SUFFIX = 104, - MAX_INTEREST_RETX = 105, - DATA_PACKET_SIZE = 106, - INTEREST_LIFETIME = 107, - CONTENT_OBJECT_EXPIRY_TIME = 108, - KEY_LOCATOR = 110, - SIGNATURE_TYPE = 111, - MIN_WINDOW_SIZE = 112, - MAX_WINDOW_SIZE = 113, - CURRENT_WINDOW_SIZE = 114, - ASYNC_MODE = 115, - MAKE_MANIFEST = 116, - PORTAL = 117, - RUNNING = 118, -} GeneralTransportOptions; - -typedef enum { - SAMPLE_NUMBER = 201, - GAMMA_VALUE = 202, - BETA_VALUE = 203, - DROP_FACTOR = 204, - MINIMUM_DROP_PROBABILITY = 205, - PATH_ID = 206, - RTT_STATS = 207, -} RaaqmTransportOptions; - -typedef enum { - RATE_ESTIMATION_ALPHA = 301, - RATE_ESTIMATION_OBSERVER = 302, - RATE_ESTIMATION_BATCH_PARAMETER = 303, - RATE_ESTIMATION_CHOICE = 304, -} RateEstimationOptions; - -typedef enum { - INTEREST_OUTPUT = 401, - INTEREST_RETRANSMISSION = 402, - INTEREST_EXPIRED = 403, - INTEREST_SATISFIED = 404, - CONTENT_OBJECT_INPUT = 411, - MANIFEST_INPUT = 412, - CONTENT_OBJECT_TO_VERIFY = 413, - CONTENT_RETRIEVED = 414, -} ConsumerCallbacksOptions; - -typedef enum { - INTEREST_INPUT = 501, - INTEREST_DROP = 502, - INTEREST_PASS = 503, - CACHE_HIT = 506, - CACHE_MISS = 508, - NEW_CONTENT_OBJECT = 509, - CONTENT_OBJECT_SIGN = 513, - CONTENT_OBJECT_READY = 510, - CONTENT_OBJECT_OUTPUT = 511, -} ProducerCallbacksOptions; - -typedef enum { - VIRTUAL_DOWNLOAD = 601, USE_CFG_FILE = 603, -} OtherOptions; - -typedef enum { - SHA_256 = 701, RSA_256 = 702, -} SignatureType; - -} // end namespace icnet - -#endif // ICNET_TRANSPORT_OPTIONS_KEYS_H_ diff --git a/icnet/transport/icnet_socket_producer.cc b/icnet/transport/icnet_socket_producer.cc deleted file mode 100644 index 994488a0..00000000 --- a/icnet/transport/icnet_socket_producer.cc +++ /dev/null @@ -1,720 +0,0 @@ -/* - * Copyright (c) 2017 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 "icnet_socket_producer.h" - -namespace icnet { - -ProducerSocket::ProducerSocket(Name prefix) - : portal_(new Portal()), - name_prefix_(prefix), - data_packet_size_(default_values::content_object_packet_size), - content_object_expiry_time_(default_values::content_object_expiry_time), - registration_status_(REGISTRATION_NOT_ATTEMPTED), - making_manifest_(false), - signature_type_(SHA_256), - key_locator_size_(default_values::key_locator_size), - output_buffer_(default_values::producer_socket_output_buffer_size), - input_buffer_capacity_(default_values::producer_socket_input_buffer_size), - input_buffer_size_(0), - processing_thread_stop_(false), - listening_thread_stop_(false), - on_interest_input_(VOID_HANDLER), - on_interest_dropped_input_buffer_(VOID_HANDLER), - on_interest_inserted_input_buffer_(VOID_HANDLER), - on_interest_satisfied_output_buffer_(VOID_HANDLER), - on_interest_process_(VOID_HANDLER), - on_new_segment_(VOID_HANDLER), - on_content_object_to_sign_(VOID_HANDLER), - on_content_object_in_output_buffer_(VOID_HANDLER), - on_content_object_output_(VOID_HANDLER), - on_content_object_evicted_from_output_buffer_(VOID_HANDLER) { - listening_thread_stop_ = false; - key_locator_size_ = default_values::key_locator_size; -} - -ProducerSocket::~ProducerSocket() { - processing_thread_stop_ = true; - portal_->stopEventsLoop(); - - if (processing_thread_.joinable()) { - processing_thread_.join(); - } - - if (listening_thread_.joinable()) { - listening_thread_.join(); - } -} - -void ProducerSocket::attach() { - listening_thread_ = std::thread(std::bind(&ProducerSocket::listen, this)); - // processing_thread_ = boost::thread(bind(&ProducerTransport::processIncomingInterest, this)); -} - -void ProducerSocket::serveForever() { - if (listening_thread_.joinable()) { - listening_thread_.join(); - } -} - -void ProducerSocket::dispatch() { - // Check that the INTEREST_INPUT callback is set. - if (on_interest_input_ == VOID_HANDLER) { - std::cerr << "Warning: the dispatcher function needs a dispatcher callback! " - "You need to set INTEREST_INPUT callback" << std::endl; - } - - listening_thread_ = std::thread(std::bind(&ProducerSocket::listen, this)); -} - -void ProducerSocket::listen() { - registration_status_ = REGISTRATION_IN_PROGRESS; - - portal_ - ->bind(name_prefix_, std::bind(&ProducerSocket::onInterest, this, std::placeholders::_1, std::placeholders::_2)); - - portal_->runEventsLoop(); -} - -void ProducerSocket::passContentObjectToCallbacks(const std::shared_ptr &content_object) { - if (content_object) { - if (on_new_segment_ != VOID_HANDLER) { - on_new_segment_(*this, *content_object); - } - - if (on_content_object_to_sign_ != VOID_HANDLER) { - if (!making_manifest_) { - on_content_object_to_sign_(*this, *content_object); - } else { - if (content_object->getContentType() == PayloadType::MANIFEST) { - on_content_object_to_sign_(*this, *content_object); - } else { - content_object->signWithSha256(key_locator_); - } - } - } else { - content_object->signWithSha256(key_locator_); - } - - if (on_content_object_in_output_buffer_ != VOID_HANDLER) { - on_content_object_in_output_buffer_(*this, *content_object); - } - - output_buffer_.insert(content_object); - - if (on_content_object_output_ != VOID_HANDLER) { - on_content_object_output_(*this, *content_object); - } - - if (content_object->getName().get(-1).toSegment() == 0) { - portal_->sendContentObject(*content_object); - } - } -} - -void ProducerSocket::produce(ContentObject &content_object) { - if (!name_prefix_.isPrefixOf(content_object.getName())) { - return; - } - - if (on_content_object_in_output_buffer_ != VOID_HANDLER) { - on_content_object_in_output_buffer_(*this, content_object); - } - - if (on_content_object_output_ != VOID_HANDLER) { - on_content_object_output_(*this, content_object); - } - - portal_->sendContentObject(content_object); -} - -void ProducerSocket::produce(Name suffix, const uint8_t *buf, size_t buffer_size, const int response_id, bool is_last) { - - if (buffer_size == 0) { - return; - } - - int bytes_segmented = 0; - - Name name(name_prefix_); - - if (!suffix.empty()) { - name.append(suffix); - } - - size_t bytes_occupied_by_name = name.size(); - - int digestSize = default_values::digest_size; // SHA_256 as default - int signatureSize = default_values::signature_size; - uint64_t free_space_for_content = 0; - - free_space_for_content = data_packet_size_ - bytes_occupied_by_name - digestSize - default_values::limit_guard; - - uint64_t number_of_segments = uint64_t(std::ceil(double(buffer_size) / double(free_space_for_content))); - - if (free_space_for_content * number_of_segments < buffer_size) { - number_of_segments++; - } - - uint64_t current_segment = 0; - - if (seq_number_map_.find(name.toString()) != seq_number_map_.end() - && seq_number_map_[name.toString()].find(response_id) != seq_number_map_[name.toString()].end()) { - current_segment = seq_number_map_[name.toString()][response_id]; - } else { - seq_number_map_[name.toString()][response_id] = current_segment; - } - - if (making_manifest_) { - - std::shared_ptr content_object_segment; - std::shared_ptr manifest_segment; - bool manifest_segment_needed = true; - - uint64_t free_space_for_manifest = - data_packet_size_ - bytes_occupied_by_name - signatureSize - default_values::limit_guard; - - for (unsigned int packaged_segments = 0; packaged_segments < number_of_segments;) { - - if (manifest_segment_needed) { - - Name manifest_name(name_prefix_); - - if (!suffix.empty()) { - manifest_name.append(suffix); - } - - manifest_name.appendSegment(current_segment); - - if (manifest_segment) { - manifest_segment->encode(); - passContentObjectToCallbacks(manifest_segment); - } - - manifest_segment = std::make_shared(manifest_name); - - if (is_last) { - manifest_segment->setFinalChunkNumber(current_segment + number_of_segments - packaged_segments); - } - - // finalSegment = current_segment; - manifest_segment_needed = false; - current_segment++; - - key_locator_.clear(); - key_locator_.setName(const_cast(manifest_segment->getName())); - } - - Name full_name = name; - - content_object_segment = std::make_shared(std::move(full_name.appendSegment(current_segment))); - // content_object_segment->setExpiryTime((uint64_t) m_dataFreshness); - - if (packaged_segments == number_of_segments - 1) { - content_object_segment->setContent(&buf[bytes_segmented], buffer_size - bytes_segmented); - bytes_segmented += buffer_size - bytes_segmented; - } else { - content_object_segment->setContent(&buf[bytes_segmented], free_space_for_content); - bytes_segmented += free_space_for_content; - } - - if (is_last) { - content_object_segment->setFinalChunkNumber(current_segment + number_of_segments - packaged_segments - 1); - } - - passContentObjectToCallbacks(content_object_segment); - - size_t manifestSize = manifest_segment->estimateManifestSize(); - Name &content_object_name = (Name &) content_object_segment->getName(); - size_t fullNameSize = content_object_name.size(); - - // TODO Signature - - if (manifestSize + 2 * fullNameSize > free_space_for_manifest) { - manifest_segment_needed = true; - } - - // TODO Manifest and hashes! - // Array block = content_object_segment->getContent(); - // icn-interface::ConstBufferPtr implicitDigest = icn-interface::crypto::sha256(block.data(), block.size()); - // - // //add implicit digest to the manifest - // manifest_segment->addNameToCatalogue(Name(std::to_string(current_segment)), implicitDigest->buf(), - // implicitDigest->size()); - - packaged_segments++; - current_segment++; - - if (packaged_segments == number_of_segments) { - manifest_segment->encode(); - passContentObjectToCallbacks(manifest_segment); - } - } - } else { - - for (unsigned int packaged_segments = 0; packaged_segments < number_of_segments; packaged_segments++) { - Name fullName = name; - - std::shared_ptr - content_object = std::make_shared(std::move(fullName.appendSegment(current_segment))); - - // TODO If we set the throughput will decrease.. to investigate - // content_object->setExpiryTime((uint64_t)m_dataFreshness); - - if (is_last) { - content_object->setFinalChunkNumber(current_segment + number_of_segments - packaged_segments - 1); - } - - if (packaged_segments == number_of_segments - 1) { - content_object->setContent(&buf[bytes_segmented], buffer_size - bytes_segmented); - bytes_segmented += buffer_size - bytes_segmented; - } else { - content_object->setContent(&buf[bytes_segmented], free_space_for_content); - bytes_segmented += free_space_for_content; - } - - current_segment++; - passContentObjectToCallbacks(content_object); - } - } - - seq_number_map_[name.toString()][response_id] = current_segment; - - if (is_last) { - seq_number_map_[name.toString()].erase(response_id); - if (seq_number_map_[name.toString()].empty()) { - seq_number_map_.erase(name.toString()); - } - } -} - -void ProducerSocket::asyncProduce(ContentObject &content_object) { - std::shared_ptr c_object = std::make_shared(content_object); - std::thread t([c_object, this]() { produce(*c_object); }); - t.detach(); -} - -void ProducerSocket::asyncProduce(Name suffix, - const uint8_t *buf, - size_t buffer_size, - const int response_id, - bool is_last) { - std::thread t([suffix, buf, buffer_size, response_id, is_last, this]() { - produce(suffix, buf, buffer_size, response_id, is_last); - }); - t.detach(); -} - -void ProducerSocket::onInterest(const Name &name, const Interest &interest) { - if (on_interest_input_ != VOID_HANDLER) { - on_interest_input_(*this, interest); - } - - const std::shared_ptr &content_object = output_buffer_.find(interest); - - if (content_object) { - - if (on_interest_satisfied_output_buffer_ != VOID_HANDLER) { - on_interest_satisfied_output_buffer_(*this, interest); - } - - if (on_content_object_output_ != VOID_HANDLER) { - on_content_object_output_(*this, *content_object); - } - - portal_->sendContentObject(*content_object); - } else { - if (on_interest_process_ != VOID_HANDLER) { - on_interest_process_(*this, interest); - } - } -} - -int ProducerSocket::setSocketOption(int socket_option_key, int socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::DATA_PACKET_SIZE: - if (socket_option_value < default_values::max_content_object_size && socket_option_value > 0) { - data_packet_size_ = socket_option_value; - return SOCKET_OPTION_SET; - } else { - return SOCKET_OPTION_NOT_SET; - } - - case GeneralTransportOptions::INPUT_BUFFER_SIZE: - if (socket_option_value >= 1) { - input_buffer_capacity_ = socket_option_value; - return SOCKET_OPTION_SET; - } else { - return SOCKET_OPTION_NOT_SET; - } - - case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: - if (socket_option_value >= 0) { - output_buffer_.setLimit(socket_option_value); - return SOCKET_OPTION_SET; - } else { - return SOCKET_OPTION_NOT_SET; - } - - case GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME: - content_object_expiry_time_ = socket_option_value; - return SOCKET_OPTION_SET; - - case GeneralTransportOptions::SIGNATURE_TYPE: - if (socket_option_value == SOCKET_OPTION_DEFAULT) { - signature_type_ = SHA_256; - } else { - signature_type_ = socket_option_value; - } - - if (signature_type_ == SHA_256 || signature_type_ == RSA_256) { - signature_size_ = 32; - } - - case ProducerCallbacksOptions::INTEREST_INPUT: - if (socket_option_value == VOID_HANDLER) { - on_interest_input_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ProducerCallbacksOptions::INTEREST_DROP: - if (socket_option_value == VOID_HANDLER) { - on_interest_dropped_input_buffer_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ProducerCallbacksOptions::INTEREST_PASS: - if (socket_option_value == VOID_HANDLER) { - on_interest_inserted_input_buffer_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ProducerCallbacksOptions::CACHE_HIT: - if (socket_option_value == VOID_HANDLER) { - on_interest_satisfied_output_buffer_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ProducerCallbacksOptions::CACHE_MISS: - if (socket_option_value == VOID_HANDLER) { - on_interest_process_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ProducerCallbacksOptions::NEW_CONTENT_OBJECT: - if (socket_option_value == VOID_HANDLER) { - on_new_segment_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ProducerCallbacksOptions::CONTENT_OBJECT_SIGN: - if (socket_option_value == VOID_HANDLER) { - on_content_object_to_sign_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ProducerCallbacksOptions::CONTENT_OBJECT_READY: - if (socket_option_value == VOID_HANDLER) { - on_content_object_in_output_buffer_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - case ProducerCallbacksOptions::CONTENT_OBJECT_OUTPUT: - if (socket_option_value == VOID_HANDLER) { - on_content_object_output_ = VOID_HANDLER; - return SOCKET_OPTION_SET; - } - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ProducerSocket::setSocketOption(int socket_option_key, double socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ProducerSocket::setSocketOption(int socket_option_key, bool socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::MAKE_MANIFEST: - making_manifest_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ProducerSocket::setSocketOption(int socket_option_key, Name socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::NAME_PREFIX: - name_prefix_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ProducerSocket::setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value) { - switch (socket_option_key) { - case ProducerCallbacksOptions::NEW_CONTENT_OBJECT: - on_new_segment_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ProducerCallbacksOptions::CONTENT_OBJECT_SIGN: - on_content_object_to_sign_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ProducerCallbacksOptions::CONTENT_OBJECT_READY: - on_content_object_in_output_buffer_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ProducerCallbacksOptions::CONTENT_OBJECT_OUTPUT: - on_content_object_output_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ProducerSocket::setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value) { - switch (socket_option_key) { - case ProducerCallbacksOptions::INTEREST_INPUT: - on_interest_input_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ProducerCallbacksOptions::INTEREST_DROP: - on_interest_dropped_input_buffer_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ProducerCallbacksOptions::INTEREST_PASS: - on_interest_inserted_input_buffer_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ProducerCallbacksOptions::CACHE_HIT: - on_interest_satisfied_output_buffer_ = socket_option_value; - return SOCKET_OPTION_SET; - - case ProducerCallbacksOptions::CACHE_MISS: - on_interest_process_ = socket_option_value; - return SOCKET_OPTION_SET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ProducerSocket::setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ProducerSocket::setSocketOption(int socket_option_key, - ConsumerContentObjectVerificationCallback socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ProducerSocket::setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ProducerSocket::setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ProducerSocket::setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ProducerSocket::setSocketOption(int socket_option_key, KeyLocator socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -int ProducerSocket::getSocketOption(int socket_option_key, int &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::INPUT_BUFFER_SIZE: - socket_option_value = input_buffer_capacity_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: - socket_option_value = output_buffer_.getLimit(); - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::DATA_PACKET_SIZE: - socket_option_value = data_packet_size_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME: - socket_option_value = content_object_expiry_time_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::SIGNATURE_TYPE: - socket_option_value = signature_type_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ProducerSocket::getSocketOption(int socket_option_key, double &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::getSocketOption(int socket_option_key, bool &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::MAKE_MANIFEST: - socket_option_value = making_manifest_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ProducerSocket::getSocketOption(int socket_option_key, Name &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::NAME_PREFIX: - socket_option_value = name_prefix_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ProducerSocket::getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value) { - switch (socket_option_key) { - case ProducerCallbacksOptions::NEW_CONTENT_OBJECT: - socket_option_value = on_new_segment_; - return SOCKET_OPTION_GET; - - case ProducerCallbacksOptions::CONTENT_OBJECT_SIGN: - socket_option_value = on_content_object_to_sign_; - return SOCKET_OPTION_GET; - - case ProducerCallbacksOptions::CONTENT_OBJECT_READY: - socket_option_value = on_content_object_in_output_buffer_; - return SOCKET_OPTION_GET; - - case ProducerCallbacksOptions::CONTENT_OBJECT_OUTPUT: - socket_option_value = on_content_object_output_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ProducerSocket::getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value) { - switch (socket_option_key) { - case ProducerCallbacksOptions::INTEREST_INPUT: - socket_option_value = on_interest_input_; - return SOCKET_OPTION_GET; - - case ProducerCallbacksOptions::INTEREST_DROP: - socket_option_value = on_interest_dropped_input_buffer_; - return SOCKET_OPTION_GET; - - case ProducerCallbacksOptions::INTEREST_PASS: - socket_option_value = on_interest_inserted_input_buffer_; - return SOCKET_OPTION_GET; - - case CACHE_HIT: - socket_option_value = on_interest_satisfied_output_buffer_; - return SOCKET_OPTION_GET; - - case CACHE_MISS: - socket_option_value = on_interest_process_; - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ProducerSocket::getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::getSocketOption(int socket_option_key, - ConsumerContentObjectVerificationCallback &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::setSocketOption(int socket_option_key, size_t socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::INPUT_BUFFER_SIZE: - if (input_buffer_capacity_ >= 1) { - input_buffer_capacity_ = socket_option_value; - return SOCKET_OPTION_SET; - } - - default: - return SOCKET_OPTION_NOT_SET; - } -} - -int ProducerSocket::getSocketOption(int socket_option_key, size_t &socket_option_value) { - switch (socket_option_key) { - case GeneralTransportOptions::INPUT_BUFFER_SIZE: - socket_option_value = input_buffer_capacity_; - return SOCKET_OPTION_GET; - - case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: - socket_option_value = output_buffer_.size(); - return SOCKET_OPTION_GET; - - default: - return SOCKET_OPTION_NOT_GET; - } -} - -int ProducerSocket::getSocketOption(int socket_option_key, KeyLocator &socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value) { - switch (socket_option_key) { - case PORTAL: - socket_option_value = portal_; - return SOCKET_OPTION_GET; - } - - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::getSocketOption(int socket_option_key, IcnObserver **socket_option_value) { - return SOCKET_OPTION_NOT_GET; -} - -int ProducerSocket::setSocketOption(int socket_option_key, IcnObserver *socket_option_value) { - return SOCKET_OPTION_NOT_SET; -} - -} // end namespace icnet diff --git a/icnet/transport/icnet_socket_producer.h b/icnet/transport/icnet_socket_producer.h deleted file mode 100644 index d709e305..00000000 --- a/icnet/transport/icnet_socket_producer.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_PRODUCER_SOCKET_H_ -#define ICNET_PRODUCER_SOCKET_H_ - -#include "icnet_socket.h" -#include "icnet_content_store.h" - -#include -#include -#include -#include - -#define REGISTRATION_NOT_ATTEMPTED 0 -#define REGISTRATION_SUCCESS 1 -#define REGISTRATION_FAILURE 2 -#define REGISTRATION_IN_PROGRESS 3 - -namespace icnet { - -class ProducerSocket : public Socket { - public: - - explicit ProducerSocket(Name prefix); - - ~ProducerSocket(); - - void attach(); - - void dispatch(); - - void produce(Name suffix, const uint8_t *buffer, size_t buffer_size, const int request_id = 0, bool is_last = false); - - void produce(ContentObject &content_object); - - void asyncProduce(Name suffix, const uint8_t *buf, size_t buffer_size, const int response_id, bool is_last); - - void asyncProduce(ContentObject &content_object); - - void serveForever(); - - void onInterest(const Name &name, const Interest &interest); - - int setSocketOption(int socket_option_key, int socket_option_value); - - int setSocketOption(int socket_option_key, double socket_option_value); - - int setSocketOption(int socket_option_key, bool socket_option_value); - - int setSocketOption(int socket_option_key, size_t socket_option_value); - - int setSocketOption(int socket_option_key, Name socket_option_value); - - int setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value); - - int setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value); - - int setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value); - - int setSocketOption(int socket_option_key, KeyLocator socket_option_value); - - int setSocketOption(int socket_option_key, IcnObserver *obs); - - int getSocketOption(int socket_option_key, int &socket_option_value); - - int getSocketOption(int socket_option_key, double &socket_option_value); - - int getSocketOption(int socket_option_key, bool &socket_option_value); - - int getSocketOption(int socket_option_key, size_t &socket_option_value); - - int getSocketOption(int socket_option_key, Name &socket_option_value); - - int getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value); - - int getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value); - - int getSocketOption(int socket_option_key, KeyLocator &socket_option_value); - - int getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value); - - int getSocketOption(int socket_option_key, IcnObserver **socket_option_value); - - private: - - std::shared_ptr portal_; - boost::asio::io_service io_service_; - - Name name_prefix_; - - int data_packet_size_; - int content_object_expiry_time_; - int registration_status_; - - bool making_manifest_; - - // map for storing sequence numbers for several calls of the publish function - std::unordered_map> seq_number_map_; - - int signature_type_; - int signature_size_; - int key_locator_size_; - KeyLocator key_locator_; - - // buffers - ContentStore output_buffer_; - - std::queue > input_buffer_; - std::mutex input_buffer_mutex_; - std::atomic_size_t input_buffer_capacity_; - std::atomic_size_t input_buffer_size_; - - // threads - std::thread listening_thread_; - std::thread processing_thread_; - volatile bool processing_thread_stop_; - volatile bool listening_thread_stop_; - - // callbacks - ProducerInterestCallback on_interest_input_; - ProducerInterestCallback on_interest_dropped_input_buffer_; - ProducerInterestCallback on_interest_inserted_input_buffer_; - ProducerInterestCallback on_interest_satisfied_output_buffer_; - ProducerInterestCallback on_interest_process_; - - ProducerContentObjectCallback on_new_segment_; - ProducerContentObjectCallback on_content_object_to_sign_; - ProducerContentObjectCallback on_content_object_in_output_buffer_; - ProducerContentObjectCallback on_content_object_output_; - ProducerContentObjectCallback on_content_object_evicted_from_output_buffer_; - - private: - void listen(); - - void passContentObjectToCallbacks(const std::shared_ptr &content_object); - -}; - -} - -#endif // ICNET_PRODUCER_SOCKET_H_ diff --git a/icnet/transport/icnet_transport.cc b/icnet/transport/icnet_transport.cc deleted file mode 100644 index 632d03c4..00000000 --- a/icnet/transport/icnet_transport.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2017 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 "icnet_transport.h" - -namespace icnet { - -TransportProtocol::TransportProtocol(Socket *icn_socket) - : socket_(icn_socket), is_running_(false) { -} - -void TransportProtocol::updatePortal() { - socket_->getSocketOption(PORTAL, portal_); -} - -bool TransportProtocol::isRunning() { - return is_running_; -} - -} // end namespace icnet diff --git a/icnet/transport/icnet_transport.h b/icnet/transport/icnet_transport.h deleted file mode 100644 index 738634fb..00000000 --- a/icnet/transport/icnet_transport.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 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 ICNET_TRANSPORT_PROTOCOL_H_ -#define ICNET_TRANSPORT_PROTOCOL_H_ - -#include "icnet_socket.h" - -namespace icnet { - -class TransportProtocol { - public: - TransportProtocol(Socket *icn_socket); - - void updatePortal(); - - bool isRunning(); - - virtual void start() = 0; - - virtual void stop() = 0; - - protected: - Socket *socket_; - std::shared_ptr portal_; - bool is_running_; -}; - -} - -#endif // ICNET_TRANSPORT_PROTOCOL_H_ diff --git a/icnet/transport/icnet_transport_common.h b/icnet/transport/icnet_transport_common.h new file mode 100644 index 00000000..d507b324 --- /dev/null +++ b/icnet/transport/icnet_transport_common.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 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 ICNET_COMMON_H_ +#define ICNET_COMMON_H_ + +// require C++11 +#if __cplusplus < 201103L && !defined(__GXX_EXPERIMENTAL_CXX0X__) +#error "icnet needs to be compiled using the C++11 standard" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.hpp" +#include "icnet_ccnx_facade.h" + +#if defined(__GNUC__) || defined(__clang__) +# define DEPRECATED(func) func __attribute__ ((deprecated)) +#elif defined(_MSC_VER) +# define DEPRECATED(func) __declspec(deprecated) func +#else +# pragma message("DEPRECATED not implemented") +# define DEPRECATED(func) func +#endif + +#endif // ICNET_COMMON_H_ diff --git a/icnet/transport/icnet_transport_content_store.cc b/icnet/transport/icnet_transport_content_store.cc new file mode 100644 index 00000000..a9f05658 --- /dev/null +++ b/icnet/transport/icnet_transport_content_store.cc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017 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 "icnet_transport_content_store.h" + +namespace icnet { + +namespace transport { + +ContentStore::ContentStore(std::size_t max_packets) + : max_content_store_size_(max_packets) { +} + +ContentStore::~ContentStore() { + content_store_hash_table_.clear(); +} + +void ContentStore::insert(const std::shared_ptr &content_object) { + std::unique_lock lock(cs_mutex_); + if (content_store_hash_table_.size() >= max_content_store_size_) { + // Evict item + content_store_hash_table_.erase(lru_list_.back()); + lru_list_.pop_back(); + } + + // Insert new item + lru_list_.push_back(std::cref(content_object->getName())); + LRUList::iterator pos = lru_list_.end(); + content_store_hash_table_[content_object->getName()] = CcnxContentStoreEntry(content_object, pos); + +} + +const std::shared_ptr &ContentStore::find(const Interest &interest) { + std::unique_lock lock(cs_mutex_); + ContentStoreHashTable::iterator it = content_store_hash_table_.find(interest.getName()); + if (it != content_store_hash_table_.end()) { + if (it->second.second != lru_list_.begin()) { + // Move element to the top of the LRU list + lru_list_.splice(lru_list_.begin(), lru_list_, it->second.second); + } + return it->second.first; + } else { + return empty_reference_; + } +} + +void ContentStore::erase(const Name &exact_name) { + std::unique_lock lock(cs_mutex_); + ContentStoreHashTable::iterator it = content_store_hash_table_.find(exact_name); + lru_list_.erase(it->second.second); + content_store_hash_table_.erase(exact_name); +} + +void ContentStore::setLimit(size_t max_packets) { + max_content_store_size_ = max_packets; +} + +std::size_t ContentStore::getLimit() const { + return max_content_store_size_; +} + +std::size_t ContentStore::size() const { + return content_store_hash_table_.size(); +} + +} + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/transport/icnet_transport_content_store.h b/icnet/transport/icnet_transport_content_store.h new file mode 100644 index 00000000..8a2ed4c6 --- /dev/null +++ b/icnet/transport/icnet_transport_content_store.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017 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 ICNET_CONTENT_STORE_H_ +#define ICNET_CONTENT_STORE_H_ + +#include "icnet_transport_socket.h" + +#include + +namespace icnet { + +namespace transport { + +typedef std::pair, std::list>::iterator> + CcnxContentStoreEntry; +typedef std::list> LRUList; +typedef std::unordered_map ContentStoreHashTable; + +class ContentStore { + public: + + explicit ContentStore(std::size_t max_packets = 65536); + + ~ContentStore(); + + void insert(const std::shared_ptr &content_object); + + const std::shared_ptr &find(const Interest &interest); + + void erase(const Name &exact_name); + + void setLimit(size_t max_packets); + + size_t getLimit() const; + + size_t size() const; + + private: + ContentStoreHashTable content_store_hash_table_; + LRUList lru_list_; + std::shared_ptr empty_reference_; + std::size_t max_content_store_size_; + std::mutex cs_mutex_; +}; + +} // end namespace transport + +} // end namespace icnet + + +#endif // ICNET_CONTENT_STORE_H_ diff --git a/icnet/transport/icnet_transport_download_observer.h b/icnet/transport/icnet_transport_download_observer.h new file mode 100644 index 00000000..15ed5436 --- /dev/null +++ b/icnet/transport/icnet_transport_download_observer.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 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 ICNET_DOWNLOAD_OBSERVER_H_ +#define ICNET_DOWNLOAD_OBSERVER_H_ + +namespace icnet { + +namespace transport { + +class IcnObserver { + public: + virtual ~IcnObserver() { + }; + + virtual void notifyStats(double throughput) = 0; +}; + +} // end namespace transport + +} // end namespace icnet + +#endif // ICNET_DOWNLOAD_OBSERVER_H_ + diff --git a/icnet/transport/icnet_transport_protocol.cc b/icnet/transport/icnet_transport_protocol.cc new file mode 100644 index 00000000..71b855eb --- /dev/null +++ b/icnet/transport/icnet_transport_protocol.cc @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 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 "icnet_transport_protocol.h" + +namespace icnet { + +namespace transport { + +TransportProtocol::TransportProtocol(Socket *icn_socket) + : socket_(icn_socket), is_running_(false) { +} + +void TransportProtocol::updatePortal() { + socket_->getSocketOption(PORTAL, portal_); +} + +bool TransportProtocol::isRunning() { + return is_running_; +} + +} // end namespace transport + +} // end namespace icnet diff --git a/icnet/transport/icnet_transport_protocol.h b/icnet/transport/icnet_transport_protocol.h new file mode 100644 index 00000000..5ad43fb5 --- /dev/null +++ b/icnet/transport/icnet_transport_protocol.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 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 ICNET_TRANSPORT_PROTOCOL_H_ +#define ICNET_TRANSPORT_PROTOCOL_H_ + +#include "icnet_transport_socket.h" + +namespace icnet { + +namespace transport { + +class TransportProtocol { + public: + TransportProtocol(Socket *icn_socket); + + void updatePortal(); + + bool isRunning(); + + virtual void start() = 0; + + virtual void stop() = 0; + + protected: + Socket *socket_; + std::shared_ptr portal_; + bool is_running_; +}; + +} // end namespace transport + +} // end namespace icnet + +#endif // ICNET_TRANSPORT_PROTOCOL_H_ diff --git a/icnet/transport/icnet_transport_raaqm.cc b/icnet/transport/icnet_transport_raaqm.cc index 7216d29e..787631f4 100644 --- a/icnet/transport/icnet_transport_raaqm.cc +++ b/icnet/transport/icnet_transport_raaqm.cc @@ -21,6 +21,8 @@ namespace icnet { +namespace transport { + RaaqmTransportProtocol::RaaqmTransportProtocol(Socket *icnet_socket) : VegasTransportProtocol(icnet_socket), rate_estimator_(NULL) { init(); @@ -560,4 +562,6 @@ RaaqmTransportProtocol::onInterest(const Interest &interest) } #endif +} // end namespace transport + } // end namespace icnet diff --git a/icnet/transport/icnet_transport_raaqm.h b/icnet/transport/icnet_transport_raaqm.h index dc5e72bd..adf3d439 100644 --- a/icnet/transport/icnet_transport_raaqm.h +++ b/icnet/transport/icnet_transport_raaqm.h @@ -19,10 +19,12 @@ #include "icnet_transport_vegas.h" #include "icnet_transport_vegas_rto_estimator.h" #include "icnet_transport_raaqm_data_path.h" -#include "icnet_rate_estimation.h" +#include "icnet_transport_rate_estimation.h" namespace icnet { +namespace transport { + class RaaqmTransportProtocol : public VegasTransportProtocol { public: RaaqmTransportProtocol(Socket *icnet_socket); @@ -95,6 +97,8 @@ class RaaqmTransportProtocol : public VegasTransportProtocol { double avg_rtt_; }; +} // end namespace transport + } // end namespace icnet #endif // ICNET_RAAQM_TRANSPORT_PROTOCOL_H_ diff --git a/icnet/transport/icnet_transport_raaqm_data_path.cc b/icnet/transport/icnet_transport_raaqm_data_path.cc index 1ff3f667..abe8db6c 100644 --- a/icnet/transport/icnet_transport_raaqm_data_path.cc +++ b/icnet/transport/icnet_transport_raaqm_data_path.cc @@ -20,6 +20,8 @@ namespace icnet { +namespace transport { + RaaqmDataPath::RaaqmDataPath(double drop_factor, double minimum_drop_probability, unsigned new_timer, @@ -209,4 +211,6 @@ bool RaaqmDataPath::isStale() { return false; } +} // end namespace transport + } // end namespace icnet diff --git a/icnet/transport/icnet_transport_raaqm_data_path.h b/icnet/transport/icnet_transport_raaqm_data_path.h index 0093f84b..526c0231 100644 --- a/icnet/transport/icnet_transport_raaqm_data_path.h +++ b/icnet/transport/icnet_transport_raaqm_data_path.h @@ -31,6 +31,8 @@ namespace icnet { +namespace transport { + class RaaqmDataPath { public: @@ -237,6 +239,8 @@ class RaaqmDataPath { double alpha_; }; +} // end namespace transport + } // end namespace icnet #endif // ICNET_RAAQM_DATA_PATH_H_ diff --git a/icnet/transport/icnet_transport_rate_estimation.cc b/icnet/transport/icnet_transport_rate_estimation.cc new file mode 100644 index 00000000..79b5b3e2 --- /dev/null +++ b/icnet/transport/icnet_transport_rate_estimation.cc @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2017 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 "icnet_transport_rate_estimation.h" + +namespace icnet { + +namespace transport { + +void *Timer(void *data) { + InterRttEstimator *estimator = (InterRttEstimator *) data; + + double dat_rtt, my_avg_win, my_avg_rtt; + int my_win_change, number_of_packets, max_packet_size; + + pthread_mutex_lock(&(estimator->mutex_)); + dat_rtt = estimator->rtt_; + pthread_mutex_unlock(&(estimator->mutex_)); + + while (estimator->is_running_) { + usleep(KV * dat_rtt); + + pthread_mutex_lock(&(estimator->mutex_)); + + dat_rtt = estimator->rtt_; + my_avg_win = estimator->avg_win_; + my_avg_rtt = estimator->avg_rtt_; + my_win_change = estimator->win_change_; + number_of_packets = estimator->number_of_packets_; + max_packet_size = estimator->max_packet_size_; + estimator->avg_rtt_ = estimator->rtt_; + estimator->avg_win_ = 0; + estimator->win_change_ = 0; + estimator->number_of_packets_ = 1; + + pthread_mutex_unlock(&(estimator->mutex_)); + + if (number_of_packets == 0 || my_win_change == 0) { + continue; + } + if (estimator->estimation_ == 0) { + estimator->estimation_ = (my_avg_win * 8.0 * max_packet_size * 1000000.0 / (1.0 * my_win_change)) + / (my_avg_rtt / (1.0 * number_of_packets)); + } + + estimator->estimation_ = estimator->alpha_ * estimator->estimation_ + (1 - estimator->alpha_) + * ((my_avg_win * 8.0 * max_packet_size * 1000000.0 / (1.0 * my_win_change)) + / (my_avg_rtt / (1.0 * number_of_packets))); + + if (estimator->observer_) { + estimator->observer_->notifyStats(estimator->estimation_); + } + } + + return nullptr; +} + +InterRttEstimator::InterRttEstimator(double alpha_arg) { + this->estimated_ = false; + this->observer_ = NULL; + this->alpha_ = alpha_arg; + this->thread_is_running_ = false; + this->my_th_ = NULL; + this->is_running_ = true; + this->avg_rtt_ = 0.0; + this->estimation_ = 0.0; + this->avg_win_ = 0.0; + this->rtt_ = 0.0; + this->win_change_ = 0; + this->number_of_packets_ = 0; + this->max_packet_size_ = 0; + this->win_current_ = 1.0; + + pthread_mutex_init(&(this->mutex_), NULL); + gettimeofday(&(this->begin_), 0); +} + +InterRttEstimator::~InterRttEstimator() { + this->is_running_ = false; + if (this->my_th_) { + pthread_join(*(this->my_th_), NULL); + } + this->my_th_ = NULL; + pthread_mutex_destroy(&(this->mutex_)); +} + +void InterRttEstimator::onRttUpdate(double rtt) { + pthread_mutex_lock(&(this->mutex_)); + this->rtt_ = rtt; + this->number_of_packets_++; + this->avg_rtt_ += rtt; + pthread_mutex_unlock(&(this->mutex_)); + + if (!thread_is_running_) { + my_th_ = (pthread_t *) malloc(sizeof(pthread_t)); + if (!my_th_) { + std::cerr << "Error allocating thread." << std::endl; + my_th_ = NULL; + } + if (/*int err = */pthread_create(my_th_, NULL, Timer, (void *) this)) { + std::cerr << "Error creating the thread" << std::endl; + my_th_ = NULL; + } + thread_is_running_ = true; + } +} + +void InterRttEstimator::onWindowIncrease(double win_current) { + timeval end; + gettimeofday(&end, 0); + double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); + + pthread_mutex_lock(&(this->mutex_)); + this->avg_win_ += this->win_current_ * delay; + this->win_current_ = win_current; + this->win_change_ += delay; + pthread_mutex_unlock(&(this->mutex_)); + + gettimeofday(&(this->begin_), 0); +} + +void InterRttEstimator::onWindowDecrease(double win_current) { + timeval end; + gettimeofday(&end, 0); + double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); + + pthread_mutex_lock(&(this->mutex_)); + this->avg_win_ += this->win_current_ * delay; + this->win_current_ = win_current; + this->win_change_ += delay; + pthread_mutex_unlock(&(this->mutex_)); + + gettimeofday(&(this->begin_), 0); +} + +ALaTcpEstimator::ALaTcpEstimator() { + this->estimation_ = 0.0; + this->observer_ = NULL; + gettimeofday(&(this->begin_), 0); + this->totalSize_ = 0.0; +} + +void ALaTcpEstimator::onStart() { + this->totalSize_ = 0.0; + gettimeofday(&(this->begin_), 0); +} + +void ALaTcpEstimator::onDownloadFinished() { + timeval end; + gettimeofday(&end, 0); + double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); + this->estimation_ = this->totalSize_ * 8 * 1000000 / delay; + if (observer_) { + observer_->notifyStats(this->estimation_); + } +} + +void ALaTcpEstimator::onDataReceived(int packet_size) { + this->totalSize_ += packet_size; +} + +SimpleEstimator::SimpleEstimator(double alphaArg, int batching_param) { + this->estimation_ = 0.0; + this->estimated_ = false; + this->observer_ = NULL; + this->batching_param_ = batching_param; + this->total_size_ = 0.0; + this->number_of_packets_ = 0; + this->base_alpha_ = alphaArg; + this->alpha_ = alphaArg; + gettimeofday(&(this->begin_), 0); +} + +void SimpleEstimator::onStart() { + this->estimated_ = false; + this->number_of_packets_ = 0; + this->total_size_ = 0.0; + gettimeofday(&(this->begin_), 0); +} + +void SimpleEstimator::onDownloadFinished() { + if (!this->estimated_) { + timeval end; + gettimeofday(&end, 0); + double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); + + //Assuming all packets carry max_packet_size_ bytes of data (8*max_packet_size_ bits); 1000000 factor to convert us to seconds + if (this->estimation_) { + this->estimation_ = alpha_ * this->estimation_ + (1 - alpha_) * (total_size_ * 8 * 1000000.0 / (delay)); + } else { + this->estimation_ = total_size_ * 8 * 1000000.0 / (delay); + } + if (observer_) { + observer_->notifyStats(this->estimation_); + } + this->alpha_ = this->base_alpha_ * (((double) this->number_of_packets_) / ((double) this->batching_param_)); + this->number_of_packets_ = 0; + this->total_size_ = 0.0; + gettimeofday(&(this->begin_), 0); + } else { + if (this->number_of_packets_ >= (int) (75.0 * (double) this->batching_param_ / 100.0)) { + timeval end; + gettimeofday(&end, 0); + double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); + + //Assuming all packets carry max_packet_size_ bytes of data (8*max_packet_size_ bits); 1000000 factor to convert us to seconds + if (this->estimation_) { + this->estimation_ = alpha_ * this->estimation_ + (1 - alpha_) * (total_size_ * 8 * 1000000.0 / (delay)); + } else { + this->estimation_ = total_size_ * 8 * 1000000.0 / (delay); + } + if (observer_) { + observer_->notifyStats(this->estimation_); + } + this->alpha_ = this->base_alpha_ * (((double) this->number_of_packets_) / ((double) this->batching_param_)); + this->number_of_packets_ = 0; + this->total_size_ = 0.0; + + gettimeofday(&(this->begin_), 0); + + } + } +} + +void SimpleEstimator::onDataReceived(int packet_size) { + this->total_size_ += packet_size; +} + +void SimpleEstimator::onRttUpdate(double rtt) { + this->number_of_packets_++; + + if (number_of_packets_ == this->batching_param_) { + timeval end; + gettimeofday(&end, 0); + double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); + //Assuming all packets carry max_packet_size_ bytes of data (8*max_packet_size_ bits); 1000000 factor to convert us to seconds + if (this->estimation_) { + this->estimation_ = alpha_ * this->estimation_ + (1 - alpha_) * (total_size_ * 8 * 1000000.0 / (delay)); + } else { + this->estimation_ = total_size_ * 8 * 1000000.0 / (delay); + } + if (observer_) { + observer_->notifyStats(this->estimation_); + } + this->alpha_ = this->base_alpha_; + this->number_of_packets_ = 0; + this->total_size_ = 0.0; + gettimeofday(&(this->begin_), 0); + } +} + +BatchingPacketsEstimator::BatchingPacketsEstimator(double alpha_arg, int param) { + this->estimated_ = false; + this->observer_ = NULL; + this->alpha_ = alpha_arg; + this->batching_param_ = param; + this->number_of_packets_ = 0; + this->avg_win_ = 0.0; + this->avg_rtt_ = 0.0; + this->win_change_ = 0.0; + this->max_packet_size_ = 0; + this->estimation_ = 0.0; + this->win_current_ = 1.0; + gettimeofday(&(this->begin_), 0); +} + +void BatchingPacketsEstimator::onRttUpdate(double rtt) { + this->number_of_packets_++; + this->avg_rtt_ += rtt; + + if (number_of_packets_ == this->batching_param_) { + if (estimation_ == 0) { + estimation_ = (avg_win_ * 8.0 * max_packet_size_ * 1000000.0 / (1.0 * win_change_)) + / (avg_rtt_ / (1.0 * number_of_packets_)); + } else { + estimation_ = alpha_ * estimation_ + (1 - alpha_) + * ((avg_win_ * 8.0 * max_packet_size_ * 1000000.0 / (1.0 * win_change_)) + / (avg_rtt_ / (1.0 * number_of_packets_))); + } + + if (observer_) { + observer_->notifyStats(estimation_); + } + + this->number_of_packets_ = 0; + this->avg_win_ = 0.0; + this->avg_rtt_ = 0.0; + this->win_change_ = 0.0; + } +} + +void BatchingPacketsEstimator::onWindowIncrease(double win_current) { + timeval end; + gettimeofday(&end, 0); + double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); + this->avg_win_ += this->win_current_ * delay; + this->win_current_ = win_current; + this->win_change_ += delay; + gettimeofday(&(this->begin_), 0); +} + +void BatchingPacketsEstimator::onWindowDecrease(double win_current) { + timeval end; + gettimeofday(&end, 0); + double delay = RaaqmDataPath::getMicroSeconds(end) - RaaqmDataPath::getMicroSeconds(this->begin_); + this->avg_win_ += this->win_current_ * delay; + this->win_current_ = win_current; + this->win_change_ += delay; + gettimeofday(&(this->begin_), 0); +} + +} // end namespace transport + +} // end namespace icnet + diff --git a/icnet/transport/icnet_transport_rate_estimation.h b/icnet/transport/icnet_transport_rate_estimation.h new file mode 100644 index 00000000..7916ccfa --- /dev/null +++ b/icnet/transport/icnet_transport_rate_estimation.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2017 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 ICNET_RATE_ESTIMATION_H_ +#define ICNET_RATE_ESTIMATION_H_ + +#include + +#include "icnet_transport_raaqm_data_path.h" +#include "icnet_transport_download_observer.h" + +#define BATCH 50 +#define KV 20 +#define ALPHA 0.8 +#define RATE_CHOICE 0 + +namespace icnet { + +namespace transport { + +class IcnRateEstimator { + public: + IcnRateEstimator() { + }; + + virtual ~IcnRateEstimator() { + }; + + virtual void onRttUpdate(double rtt) { + }; + + virtual void onDataReceived(int packetSize) { + }; + + virtual void onWindowIncrease(double winCurrent) { + }; + + virtual void onWindowDecrease(double winCurrent) { + }; + + virtual void onStart() { + }; + + virtual void onDownloadFinished() { + }; + + virtual void setObserver(IcnObserver *observer) { + this->observer_ = observer; + }; + IcnObserver *observer_; + struct timeval begin_; + double base_alpha_; + double alpha_; + double estimation_; + int number_of_packets_; + // this boolean is to make sure at least one estimation of the BW is done + bool estimated_; +}; + +// A rate estimator RTT-based. Computes EWMA(WinSize)/EWMA(RTT) + +class InterRttEstimator : public IcnRateEstimator { + public: + InterRttEstimator(double alpha_arg); + + ~InterRttEstimator(); + + void onRttUpdate(double rtt); + + void onDataReceived(int packet_size) { + if (packet_size > this->max_packet_size_) { + this->max_packet_size_ = packet_size; + } + }; + + void onWindowIncrease(double win_current); + + void onWindowDecrease(double win_current); + + void onStart() { + }; + + void onDownloadFinished() { + }; + + // private: should be done by using getters + pthread_t *my_th_; + bool thread_is_running_; + double rtt_; + bool is_running_; + pthread_mutex_t mutex_; + double avg_rtt_; + double avg_win_; + int max_packet_size_; + double win_change_; + double win_current_; +}; + +// A rate estimator, Batching Packets based. Computes EWMA(WinSize)/EWMA(RTT) + +class BatchingPacketsEstimator : public IcnRateEstimator { + public: + BatchingPacketsEstimator(double alpha_arg, int batchingParam); + + void onRttUpdate(double rtt); + + void onDataReceived(int packet_size) { + if (packet_size > this->max_packet_size_) { + this->max_packet_size_ = packet_size; + } + }; + + void onWindowIncrease(double win_current); + + void onWindowDecrease(double win_current); + + void onStart() { + }; + + void onDownloadFinished() { + }; + + private: + int batching_param_; + double avg_rtt_; + double avg_win_; + double win_change_; + int max_packet_size_; + double win_current_; +}; + +//Segment Estimator + +class ALaTcpEstimator : public IcnRateEstimator { + public: + ALaTcpEstimator(); + + void onDataReceived(int packet_size); + void onStart(); + void onDownloadFinished(); + + private: + double totalSize_; +}; + +// A Rate estimator, this one is the simplest: counting batching_param_ packets and then divide the sum of the size of these packets by the time taken to DL them. +// Should be the one used + +class SimpleEstimator : public IcnRateEstimator { + public: + SimpleEstimator(double alpha, int batching_param); + + void onRttUpdate(double rtt); + + void onDataReceived(int packet_size); + + void onWindowIncrease(double win_current) { + }; + + void onWindowDecrease(double win_current) { + }; + + void onStart(); + + void onDownloadFinished(); + + private: + int batching_param_; + double total_size_; +}; + +void *Timer(void *data); + +} // end namespace transport + +} // end namespace icnet + +#endif // ICNET_RATE_ESTIMATION_H_ + diff --git a/icnet/transport/icnet_transport_socket.h b/icnet/transport/icnet_transport_socket.h new file mode 100644 index 00000000..edfdf1e8 --- /dev/null +++ b/icnet/transport/icnet_transport_socket.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2017 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 ICNET_SOCKET_H_ +#define ICNET_SOCKET_H_ + +#include "icnet_transport_common.h" +#include "icnet_transport_socket_options_keys.h" +#include "icnet_transport_socket_options_default_values.h" +#include "icnet_transport_download_observer.h" + +#define SOCKET_OPTION_GET 0 +#define SOCKET_OPTION_NOT_GET 1 +#define SOCKET_OPTION_SET 2 +#define SOCKET_OPTION_NOT_SET 3 +#define SOCKET_OPTION_DEFAULT 12345 + +#define VOID_HANDLER 0 + +namespace icnet { + +namespace transport { + +class ConsumerSocket; +class ProducerSocket; + +typedef ccnx::Interest Interest; +typedef ccnx::ContentObject ContentObject; +typedef ccnx::Name Name; +typedef ccnx::Manifest Manifest; +typedef ccnx::Portal Portal; +typedef ccnx::KeyLocator KeyLocator; +typedef ccnx::Segment Segment; +typedef ccnx::PayloadType PayloadType; +typedef ccnx::Array Array; + +typedef std::function ConsumerInterestCallback; +typedef std::function &&)> ConsumerContentCallback; +typedef std::function ConsumerContentObjectCallback; +typedef std::function ConsumerContentObjectVerificationCallback; +typedef std::function ConsumerManifestCallback; +typedef std::function ProducerContentObjectCallback; +typedef std::function ProducerInterestCallback; + +class Socket { + public: + + virtual int setSocketOption(int socket_option_key, int socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, double socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, size_t socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, bool socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, Name socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, KeyLocator socket_option_value) = 0; + + virtual int setSocketOption(int socket_option_key, IcnObserver *socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, int &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, double &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, size_t &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, bool &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, Name &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, + ConsumerContentObjectVerificationCallback &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, KeyLocator &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value) = 0; + + virtual int getSocketOption(int socket_option_key, IcnObserver **socket_option_value) = 0; + + protected: + virtual ~Socket() { + }; +}; + +} // end namespace transport + +} // namespace icnet + +#endif // ICNET_SOCKET_H_ diff --git a/icnet/transport/icnet_transport_socket_consumer.cc b/icnet/transport/icnet_transport_socket_consumer.cc new file mode 100644 index 00000000..21fa7327 --- /dev/null +++ b/icnet/transport/icnet_transport_socket_consumer.cc @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2017 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 "icnet_transport_socket_consumer.h" + +namespace icnet { + +namespace transport { + +ConsumerSocket::ConsumerSocket(Name prefix, int protocol) + : is_running_(false), + name_prefix_(prefix), + interest_lifetime_(default_values::interest_lifetime), + min_window_size_(default_values::min_window_size), + max_window_size_(default_values::max_window_size), + current_window_size_(-1), + max_retransmissions_(default_values::transport_protocol_max_retransmissions), + /****** RAAQM Parameters ******/ + minimum_drop_probability_(default_values::minimum_drop_probability), + sample_number_(default_values::sample_number), + gamma_(default_values::gamma_value), + beta_(default_values::beta_value), + drop_factor_(default_values::drop_factor), + /****** END RAAQM Parameters ******/ + rate_estimation_alpha_(default_values::rate_alpha), + rate_estimation_observer_(NULL), + is_async_(false), + on_interest_output_(VOID_HANDLER), + on_interest_timeout_(VOID_HANDLER), + on_interest_satisfied_(VOID_HANDLER), + on_content_object_input_(VOID_HANDLER), + on_content_object_verification_(VOID_HANDLER), + on_content_object_(VOID_HANDLER), + on_manifest_(VOID_HANDLER), + on_payload_retrieved_(VOID_HANDLER), + virtual_download_(false), + rtt_stats_(false) { + + portal_ = std::make_shared(); + + switch (protocol) { + case TransportProtocolAlgorithms::VEGAS: { + transport_protocol_ = std::make_shared(this); + break; + } + case TransportProtocolAlgorithms::RAAQM: { + transport_protocol_ = std::make_shared(this); + break; + } + } +} + +ConsumerSocket::~ConsumerSocket() { + stop(); + transport_protocol_.reset(); + portal_.reset(); +} + +int ConsumerSocket::consume(Name suffix) { + if (is_running_) { + portal_->getIoService().post(std::bind(&ConsumerSocket::postponedConsume, this, suffix)); + return CONSUMER_BUSY; + } + + if (is_async_) { + portal_ = std::make_shared(); + transport_protocol_->updatePortal(); + } + + name_suffix_ = suffix; + is_async_ = false; + transport_protocol_->start(); + is_running_ = false; + return CONSUMER_READY; +} + +void ConsumerSocket::postponedConsume(Name name_suffix) { + if (is_async_) { + portal_ = std::make_shared(); + transport_protocol_->updatePortal(); + } + + name_suffix_ = name_suffix; + is_async_ = false; + transport_protocol_->start(); +} + +int ConsumerSocket::asyncConsume(Name suffix) { + if (transport_protocol_->isRunning()) { + return CONSUMER_BUSY; + } + + name_suffix_ = suffix; + is_async_ = true; + transport_protocol_->start(); + return CONSUMER_READY; +} + +void ConsumerSocket::stop() { + if (transport_protocol_->isRunning()) { + transport_protocol_->stop(); + } + + is_running_ = false; +} + +int ConsumerSocket::setSocketOption(int socket_option_key, double socket_option_value) { + switch (socket_option_key) { + case MIN_WINDOW_SIZE: + min_window_size_ = socket_option_value; + return SOCKET_OPTION_SET; + + case MAX_WINDOW_SIZE: + max_window_size_ = socket_option_value; + return SOCKET_OPTION_SET; + + case CURRENT_WINDOW_SIZE: + current_window_size_ = socket_option_value; + return SOCKET_OPTION_SET; + + case GAMMA_VALUE: + gamma_ = socket_option_value; + return SOCKET_OPTION_SET; + + case BETA_VALUE: + beta_ = socket_option_value; + return SOCKET_OPTION_SET; + + case DROP_FACTOR: + drop_factor_ = socket_option_value; + return SOCKET_OPTION_SET; + + case MINIMUM_DROP_PROBABILITY: + minimum_drop_probability_ = socket_option_value; + return SOCKET_OPTION_SET; + + case RATE_ESTIMATION_ALPHA: + if (socket_option_value >= 0 && socket_option_value < 1) { + rate_estimation_alpha_ = socket_option_value; + } else { + rate_estimation_alpha_ = ALPHA; + } + return SOCKET_OPTION_SET; + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, int socket_option_value) { + switch (socket_option_key) { + + case GeneralTransportOptions::INPUT_BUFFER_SIZE: + input_buffer_size_ = socket_option_value; + return SOCKET_OPTION_SET; + + case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: + output_buffer_size_ = socket_option_value; + return SOCKET_OPTION_SET; + + case GeneralTransportOptions::MAX_INTEREST_RETX: + max_retransmissions_ = socket_option_value; + return SOCKET_OPTION_SET; + + case GeneralTransportOptions::INTEREST_LIFETIME: + interest_lifetime_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ConsumerCallbacksOptions::INTEREST_RETRANSMISSION: + if (socket_option_value == VOID_HANDLER) { + on_interest_retransmission_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ConsumerCallbacksOptions::INTEREST_EXPIRED: + if (socket_option_value == VOID_HANDLER) { + on_interest_timeout_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ConsumerCallbacksOptions::INTEREST_SATISFIED: + if (socket_option_value == VOID_HANDLER) { + on_interest_satisfied_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ConsumerCallbacksOptions::INTEREST_OUTPUT: + if (socket_option_value == VOID_HANDLER) { + on_interest_output_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ConsumerCallbacksOptions::CONTENT_OBJECT_INPUT: + if (socket_option_value == VOID_HANDLER) { + on_content_object_input_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY: + if (socket_option_value == VOID_HANDLER) { + on_content_object_verification_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ConsumerCallbacksOptions::CONTENT_RETRIEVED: + if (socket_option_value == VOID_HANDLER) { + on_payload_retrieved_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case RateEstimationOptions::RATE_ESTIMATION_BATCH_PARAMETER: + if (socket_option_value > 0) { + rate_estimation_batching_parameter_ = socket_option_value; + } else { + rate_estimation_batching_parameter_ = BATCH; + } + return SOCKET_OPTION_SET; + + case RateEstimationOptions::RATE_ESTIMATION_CHOICE: + if (socket_option_value > 0) { + rate_estimation_choice_ = socket_option_value; + } else { + rate_estimation_choice_ = RATE_CHOICE; + } + return SOCKET_OPTION_SET; + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, size_t socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::INPUT_BUFFER_SIZE: + input_buffer_size_ = socket_option_value; + return SOCKET_OPTION_SET; + + case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: + output_buffer_size_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, bool socket_option_value) { + switch (socket_option_key) { + + case GeneralTransportOptions::RUNNING: + is_running_ = socket_option_value; + return SOCKET_OPTION_SET; + + case OtherOptions::VIRTUAL_DOWNLOAD: + virtual_download_ = socket_option_value; + return SOCKET_OPTION_SET; + + case RaaqmTransportOptions::RTT_STATS: + rtt_stats_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, Name socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::NAME_PREFIX: + name_prefix_ = socket_option_value;; + return SOCKET_OPTION_SET; + + case GeneralTransportOptions::NAME_SUFFIX: + name_suffix_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::CONTENT_OBJECT_INPUT: + on_content_object_input_ = socket_option_value;; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ConsumerSocket::setSocketOption(int socket_option_key, + ConsumerContentObjectVerificationCallback socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY: + on_content_object_verification_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::INTEREST_RETRANSMISSION: + on_interest_retransmission_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ConsumerCallbacksOptions::INTEREST_OUTPUT: + on_interest_output_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ConsumerCallbacksOptions::INTEREST_EXPIRED: + on_interest_timeout_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ConsumerCallbacksOptions::INTEREST_SATISFIED: + on_interest_satisfied_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ConsumerSocket::setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::CONTENT_RETRIEVED: + on_payload_retrieved_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::MANIFEST_INPUT: + on_manifest_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::setSocketOption(int socket_option_key, KeyLocator socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ConsumerSocket::setSocketOption(int socket_option_key, IcnObserver *socket_option_value) { + if (socket_option_key == RateEstimationOptions::RATE_ESTIMATION_OBSERVER) { + rate_estimation_observer_ = socket_option_value; + return SOCKET_OPTION_SET; + } else { + return SOCKET_OPTION_NOT_SET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, double &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::MIN_WINDOW_SIZE: + socket_option_value = min_window_size_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::MAX_WINDOW_SIZE: + socket_option_value = max_window_size_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::CURRENT_WINDOW_SIZE: + socket_option_value = current_window_size_; + return SOCKET_OPTION_GET; + + // RAAQM parameters + + case RaaqmTransportOptions::GAMMA_VALUE: + socket_option_value = gamma_; + return SOCKET_OPTION_GET; + + case RaaqmTransportOptions::BETA_VALUE: + socket_option_value = beta_; + return SOCKET_OPTION_GET; + + case RaaqmTransportOptions::DROP_FACTOR: + socket_option_value = drop_factor_; + return SOCKET_OPTION_GET; + + case RaaqmTransportOptions::MINIMUM_DROP_PROBABILITY: + socket_option_value = minimum_drop_probability_; + return SOCKET_OPTION_GET; + + case RateEstimationOptions::RATE_ESTIMATION_ALPHA: + socket_option_value = rate_estimation_alpha_; + return SOCKET_OPTION_GET; + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, int &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::INPUT_BUFFER_SIZE: + socket_option_value = input_buffer_size_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: + socket_option_value = output_buffer_size_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::MAX_INTEREST_RETX: + socket_option_value = max_retransmissions_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::INTEREST_LIFETIME: + socket_option_value = interest_lifetime_; + return SOCKET_OPTION_GET; + + case RaaqmTransportOptions::SAMPLE_NUMBER: + socket_option_value = sample_number_; + return SOCKET_OPTION_GET; + + case RateEstimationOptions::RATE_ESTIMATION_BATCH_PARAMETER: + socket_option_value = rate_estimation_batching_parameter_; + return SOCKET_OPTION_GET; + + case RateEstimationOptions::RATE_ESTIMATION_CHOICE: + socket_option_value = rate_estimation_choice_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, size_t &socket_option_value) { + switch (socket_option_key) { + case INPUT_BUFFER_SIZE: + socket_option_value = input_buffer_size_; + return SOCKET_OPTION_GET; + + case OUTPUT_BUFFER_SIZE: + socket_option_value = output_buffer_size_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, bool &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::ASYNC_MODE: + socket_option_value = is_async_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::RUNNING: + socket_option_value = is_running_; + return SOCKET_OPTION_GET; + + case OtherOptions::VIRTUAL_DOWNLOAD: + socket_option_value = virtual_download_; + return SOCKET_OPTION_GET; + + case RaaqmTransportOptions::RTT_STATS: + socket_option_value = rtt_stats_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, Name &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::NAME_PREFIX: + socket_option_value = name_prefix_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::NAME_SUFFIX: + socket_option_value = name_suffix_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::CONTENT_OBJECT_INPUT: + socket_option_value = on_content_object_input_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ConsumerSocket::getSocketOption(int socket_option_key, + ConsumerContentObjectVerificationCallback &socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY: + socket_option_value = on_content_object_verification_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::INTEREST_RETRANSMISSION: + socket_option_value = on_interest_retransmission_; + return SOCKET_OPTION_GET; + + case ConsumerCallbacksOptions::INTEREST_OUTPUT: + socket_option_value = on_interest_output_; + return SOCKET_OPTION_GET; + + case ConsumerCallbacksOptions::INTEREST_EXPIRED: + socket_option_value = on_interest_timeout_; + return SOCKET_OPTION_GET; + + case ConsumerCallbacksOptions::INTEREST_SATISFIED: + socket_option_value = on_interest_satisfied_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ConsumerSocket::getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::CONTENT_RETRIEVED: + socket_option_value = on_payload_retrieved_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value) { + switch (socket_option_key) { + case ConsumerCallbacksOptions::MANIFEST_INPUT: + socket_option_value = on_manifest_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, KeyLocator &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::KEY_LOCATOR: + socket_option_value = key_locator_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value) { + switch (socket_option_key) { + case PORTAL: + socket_option_value = portal_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ConsumerSocket::getSocketOption(int socket_option_key, IcnObserver **socket_option_value) { + if (socket_option_key == RATE_ESTIMATION_OBSERVER) { + *socket_option_value = (rate_estimation_observer_); + return SOCKET_OPTION_GET; + } else { + return SOCKET_OPTION_NOT_GET; + } +} + +} // end namespace transport + +} // end namespace icnet diff --git a/icnet/transport/icnet_transport_socket_consumer.h b/icnet/transport/icnet_transport_socket_consumer.h new file mode 100644 index 00000000..59a3a8cb --- /dev/null +++ b/icnet/transport/icnet_transport_socket_consumer.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2017 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 ICNET_CONSUMER_SOCKET_H_ +#define ICNET_CONSUMER_SOCKET_H_ + +#include "icnet_transport_common.h" +#include "icnet_transport_socket.h" +#include "icnet_transport_protocol.h" +#include "icnet_transport_raaqm.h" +#include "icnet_transport_vegas.h" + +#define CONSUMER_READY 0 +#define CONSUMER_BUSY 1 + +namespace icnet { + +namespace transport { + +class ConsumerSocket : public Socket { + public: + explicit ConsumerSocket(const Name prefix, int protocol); + + ~ConsumerSocket(); + + int consume(Name suffix); + + int asyncConsume(Name suffix); + + void stop(); + + int setSocketOption(int socket_option_key, int socket_option_value); + + int setSocketOption(int socket_option_key, double socket_option_value); + + int setSocketOption(int socket_option_key, bool socket_option_value); + + int setSocketOption(int socket_option_key, size_t socket_option_value); + + int setSocketOption(int socket_option_key, Name socket_option_value); + + int setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value); + + int setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value); + + int setSocketOption(int socket_option_key, KeyLocator socket_option_value); + + int setSocketOption(int socket_option_key, IcnObserver *socket_option_value); + + int getSocketOption(int socket_option_key, int &socket_option_value); + + int getSocketOption(int socket_option_key, double &socket_option_value); + + int getSocketOption(int socket_option_key, size_t &socket_option_value); + + int getSocketOption(int socket_option_key, bool &socket_option_value); + + int getSocketOption(int socket_option_key, Name &socket_option_value); + + int getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value); + + int getSocketOption(int socket_option_key, KeyLocator &socket_option_value); + + int getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value); + + int getSocketOption(int socket_option_key, IcnObserver **socket_option_value); + + private: + + void postponedConsume(Name name_suffix); + + private: + // context inner state variables + bool is_running_; + std::shared_ptr portal_; + std::shared_ptr transport_protocol_; + + Name name_prefix_; + Name name_suffix_; + + int interest_lifetime_; + + double min_window_size_; + double max_window_size_; + double current_window_size_; + int max_retransmissions_; + size_t output_buffer_size_; + size_t input_buffer_size_; + + // RAAQM Parameters + + double minimum_drop_probability_; + unsigned int sample_number_; + double gamma_; + double beta_; + double drop_factor_; + + //Rate estimation parameters + double rate_estimation_alpha_; + IcnObserver *rate_estimation_observer_; + int rate_estimation_batching_parameter_; + int rate_estimation_choice_; + + bool is_async_; + + KeyLocator key_locator_; + + ConsumerInterestCallback on_interest_retransmission_; + ConsumerInterestCallback on_interest_output_; + ConsumerInterestCallback on_interest_timeout_; + ConsumerInterestCallback on_interest_satisfied_; + + ConsumerContentObjectCallback on_content_object_input_; + ConsumerContentObjectVerificationCallback on_content_object_verification_; + + ConsumerContentObjectCallback on_content_object_; + ConsumerManifestCallback on_manifest_; + + ConsumerContentCallback on_payload_retrieved_; + + // Virtual download for traffic generator + + bool virtual_download_; + bool rtt_stats_; +}; + +} // end namespace transport + +} // end namespace icnet + +#endif // ICNET_CONSUMER_SOCKET_H_ diff --git a/icnet/transport/icnet_transport_socket_options_default_values.h b/icnet/transport/icnet_transport_socket_options_default_values.h new file mode 100644 index 00000000..6214fc96 --- /dev/null +++ b/icnet/transport/icnet_transport_socket_options_default_values.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017 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 ICNET_SOCKET_OPTIONS_DEFAULT_VALUES_H_ +#define ICNET_SOCKET_OPTIONS_DEFAULT_VALUES_H_ + +namespace icnet { + +namespace transport { + +namespace default_values { + +const int interest_lifetime = 1000; // milliseconds +const int content_object_expiry_time = 50000; // milliseconds -> 50 seconds +const int content_object_packet_size = 1500; // The ethernet MTU +const int producer_socket_input_buffer_size = 150000; // Interests +const int producer_socket_output_buffer_size = 150000; // Content Object +const int default_buffer_size = 8096 * 8 * 2; +const int signature_size = 260; // bytes +const int key_locator_size = 60; // bytes +const int limit_guard = 80; // bytes +const int min_window_size = 1; // Interests +const int max_window_size = 128000; // Interests +const int digest_size = 34; // bytes +const int max_out_of_order_segments = 3; // content object + +// RAAQM +const int sample_number = 30; +const double gamma_value = 1; +const double beta_value = 0.8; +const double drop_factor = 0.2; +const double minimum_drop_probability = 0.00001; +const int path_id = 0; +const double rate_alpha = 0.8; + +// Vegas +const double alpha = 1 / 8; +const double beta = 1 / 4; +const uint16_t k = 4; +const std::chrono::milliseconds clock_granularity = std::chrono::milliseconds(100); + +// maximum allowed values +const int transport_protocol_min_retransmissions = 0; +const int transport_protocol_max_retransmissions = 128; +const int max_content_object_size = 8096; + +} // end namespace default_values + +} // end namespace transport + +} // end namespace icnet + +#endif // ICNET_SOCKET_OPTIONS_DEFAULT_VALUES_H_ diff --git a/icnet/transport/icnet_transport_socket_options_keys.h b/icnet/transport/icnet_transport_socket_options_keys.h new file mode 100644 index 00000000..460e8383 --- /dev/null +++ b/icnet/transport/icnet_transport_socket_options_keys.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017 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 ICNET_TRANSPORT_OPTIONS_KEYS_H_ +#define ICNET_TRANSPORT_OPTIONS_KEYS_H_ + +namespace icnet { + +namespace transport { + +typedef enum { + RAAQM = 0, VEGAS = 1 +} TransportProtocolAlgorithms; + +typedef enum { + INPUT_BUFFER_SIZE = 101, + OUTPUT_BUFFER_SIZE = 102, + NAME_PREFIX = 103, + NAME_SUFFIX = 104, + MAX_INTEREST_RETX = 105, + DATA_PACKET_SIZE = 106, + INTEREST_LIFETIME = 107, + CONTENT_OBJECT_EXPIRY_TIME = 108, + KEY_LOCATOR = 110, + SIGNATURE_TYPE = 111, + MIN_WINDOW_SIZE = 112, + MAX_WINDOW_SIZE = 113, + CURRENT_WINDOW_SIZE = 114, + ASYNC_MODE = 115, + MAKE_MANIFEST = 116, + PORTAL = 117, + RUNNING = 118, +} GeneralTransportOptions; + +typedef enum { + SAMPLE_NUMBER = 201, + GAMMA_VALUE = 202, + BETA_VALUE = 203, + DROP_FACTOR = 204, + MINIMUM_DROP_PROBABILITY = 205, + PATH_ID = 206, + RTT_STATS = 207, +} RaaqmTransportOptions; + +typedef enum { + RATE_ESTIMATION_ALPHA = 301, + RATE_ESTIMATION_OBSERVER = 302, + RATE_ESTIMATION_BATCH_PARAMETER = 303, + RATE_ESTIMATION_CHOICE = 304, +} RateEstimationOptions; + +typedef enum { + INTEREST_OUTPUT = 401, + INTEREST_RETRANSMISSION = 402, + INTEREST_EXPIRED = 403, + INTEREST_SATISFIED = 404, + CONTENT_OBJECT_INPUT = 411, + MANIFEST_INPUT = 412, + CONTENT_OBJECT_TO_VERIFY = 413, + CONTENT_RETRIEVED = 414, +} ConsumerCallbacksOptions; + +typedef enum { + INTEREST_INPUT = 501, + INTEREST_DROP = 502, + INTEREST_PASS = 503, + CACHE_HIT = 506, + CACHE_MISS = 508, + NEW_CONTENT_OBJECT = 509, + CONTENT_OBJECT_SIGN = 513, + CONTENT_OBJECT_READY = 510, + CONTENT_OBJECT_OUTPUT = 511, +} ProducerCallbacksOptions; + +typedef enum { + VIRTUAL_DOWNLOAD = 601, USE_CFG_FILE = 603, +} OtherOptions; + +typedef enum { + SHA_256 = 701, RSA_256 = 702, +} SignatureType; + +} // end namespace transport + +} // end namespace icnet + +#endif // ICNET_TRANSPORT_OPTIONS_KEYS_H_ diff --git a/icnet/transport/icnet_transport_socket_producer.cc b/icnet/transport/icnet_transport_socket_producer.cc new file mode 100644 index 00000000..190580f8 --- /dev/null +++ b/icnet/transport/icnet_transport_socket_producer.cc @@ -0,0 +1,728 @@ +/* + * Copyright (c) 2017 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 "icnet_transport_socket_producer.h" + +namespace icnet { + +namespace transport { + +ProducerSocket::ProducerSocket(Name prefix) + : portal_(new Portal()), + name_prefix_(prefix), + data_packet_size_(default_values::content_object_packet_size), + content_object_expiry_time_(default_values::content_object_expiry_time), + registration_status_(REGISTRATION_NOT_ATTEMPTED), + making_manifest_(false), + signature_type_(SHA_256), + key_locator_size_(default_values::key_locator_size), + output_buffer_(default_values::producer_socket_output_buffer_size), + input_buffer_capacity_(default_values::producer_socket_input_buffer_size), + input_buffer_size_(0), + processing_thread_stop_(false), + listening_thread_stop_(false), + on_interest_input_(VOID_HANDLER), + on_interest_dropped_input_buffer_(VOID_HANDLER), + on_interest_inserted_input_buffer_(VOID_HANDLER), + on_interest_satisfied_output_buffer_(VOID_HANDLER), + on_interest_process_(VOID_HANDLER), + on_new_segment_(VOID_HANDLER), + on_content_object_to_sign_(VOID_HANDLER), + on_content_object_in_output_buffer_(VOID_HANDLER), + on_content_object_output_(VOID_HANDLER), + on_content_object_evicted_from_output_buffer_(VOID_HANDLER) { + listening_thread_stop_ = false; + key_locator_size_ = default_values::key_locator_size; +} + +ProducerSocket::~ProducerSocket() { + processing_thread_stop_ = true; + portal_->stopEventsLoop(); + + if (processing_thread_.joinable()) { + processing_thread_.join(); + } + + if (listening_thread_.joinable()) { + listening_thread_.join(); + } +} + +void ProducerSocket::attach() { + listening_thread_ = std::thread(std::bind(&ProducerSocket::listen, this)); + // processing_thread_ = boost::thread(bind(&ProducerTransport::processIncomingInterest, this)); +} + +void ProducerSocket::serveForever() { + if (listening_thread_.joinable()) { + listening_thread_.join(); + } +} + +void ProducerSocket::stop() { + portal_->stopEventsLoop(); +} + +void ProducerSocket::dispatch() { + // Check that the INTEREST_INPUT callback is set. + if (on_interest_input_ == VOID_HANDLER) { + std::cerr << "Warning: the dispatcher function needs a dispatcher callback! " + "You need to set INTEREST_INPUT callback" << std::endl; + } + + listening_thread_ = std::thread(std::bind(&ProducerSocket::listen, this)); +} + +void ProducerSocket::listen() { + registration_status_ = REGISTRATION_IN_PROGRESS; + + portal_ + ->bind(name_prefix_, std::bind(&ProducerSocket::onInterest, this, std::placeholders::_1, std::placeholders::_2)); + + portal_->runEventsLoop(); +} + +void ProducerSocket::passContentObjectToCallbacks(const std::shared_ptr &content_object) { + if (content_object) { + if (on_new_segment_ != VOID_HANDLER) { + on_new_segment_(*this, *content_object); + } + + if (on_content_object_to_sign_ != VOID_HANDLER) { + if (!making_manifest_) { + on_content_object_to_sign_(*this, *content_object); + } else { + if (content_object->getPayloadType() == PayloadType::MANIFEST) { + on_content_object_to_sign_(*this, *content_object); + } else { + content_object->signWithSha256(key_locator_); + } + } + } else { + content_object->signWithSha256(key_locator_); + } + + if (on_content_object_in_output_buffer_ != VOID_HANDLER) { + on_content_object_in_output_buffer_(*this, *content_object); + } + + output_buffer_.insert(content_object); + + if (on_content_object_output_ != VOID_HANDLER) { + on_content_object_output_(*this, *content_object); + } + + if (content_object->getName().get(-1).toSegment() == 0) { + portal_->sendContentObject(*content_object); + } + } +} + +void ProducerSocket::produce(ContentObject &content_object) { + if (!name_prefix_.isPrefixOf(content_object.getName())) { + return; + } + + if (on_content_object_in_output_buffer_ != VOID_HANDLER) { + on_content_object_in_output_buffer_(*this, content_object); + } + + if (on_content_object_output_ != VOID_HANDLER) { + on_content_object_output_(*this, content_object); + } + + portal_->sendContentObject(content_object); +} + +void ProducerSocket::produce(Name name, const uint8_t *buf, size_t buffer_size, const int response_id, bool is_last) { + + if (buffer_size == 0) { + return; + } + + if (name.empty() || !name_prefix_.isPrefixOf(name)) { + return; + } + + int bytes_segmented = 0; + + std::cout << name.toString() << std::endl; + + size_t bytes_occupied_by_name = name.size(); + + int digestSize = default_values::digest_size; // SHA_256 as default + int signatureSize = default_values::signature_size; + uint64_t free_space_for_content = 0; + + free_space_for_content = data_packet_size_ - bytes_occupied_by_name - digestSize - default_values::limit_guard; + + uint64_t number_of_segments = uint64_t(std::ceil(double(buffer_size) / double(free_space_for_content))); + + if (free_space_for_content * number_of_segments < buffer_size) { + number_of_segments++; + } + + uint64_t current_segment = 0; + + if (seq_number_map_.find(name.toString()) != seq_number_map_.end() + && seq_number_map_[name.toString()].find(response_id) != seq_number_map_[name.toString()].end()) { + current_segment = seq_number_map_[name.toString()][response_id]; + } else { + seq_number_map_[name.toString()][response_id] = current_segment; + } + + if (making_manifest_) { + + std::shared_ptr content_object_segment; + std::shared_ptr manifest_segment; + bool manifest_segment_needed = true; + + uint64_t free_space_for_manifest = + data_packet_size_ - bytes_occupied_by_name - signatureSize - default_values::limit_guard; + + for (unsigned int packaged_segments = 0; packaged_segments < number_of_segments;) { + + if (manifest_segment_needed) { + + Name manifest_name(name_prefix_); + + if (!name.empty()) { + manifest_name.append(name); + } + + manifest_name.appendSegment(current_segment); + + if (manifest_segment) { + manifest_segment->encode(); + passContentObjectToCallbacks(manifest_segment); + } + + manifest_segment = std::make_shared(manifest_name); + + if (is_last) { + manifest_segment->setFinalChunkNumber(current_segment + number_of_segments - packaged_segments); + } + + // finalSegment = current_segment; + manifest_segment_needed = false; + current_segment++; + + key_locator_.clear(); + key_locator_.setName(const_cast(manifest_segment->getName())); + } + + Name full_name = name; + + content_object_segment = std::make_shared(std::move(full_name.appendSegment(current_segment))); + // content_object_segment->setExpiryTime((uint64_t) m_dataFreshness); + + if (packaged_segments == number_of_segments - 1) { + content_object_segment->setContent(&buf[bytes_segmented], buffer_size - bytes_segmented); + bytes_segmented += buffer_size - bytes_segmented; + } else { + content_object_segment->setContent(&buf[bytes_segmented], free_space_for_content); + bytes_segmented += free_space_for_content; + } + + if (is_last) { + content_object_segment->setFinalChunkNumber(current_segment + number_of_segments - packaged_segments - 1); + } + + passContentObjectToCallbacks(content_object_segment); + + size_t manifestSize = manifest_segment->estimateManifestSize(); + Name &content_object_name = (Name &) content_object_segment->getName(); + size_t fullNameSize = content_object_name.size(); + + // TODO Signature + + if (manifestSize + 2 * fullNameSize > free_space_for_manifest) { + manifest_segment_needed = true; + } + + // TODO Manifest and hashes! + // Array block = content_object_segment->getContent(); + // icn-interface::ConstBufferPtr implicitDigest = icn-interface::crypto::sha256(block.data(), block.size()); + // + // //add implicit digest to the manifest + // manifest_segment->addNameToCatalogue(Name(std::to_string(current_segment)), implicitDigest->buf(), + // implicitDigest->size()); + + packaged_segments++; + current_segment++; + + if (packaged_segments == number_of_segments) { + manifest_segment->encode(); + passContentObjectToCallbacks(manifest_segment); + } + } + } else { + + for (unsigned int packaged_segments = 0; packaged_segments < number_of_segments; packaged_segments++) { + Name fullName = name; + + std::shared_ptr + content_object = std::make_shared(std::move(fullName.appendSegment(current_segment))); + + // TODO If we set the throughput will decrease.. to investigate + // content_object->setExpiryTime((uint64_t)m_dataFreshness); + + if (is_last) { + content_object->setFinalChunkNumber(current_segment + number_of_segments - packaged_segments - 1); + } + + if (packaged_segments == number_of_segments - 1) { + content_object->setContent(&buf[bytes_segmented], buffer_size - bytes_segmented); + bytes_segmented += buffer_size - bytes_segmented; + } else { + content_object->setContent(&buf[bytes_segmented], free_space_for_content); + bytes_segmented += free_space_for_content; + } + + current_segment++; + passContentObjectToCallbacks(content_object); + } + } + + seq_number_map_[name.toString()][response_id] = current_segment; + + if (is_last) { + seq_number_map_[name.toString()].erase(response_id); + if (seq_number_map_[name.toString()].empty()) { + seq_number_map_.erase(name.toString()); + } + } +} + +void ProducerSocket::asyncProduce(ContentObject &content_object) { + std::shared_ptr c_object = std::make_shared(content_object); + std::thread t([c_object, this]() { produce(*c_object); }); + t.detach(); +} + +void ProducerSocket::asyncProduce(Name suffix, + const uint8_t *buf, + size_t buffer_size, + const int response_id, + bool is_last) { + std::thread t([suffix, buf, buffer_size, response_id, is_last, this]() { + produce(suffix, buf, buffer_size, response_id, is_last); + }); + t.detach(); +} + +void ProducerSocket::onInterest(const Name &name, const Interest &interest) { + if (on_interest_input_ != VOID_HANDLER) { + on_interest_input_(*this, interest); + } + + const std::shared_ptr &content_object = output_buffer_.find(interest); + + if (content_object) { + + if (on_interest_satisfied_output_buffer_ != VOID_HANDLER) { + on_interest_satisfied_output_buffer_(*this, interest); + } + + if (on_content_object_output_ != VOID_HANDLER) { + on_content_object_output_(*this, *content_object); + } + + portal_->sendContentObject(*content_object); + } else { + if (on_interest_process_ != VOID_HANDLER) { + on_interest_process_(*this, interest); + } + } +} + +int ProducerSocket::setSocketOption(int socket_option_key, int socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::DATA_PACKET_SIZE: + if (socket_option_value < default_values::max_content_object_size && socket_option_value > 0) { + data_packet_size_ = socket_option_value; + return SOCKET_OPTION_SET; + } else { + return SOCKET_OPTION_NOT_SET; + } + + case GeneralTransportOptions::INPUT_BUFFER_SIZE: + if (socket_option_value >= 1) { + input_buffer_capacity_ = socket_option_value; + return SOCKET_OPTION_SET; + } else { + return SOCKET_OPTION_NOT_SET; + } + + case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: + if (socket_option_value >= 0) { + output_buffer_.setLimit(socket_option_value); + return SOCKET_OPTION_SET; + } else { + return SOCKET_OPTION_NOT_SET; + } + + case GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME: + content_object_expiry_time_ = socket_option_value; + return SOCKET_OPTION_SET; + + case GeneralTransportOptions::SIGNATURE_TYPE: + if (socket_option_value == SOCKET_OPTION_DEFAULT) { + signature_type_ = SHA_256; + } else { + signature_type_ = socket_option_value; + } + + if (signature_type_ == SHA_256 || signature_type_ == RSA_256) { + signature_size_ = 32; + } + + case ProducerCallbacksOptions::INTEREST_INPUT: + if (socket_option_value == VOID_HANDLER) { + on_interest_input_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ProducerCallbacksOptions::INTEREST_DROP: + if (socket_option_value == VOID_HANDLER) { + on_interest_dropped_input_buffer_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ProducerCallbacksOptions::INTEREST_PASS: + if (socket_option_value == VOID_HANDLER) { + on_interest_inserted_input_buffer_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ProducerCallbacksOptions::CACHE_HIT: + if (socket_option_value == VOID_HANDLER) { + on_interest_satisfied_output_buffer_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ProducerCallbacksOptions::CACHE_MISS: + if (socket_option_value == VOID_HANDLER) { + on_interest_process_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ProducerCallbacksOptions::NEW_CONTENT_OBJECT: + if (socket_option_value == VOID_HANDLER) { + on_new_segment_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ProducerCallbacksOptions::CONTENT_OBJECT_SIGN: + if (socket_option_value == VOID_HANDLER) { + on_content_object_to_sign_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ProducerCallbacksOptions::CONTENT_OBJECT_READY: + if (socket_option_value == VOID_HANDLER) { + on_content_object_in_output_buffer_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + case ProducerCallbacksOptions::CONTENT_OBJECT_OUTPUT: + if (socket_option_value == VOID_HANDLER) { + on_content_object_output_ = VOID_HANDLER; + return SOCKET_OPTION_SET; + } + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ProducerSocket::setSocketOption(int socket_option_key, double socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ProducerSocket::setSocketOption(int socket_option_key, bool socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::MAKE_MANIFEST: + making_manifest_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ProducerSocket::setSocketOption(int socket_option_key, Name socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::NAME_PREFIX: + name_prefix_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ProducerSocket::setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value) { + switch (socket_option_key) { + case ProducerCallbacksOptions::NEW_CONTENT_OBJECT: + on_new_segment_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ProducerCallbacksOptions::CONTENT_OBJECT_SIGN: + on_content_object_to_sign_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ProducerCallbacksOptions::CONTENT_OBJECT_READY: + on_content_object_in_output_buffer_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ProducerCallbacksOptions::CONTENT_OBJECT_OUTPUT: + on_content_object_output_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ProducerSocket::setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value) { + switch (socket_option_key) { + case ProducerCallbacksOptions::INTEREST_INPUT: + on_interest_input_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ProducerCallbacksOptions::INTEREST_DROP: + on_interest_dropped_input_buffer_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ProducerCallbacksOptions::INTEREST_PASS: + on_interest_inserted_input_buffer_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ProducerCallbacksOptions::CACHE_HIT: + on_interest_satisfied_output_buffer_ = socket_option_value; + return SOCKET_OPTION_SET; + + case ProducerCallbacksOptions::CACHE_MISS: + on_interest_process_ = socket_option_value; + return SOCKET_OPTION_SET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ProducerSocket::setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ProducerSocket::setSocketOption(int socket_option_key, + ConsumerContentObjectVerificationCallback socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ProducerSocket::setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ProducerSocket::setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ProducerSocket::setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ProducerSocket::setSocketOption(int socket_option_key, KeyLocator socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +int ProducerSocket::getSocketOption(int socket_option_key, int &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::INPUT_BUFFER_SIZE: + socket_option_value = input_buffer_capacity_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: + socket_option_value = output_buffer_.getLimit(); + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::DATA_PACKET_SIZE: + socket_option_value = data_packet_size_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME: + socket_option_value = content_object_expiry_time_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::SIGNATURE_TYPE: + socket_option_value = signature_type_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ProducerSocket::getSocketOption(int socket_option_key, double &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::getSocketOption(int socket_option_key, bool &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::MAKE_MANIFEST: + socket_option_value = making_manifest_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ProducerSocket::getSocketOption(int socket_option_key, Name &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::NAME_PREFIX: + socket_option_value = name_prefix_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ProducerSocket::getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value) { + switch (socket_option_key) { + case ProducerCallbacksOptions::NEW_CONTENT_OBJECT: + socket_option_value = on_new_segment_; + return SOCKET_OPTION_GET; + + case ProducerCallbacksOptions::CONTENT_OBJECT_SIGN: + socket_option_value = on_content_object_to_sign_; + return SOCKET_OPTION_GET; + + case ProducerCallbacksOptions::CONTENT_OBJECT_READY: + socket_option_value = on_content_object_in_output_buffer_; + return SOCKET_OPTION_GET; + + case ProducerCallbacksOptions::CONTENT_OBJECT_OUTPUT: + socket_option_value = on_content_object_output_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ProducerSocket::getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value) { + switch (socket_option_key) { + case ProducerCallbacksOptions::INTEREST_INPUT: + socket_option_value = on_interest_input_; + return SOCKET_OPTION_GET; + + case ProducerCallbacksOptions::INTEREST_DROP: + socket_option_value = on_interest_dropped_input_buffer_; + return SOCKET_OPTION_GET; + + case ProducerCallbacksOptions::INTEREST_PASS: + socket_option_value = on_interest_inserted_input_buffer_; + return SOCKET_OPTION_GET; + + case CACHE_HIT: + socket_option_value = on_interest_satisfied_output_buffer_; + return SOCKET_OPTION_GET; + + case CACHE_MISS: + socket_option_value = on_interest_process_; + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ProducerSocket::getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::getSocketOption(int socket_option_key, + ConsumerContentObjectVerificationCallback &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::setSocketOption(int socket_option_key, size_t socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::INPUT_BUFFER_SIZE: + if (input_buffer_capacity_ >= 1) { + input_buffer_capacity_ = socket_option_value; + return SOCKET_OPTION_SET; + } + + default: + return SOCKET_OPTION_NOT_SET; + } +} + +int ProducerSocket::getSocketOption(int socket_option_key, size_t &socket_option_value) { + switch (socket_option_key) { + case GeneralTransportOptions::INPUT_BUFFER_SIZE: + socket_option_value = input_buffer_capacity_; + return SOCKET_OPTION_GET; + + case GeneralTransportOptions::OUTPUT_BUFFER_SIZE: + socket_option_value = output_buffer_.size(); + return SOCKET_OPTION_GET; + + default: + return SOCKET_OPTION_NOT_GET; + } +} + +int ProducerSocket::getSocketOption(int socket_option_key, KeyLocator &socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value) { + switch (socket_option_key) { + case PORTAL: + socket_option_value = portal_; + return SOCKET_OPTION_GET; + } + + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::getSocketOption(int socket_option_key, IcnObserver **socket_option_value) { + return SOCKET_OPTION_NOT_GET; +} + +int ProducerSocket::setSocketOption(int socket_option_key, IcnObserver *socket_option_value) { + return SOCKET_OPTION_NOT_SET; +} + +} // end namespace transport + +} // end namespace icnet diff --git a/icnet/transport/icnet_transport_socket_producer.h b/icnet/transport/icnet_transport_socket_producer.h new file mode 100644 index 00000000..4f98f9e2 --- /dev/null +++ b/icnet/transport/icnet_transport_socket_producer.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2017 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 ICNET_PRODUCER_SOCKET_H_ +#define ICNET_PRODUCER_SOCKET_H_ + +#include "icnet_transport_socket.h" +#include "icnet_transport_content_store.h" + +#include +#include +#include +#include + +#define REGISTRATION_NOT_ATTEMPTED 0 +#define REGISTRATION_SUCCESS 1 +#define REGISTRATION_FAILURE 2 +#define REGISTRATION_IN_PROGRESS 3 + +namespace icnet { + +namespace transport { + +class ProducerSocket : public Socket { + public: + + explicit ProducerSocket(Name prefix); + + ~ProducerSocket(); + + void attach(); + + void dispatch(); + + void produce(Name name, const uint8_t *buffer, size_t buffer_size, const int request_id = 0, bool is_last = false); + + void produce(ContentObject &content_object); + + void asyncProduce(Name suffix, const uint8_t *buf, size_t buffer_size, const int response_id, bool is_last); + + void asyncProduce(ContentObject &content_object); + + void serveForever(); + + void stop(); + + void onInterest(const Name &name, const Interest &interest); + + int setSocketOption(int socket_option_key, int socket_option_value); + + int setSocketOption(int socket_option_key, double socket_option_value); + + int setSocketOption(int socket_option_key, bool socket_option_value); + + int setSocketOption(int socket_option_key, size_t socket_option_value); + + int setSocketOption(int socket_option_key, Name socket_option_value); + + int setSocketOption(int socket_option_key, ProducerContentObjectCallback socket_option_value); + + int setSocketOption(int socket_option_key, ProducerInterestCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerContentObjectCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerInterestCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerContentCallback socket_option_value); + + int setSocketOption(int socket_option_key, ConsumerManifestCallback socket_option_value); + + int setSocketOption(int socket_option_key, KeyLocator socket_option_value); + + int setSocketOption(int socket_option_key, IcnObserver *obs); + + int getSocketOption(int socket_option_key, int &socket_option_value); + + int getSocketOption(int socket_option_key, double &socket_option_value); + + int getSocketOption(int socket_option_key, bool &socket_option_value); + + int getSocketOption(int socket_option_key, size_t &socket_option_value); + + int getSocketOption(int socket_option_key, Name &socket_option_value); + + int getSocketOption(int socket_option_key, ProducerContentObjectCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ProducerInterestCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerContentObjectVerificationCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerContentObjectCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerInterestCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerContentCallback &socket_option_value); + + int getSocketOption(int socket_option_key, ConsumerManifestCallback &socket_option_value); + + int getSocketOption(int socket_option_key, KeyLocator &socket_option_value); + + int getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value); + + int getSocketOption(int socket_option_key, IcnObserver **socket_option_value); + + private: + + std::shared_ptr portal_; + boost::asio::io_service io_service_; + + Name name_prefix_; + + int data_packet_size_; + int content_object_expiry_time_; + int registration_status_; + + bool making_manifest_; + + // map for storing sequence numbers for several calls of the publish function + std::unordered_map> seq_number_map_; + + int signature_type_; + int signature_size_; + int key_locator_size_; + KeyLocator key_locator_; + + // buffers + ContentStore output_buffer_; + + std::queue > input_buffer_; + std::mutex input_buffer_mutex_; + std::atomic_size_t input_buffer_capacity_; + std::atomic_size_t input_buffer_size_; + + // threads + std::thread listening_thread_; + std::thread processing_thread_; + volatile bool processing_thread_stop_; + volatile bool listening_thread_stop_; + + // callbacks + ProducerInterestCallback on_interest_input_; + ProducerInterestCallback on_interest_dropped_input_buffer_; + ProducerInterestCallback on_interest_inserted_input_buffer_; + ProducerInterestCallback on_interest_satisfied_output_buffer_; + ProducerInterestCallback on_interest_process_; + + ProducerContentObjectCallback on_new_segment_; + ProducerContentObjectCallback on_content_object_to_sign_; + ProducerContentObjectCallback on_content_object_in_output_buffer_; + ProducerContentObjectCallback on_content_object_output_; + ProducerContentObjectCallback on_content_object_evicted_from_output_buffer_; + + private: + void listen(); + + void passContentObjectToCallbacks(const std::shared_ptr &content_object); + +}; + +} // end namespace transport + +} // end namespace icnet + +#endif // ICNET_PRODUCER_SOCKET_H_ diff --git a/icnet/transport/icnet_transport_vegas.cc b/icnet/transport/icnet_transport_vegas.cc index d5a3c500..dd5c7c90 100644 --- a/icnet/transport/icnet_transport_vegas.cc +++ b/icnet/transport/icnet_transport_vegas.cc @@ -14,10 +14,12 @@ */ #include "icnet_transport_vegas.h" -#include "icnet_socket_consumer.h" +#include "icnet_transport_socket_consumer.h" namespace icnet { +namespace transport { + VegasTransportProtocol::VegasTransportProtocol(Socket *icnet_socket) : TransportProtocol(icnet_socket), is_final_block_number_discovered_(false), @@ -139,9 +141,9 @@ void VegasTransportProtocol::onContentSegment(const Interest &interest, ContentO on_interest_satisfied(*dynamic_cast(socket_), const_cast(interest)); } - if (content_object.getContentType() == PayloadType::MANIFEST) { + if (content_object.getPayloadType() == PayloadType::MANIFEST) { onManifest(interest, content_object); - } else if (content_object.getContentType() == PayloadType::DATA) { + } else if (content_object.getPayloadType() == PayloadType::DATA) { onContentObject(interest, content_object); } // TODO InterestReturn @@ -381,8 +383,7 @@ void VegasTransportProtocol::copyContent(ContentObject &content_object) { socket_->getSocketOption(CONTENT_RETRIEVED, on_payload); if (on_payload != VOID_HANDLER) { on_payload(*dynamic_cast(socket_), - (uint8_t *) (content_buffer_.data()), - content_buffer_.size()); + std::move(content_buffer_)); } //reduce window size to prevent its speculative growth in case when consume() is called in loop @@ -401,7 +402,7 @@ void VegasTransportProtocol::reassemble() { uint64_t index = last_reassembled_segment_ % default_values::default_buffer_size; while (receive_buffer_[index % default_values::default_buffer_size]) { - if (receive_buffer_[index % default_values::default_buffer_size]->getContentType() == PayloadType::DATA) { + if (receive_buffer_[index % default_values::default_buffer_size]->getPayloadType() == PayloadType::DATA) { copyContent(*receive_buffer_[index % default_values::default_buffer_size]); } @@ -484,4 +485,6 @@ void VegasTransportProtocol::removeAllPendingInterests() { portal_->clear(); } -} // namespace icn-interface +} // end namespace transport + +} // end namespace icnet diff --git a/icnet/transport/icnet_transport_vegas.h b/icnet/transport/icnet_transport_vegas.h index a47050d8..cec2aa5a 100644 --- a/icnet/transport/icnet_transport_vegas.h +++ b/icnet/transport/icnet_transport_vegas.h @@ -16,11 +16,13 @@ #ifndef ICNET_VEGAS_TRANSPORT_PROTOCOL_H_ #define ICNET_VEGAS_TRANSPORT_PROTOCOL_H_ -#include "icnet_transport.h" +#include "icnet_transport_protocol.h" #include "icnet_transport_vegas_rto_estimator.h" namespace icnet { +namespace transport { + class VegasTransportProtocol : public TransportProtocol { public: @@ -103,6 +105,8 @@ class VegasTransportProtocol : public TransportProtocol { std::unordered_map fast_retransmitted_segments; }; +} // end namespace transport + } // end namespace icnet diff --git a/icnet/transport/icnet_transport_vegas_rto_estimator.cc b/icnet/transport/icnet_transport_vegas_rto_estimator.cc index 6653518e..f1c10637 100644 --- a/icnet/transport/icnet_transport_vegas_rto_estimator.cc +++ b/icnet/transport/icnet_transport_vegas_rto_estimator.cc @@ -14,10 +14,12 @@ */ #include "icnet_transport_vegas_rto_estimator.h" -#include "icnet_socket_options_default_values.h" +#include "icnet_transport_socket_options_default_values.h" namespace icnet { +namespace transport { + RtoEstimator::RtoEstimator(Duration min_rto) : smoothed_rtt_(RtoEstimator::getInitialRtt().count()), rtt_variation_(0), @@ -44,4 +46,6 @@ RtoEstimator::Duration RtoEstimator::computeRto() const { return Duration(static_cast(rto)); } +} // end namespace transport + } // end namespace icnet \ No newline at end of file diff --git a/icnet/transport/icnet_transport_vegas_rto_estimator.h b/icnet/transport/icnet_transport_vegas_rto_estimator.h index 7b18533c..799d6fbc 100644 --- a/icnet/transport/icnet_transport_vegas_rto_estimator.h +++ b/icnet/transport/icnet_transport_vegas_rto_estimator.h @@ -16,12 +16,14 @@ #ifndef ICNET_VEGAS_TRANSPORT_PROTOCOL_RTT_ESTIMATOR_H_ #define ICNET_VEGAS_TRANSPORT_PROTOCOL_RTT_ESTIMATOR_H_ -#include "icnet_common.h" +#include "icnet_transport_common.h" // Implementation inspired from RFC6298 (https://tools.ietf.org/search/rfc6298#ref-JK88) namespace icnet { +namespace transport { + class RtoEstimator { public: typedef std::chrono::microseconds Duration; @@ -43,6 +45,8 @@ class RtoEstimator { double last_rto_; }; +} // end namespace transport + } // end namespace icnet diff --git a/icnet/utils/icnet_utils_array.cc b/icnet/utils/icnet_utils_array.cc new file mode 100644 index 00000000..413119cb --- /dev/null +++ b/icnet/utils/icnet_utils_array.cc @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 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 "icnet_utils_array.h" + +namespace icnet { + +namespace utils { + +Array::Array(const void *array, size_t size) { + this->array_ = array; + this->size_ = size; +} + +Array::Array() { + this->array_ = nullptr; + this->size_ = 0; +} + +const void *Array::data() const { + return array_; +} + +std::size_t Array::size() const { + return size_; +} + +Array &Array::setData(const void *data) { + array_ = data; + return *this; +} + +Array &Array::setSize(std::size_t size) { + size_ = size; + return *this; +} + +} + +} \ No newline at end of file diff --git a/icnet/utils/icnet_utils_array.h b/icnet/utils/icnet_utils_array.h new file mode 100644 index 00000000..f13c0b47 --- /dev/null +++ b/icnet/utils/icnet_utils_array.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 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 + +namespace icnet { + +namespace utils { + +class Array { + public: + explicit Array(const void *array, size_t size); + + Array(); + + const void *data() const; + + std::size_t size() const; + + Array &setData(const void *data); + + Array &setSize(std::size_t size); + + private: + std::size_t size_; + const void *array_; +}; + +} + +} diff --git a/icnet/utils/icnet_utils_daemonizator.cc b/icnet/utils/icnet_utils_daemonizator.cc new file mode 100644 index 00000000..2bb6dd05 --- /dev/null +++ b/icnet/utils/icnet_utils_daemonizator.cc @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017 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 "icnet_utils_daemonizator.h" +#include "icnet_errors_runtime_exception.h" +#include +#include +#include +#include + +namespace icnet { + +namespace utils { + +void Daemonizator::daemonize() { + pid_t process_id = 0; + pid_t sid = 0; + + // Create child process + process_id = fork(); + + // Indication of fork() failure + if (process_id < 0) { + throw errors::RuntimeException("Fork failed."); + } + + // PARENT PROCESS. Need to kill it. + if (process_id > 0) { + std::cout << "Process id of child process " << process_id << std::endl; + // return success in exit status + exit(EXIT_SUCCESS); + } + + // unmask the file mode + umask(0); + + // set new session + sid = setsid(); + if (sid < 0) { + // Return failure + exit(EXIT_FAILURE); + } + + // Change the current working directory to root. + int ret = chdir("/"); + + if (ret < 0) { + throw errors::RuntimeException("Error changing working directory to root"); + } + + // Close stdin. stdout and stderr + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + // Really start application +} + +} + +} diff --git a/icnet/utils/icnet_utils_daemonizator.h b/icnet/utils/icnet_utils_daemonizator.h new file mode 100644 index 00000000..20cd80bb --- /dev/null +++ b/icnet/utils/icnet_utils_daemonizator.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 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 + +namespace icnet { + +namespace utils { + +class Daemonizator { + public: + static void daemonize(); +}; + +} + +} \ No newline at end of file diff --git a/icnet/utils/icnet_utils_hash.cc b/icnet/utils/icnet_utils_hash.cc new file mode 100644 index 00000000..39dd0229 --- /dev/null +++ b/icnet/utils/icnet_utils_hash.cc @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017 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 "icnet_utils_hash.h" + +namespace icnet { + +namespace utils { + +uint32_t Hash::hash32(const void *data, std::size_t len) { + const uint32_t fnv1a_offset = 0x811C9DC5; + return Hash::cumulativeHash32(data, len, fnv1a_offset); +} + +uint32_t Hash::cumulativeHash32(const void *data, std::size_t len, uint32_t lastValue) { + // Standard FNV 32-bit prime: see http://www.isthe.com/chongo/tech/comp/fnv/#FNV-param + const uint32_t fnv1a_prime = 0x01000193; + uint32_t hash = lastValue; + + const char *chardata = (char *) data; + + for (std::size_t i = 0; i < len; i++) { + hash = hash ^ chardata[i]; + hash = hash * fnv1a_prime; + } + + return hash; +} + +uint64_t Hash::hash64(const void *data, std::size_t len) { + // Standard FNV 64-bit offset: see http://www.isthe.com/chongo/tech/comp/fnv/#FNV-param + const uint64_t fnv1a_offset = 0xCBF29CE484222325ULL; + return cumulativeHash64(data, len, fnv1a_offset); +} + +uint64_t Hash::cumulativeHash64(const void *data, std::size_t len, uint64_t lastValue) { + // Standard FNV 64-bit prime: see http://www.isthe.com/chongo/tech/comp/fnv/#FNV-param + const uint64_t fnv1a_prime = 0x00000100000001B3ULL; + uint64_t hash = lastValue; + const char *chardata = (char *) data; + + for (std::size_t i = 0; i < len; i++) { + hash = hash ^ chardata[i]; + hash = hash * fnv1a_prime; + } + + return hash; +} + +} + +} \ No newline at end of file diff --git a/icnet/utils/icnet_utils_hash.h b/icnet/utils/icnet_utils_hash.h new file mode 100644 index 00000000..9ae01f39 --- /dev/null +++ b/icnet/utils/icnet_utils_hash.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 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 +#include + +namespace icnet { + +namespace utils { + +//const uint32_t FNV1A_PRIME_32 = 0x01000193; +//const uint32_t FNV1A_OFFSET_32 = 0x811C9DC5; +//const uint64_t FNV1A_PRIME_64 = 0x00000100000001B3ULL; +//const uint64_t FNV1A_OFFSET_64 = 0xCBF29CE484222325ULL; + +class Hash { + public: + static uint32_t cumulativeHash32(const void *data, std::size_t len, uint32_t lastValue); + static uint64_t cumulativeHash64(const void *data, std::size_t len, uint64_t lastValue); + static uint32_t hash32(const void *data, std::size_t len); + static uint64_t hash64(const void *data, std::size_t len); + private: + +}; + +} + +} \ No newline at end of file diff --git a/icnet/utils/icnet_utils_string_tokenizer.cc b/icnet/utils/icnet_utils_string_tokenizer.cc new file mode 100644 index 00000000..ead1052a --- /dev/null +++ b/icnet/utils/icnet_utils_string_tokenizer.cc @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 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 +#include "icnet_utils_string_tokenizer.h" +#include "icnet_errors.h" + +namespace icnet { + +namespace utils { + +StringTokenizer::StringTokenizer(const std::string &str) + : str_(str), delimiter_(" ") { +} + +StringTokenizer::StringTokenizer(const std::string &str, const std::string &delim) + : str_(str), delimiter_(delim) { +} + +bool StringTokenizer::hasMoreTokens() { + return str_.find(delimiter_) != std::string::npos && !str_.empty(); +} + +std::string StringTokenizer::nextToken() { + unsigned long pos = str_.find(delimiter_); + + bool token_found = std::string::npos != pos; + + if (!token_found && str_.empty()) { + throw errors::TokenizerException(); + } + + std::string token = str_.substr(0, pos); + str_.erase(0, token_found ? pos + delimiter_.length() : pos); + + return token; +} + +} +} \ No newline at end of file diff --git a/icnet/utils/icnet_utils_string_tokenizer.h b/icnet/utils/icnet_utils_string_tokenizer.h new file mode 100644 index 00000000..7dc6b458 --- /dev/null +++ b/icnet/utils/icnet_utils_string_tokenizer.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 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 + +namespace icnet { + +namespace utils { + +class StringTokenizer { + public: + StringTokenizer(const std::string &str); + StringTokenizer(const std::string &str, const std::string &delim); + + bool hasMoreTokens(); + std::string nextToken(); + private: + std::string str_; + std::string delimiter_; +}; + +} + +} diff --git a/icnet/utils/icnet_utils_uri.cc b/icnet/utils/icnet_utils_uri.cc new file mode 100644 index 00000000..8268bdf9 --- /dev/null +++ b/icnet/utils/icnet_utils_uri.cc @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2017 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 "icnet_utils_uri.h" +#include "icnet_errors_runtime_exception.h" + +namespace icnet { + +namespace utils { + +Uri::Uri() { + +} + +Uri &Uri::parse(const std::string &uri) { + if (uri.length() == 0) { + throw errors::RuntimeException("Malformed URI."); + } + + iterator_t uriEnd = uri.end(); + + // get query start + iterator_t queryStart = std::find(uri.begin(), uriEnd, '?'); + + // protocol + iterator_t protocolStart = uri.begin(); + iterator_t protocolEnd = std::find(protocolStart, uriEnd, ':'); //"://"); + + if (protocolEnd != uriEnd) { + std::string prot = &*(protocolEnd); + if ((prot.length() > 3) && (prot.substr(0, 3) == "://")) { + protocol_ = std::string(protocolStart, protocolEnd); + protocolEnd += 3; // :// + } else { + protocolEnd = uri.begin(); // no protocol + } + } else { + protocolEnd = uri.begin(); // no protocol + } + // host + iterator_t hostStart = protocolEnd; + iterator_t pathStart = std::find(hostStart, uriEnd, '/'); // get pathStart + + iterator_t hostEnd = std::find(protocolEnd, + (pathStart != uriEnd) ? pathStart : queryStart, + ':'); // check for port + + locator_ = std::string(hostStart, hostEnd); + + // port + if ((hostEnd != uriEnd) && ((&*(hostEnd))[0] == ':')) { + hostEnd++; + iterator_t portEnd = (pathStart != uriEnd) ? pathStart : queryStart; + port_ = std::string(hostEnd, portEnd); + } + + // path + if (pathStart != uriEnd) { + path_ = std::string(pathStart, queryStart); + } + // query + if (queryStart != uriEnd) { + query_string_ = std::string(queryStart, uri.end()); + } + + return *this; + +} + +Uri &Uri::parseProtocolAndLocator(const std::string &locator) { + + iterator_t total_end = locator.end(); + + // protocol + iterator_t protocol_start = locator.begin(); + iterator_t protocol_end = std::find(protocol_start, total_end, ':'); //"://"); + + if (protocol_end != total_end) { + std::string prot = &*(protocol_end); + if ((prot.length() > 3) && (prot.substr(0, 3) == "://")) { + protocol_ = std::string(protocol_start, protocol_end); + protocol_end += 3; // :// + } else { + throw errors::RuntimeException("Malformed locator. (Missing \"://\")"); + } + } else { + throw errors::RuntimeException("Malformed locator. No protocol specified."); + } + + // locator + iterator_t host_start = protocol_end; + iterator_t host_end = std::find(protocol_end, total_end, '/'); + + if (host_start == host_end) { + throw errors::RuntimeException("Malformed locator. Locator name is missing"); + } + + locator_ = std::string(host_start, host_end); + + return *this; +} + +std::string Uri::getLocator() { + return locator_; +} + +std::string Uri::getPath() { + return path_; +} + +std::string Uri::getPort() { + return port_; +} + +std::string Uri::getProtocol() { + return protocol_; +} + +std::string Uri::getQueryString() { + return query_string_; +} + +} // end namespace utils + +} // end namespace icnet \ No newline at end of file diff --git a/icnet/utils/icnet_utils_uri.h b/icnet/utils/icnet_utils_uri.h new file mode 100644 index 00000000..38172282 --- /dev/null +++ b/icnet/utils/icnet_utils_uri.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 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 +#include // find + +namespace icnet { + +namespace utils { + +class Uri { + + typedef std::string::const_iterator iterator_t; + + public: + Uri(); + + Uri &parse(const std::string &uri); + + Uri &parseProtocolAndLocator(const std::string &locator); + + std::string getQueryString(); + + std::string getPath(); + + std::string getProtocol(); + + std::string getLocator(); + + std::string getPort(); + private: + std::string query_string_, path_, protocol_, locator_, port_; +}; // uri + +} + +} \ No newline at end of file -- cgit 1.2.3-korg