aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Muscariello <muscariello@ieee.org>2021-04-15 09:05:46 +0200
committerMauro Sardara <msardara@cisco.com>2021-04-15 16:36:16 +0200
commite92e9e839ca2cf42b56322b2489ccc0d8bf767af (patch)
tree9f1647c83a87fbf982ae329e800af25dbfb226b5
parent3e541d7c947cc2f9db145f26c9274efd29a6fb56 (diff)
[HICN-690] Transport Library Major Refactory
The current patch provides a major refactory of the transportlibrary. A summary of the different components that underwent major modifications is reported below. - Transport protocol updates The hierarchy of classes has been optimized to have common transport services across different transport protocols. This can allow to customize a transport protocol with new features. - A new real-time communication protocol The RTC protocol has been optimized in terms of algorithms to reduce consumer-producer synchronization latency. - A novel socket API The API has been reworked to be easier to consumer but also to have a more efficient integration in L4 proxies. - Several performance improvements A large number of performance improvements have been included in particular to make the entire stack zero-copy and optimize cache miss. - New memory buffer framework Memory management has been reworked entirely to provide a more efficient infra with a richer API. Buffers are now allocated in blocks and a single buffer holds the memory for (1) the shared_ptr control block, (2) the metadata of the packet (e.g. name, pointer to other buffers if buffer is chained and relevant offsets), and (3) the packet itself, as it is sent/received over the network. - A new slab allocator Dynamic memory allocation is now managed by a novel slab allocator that is optimised for packet processing and connection management. Memory is organized in pools of blocks all of the same size which are used during the processing of outgoing/incoming packets. When a memory block Is allocated is always taken from a global pool and when it is deallocated is returned to the pool, thus avoiding the cost of any heap allocation in the data path. - New transport connectors Consumer and producer end-points can communication either using an hicn packet forwarder or with direct connector based on shared memories or sockets. The usage of transport connectors typically for unit and funcitonal testing but may have additional usage. - Support for FEC/ECC for transport services FEC/ECC via reed solomon is supported by default and made available to transport services as a modular component. Reed solomon block codes is a default FEC model that can be replaced in a modular way by many other codes including RLNC not avaiable in this distribution. The current FEC framework support variable size padding and efficiently makes use of the infra memory buffers to avoid additiona copies. - Secure transport framework for signature computation and verification Crypto support is nativelty used in hICN for integrity and authenticity. Novel support that includes RTC has been implemented and made modular and reusable acrosso different transport protocols. - TLS - Transport layer security over hicn Point to point confidentiality is provided by integrating TLS on top of hICN reliable and non-reliable transport. The integration is common and makes a different use of the TLS record. - MLS - Messaging layer security over hicn MLS integration on top of hICN is made by using the MLSPP implemetation open sourced by Cisco. We have included instrumentation tools to deploy performance and functional tests of groups of end-points. - Android support The overall code has been heavily tested in Android environments and has received heavy lifting to better run natively in recent Android OS. Co-authored-by: Mauro Sardara <msardara@cisco.com> Co-authored-by: Michele Papalini <micpapal@cisco.com> Co-authored-by: Olivier Roques <oroques+fdio@cisco.com> Co-authored-by: Giulio Grassi <gigrassi@cisco.com> Change-Id: If477ba2fa686e6f47bdf96307ac60938766aef69 Signed-off-by: Luca Muscariello <muscariello@ieee.org>
-rw-r--r--CMakeLists.txt3
-rw-r--r--apps/.clang-format14
-rw-r--r--apps/CMakeLists.txt8
-rw-r--r--apps/higet/higet.cc12
-rw-r--r--apps/http-proxy/src/forwarder_interface.cc3
-rw-r--r--apps/http-proxy/src/http_proxy.cc1
-rw-r--r--apps/http-proxy/src/icn_receiver.cc2
-rw-r--r--cmake/Modules/BuildMacros.cmake87
-rw-r--r--cmake/Modules/FindLibFec.cmake24
-rw-r--r--cmake/Modules/FindLibRely.cmake24
-rw-r--r--cmake/Modules/FindLibconfig++.cmake43
-rw-r--r--cmake/Modules/FindLibconfig.cmake43
-rw-r--r--cmake/Modules/FindLibhicn.cmake2
-rw-r--r--cmake/Modules/GTestImport.cmake7
-rw-r--r--cmake/Modules/ServiceScript.cmake2
-rw-r--r--ctrl/facemgr/CMakeLists.txt2
-rw-r--r--ctrl/facemgr/src/CMakeLists.txt6
-rw-r--r--ctrl/libhicnctrl/src/CMakeLists.txt2
-rw-r--r--ctrl/libhicnctrl/src/hicn_plugin_api.c10
-rw-r--r--docs/source/index.rst1
-rw-r--r--extras/CMakeLists.txt1
-rw-r--r--extras/libmemif/CMakeLists2.patch2
-rw-r--r--hicn-light/src/hicn/CMakeLists.txt2
-rw-r--r--hicn-light/src/hicn/core/message.c3
-rw-r--r--hicn-light/src/hicn/core/messageHandler.h36
-rw-r--r--hicn-plugin/src/CMakeLists.txt14
-rw-r--r--hicn-plugin/src/faces/face.c1
-rw-r--r--hicn-plugin/src/faces/face.h5
-rw-r--r--hicn-plugin/src/faces/iface_node.c10
-rw-r--r--hicn-plugin/src/hicn.h1
-rw-r--r--hicn-plugin/src/interest_hitcs_node.c3
-rw-r--r--hicn-plugin/vapi/CMakeLists.txt2
-rw-r--r--lib/.clang-format21
-rw-r--r--lib/includes/hicn/base.h18
-rw-r--r--lib/includes/hicn/common.h9
-rw-r--r--lib/includes/hicn/compat.h299
-rw-r--r--lib/includes/hicn/ops.h14
-rw-r--r--lib/src/CMakeLists.txt4
-rw-r--r--lib/src/common.c12
-rw-r--r--lib/src/compat.c472
-rw-r--r--lib/src/name.c2
-rw-r--r--lib/src/protocol/ah.c2
-rw-r--r--lib/src/protocol/icmp.c2
-rw-r--r--lib/src/protocol/ipv4.c4
-rw-r--r--lib/src/protocol/ipv6.c20
-rw-r--r--lib/src/protocol/tcp.c28
-rw-r--r--libtransport/CMakeLists.txt60
-rw-r--r--libtransport/includes/hicn/transport/CMakeLists.txt4
-rw-r--r--libtransport/includes/hicn/transport/auth/CMakeLists.txt29
-rw-r--r--libtransport/includes/hicn/transport/auth/common.h29
-rw-r--r--libtransport/includes/hicn/transport/auth/crypto_hash.h121
-rw-r--r--libtransport/includes/hicn/transport/auth/crypto_hash_type.h35
-rw-r--r--libtransport/includes/hicn/transport/auth/crypto_hasher.h70
-rw-r--r--libtransport/includes/hicn/transport/auth/crypto_suite.h39
-rw-r--r--libtransport/includes/hicn/transport/auth/identity.h66
-rw-r--r--libtransport/includes/hicn/transport/auth/key_id.h27
-rw-r--r--libtransport/includes/hicn/transport/auth/policies.h33
-rw-r--r--libtransport/includes/hicn/transport/auth/signer.h92
-rw-r--r--libtransport/includes/hicn/transport/auth/verifier.h169
-rw-r--r--libtransport/includes/hicn/transport/core/CMakeLists.txt4
-rw-r--r--libtransport/includes/hicn/transport/core/connector.h212
-rw-r--r--libtransport/includes/hicn/transport/core/connector_stats.h40
-rw-r--r--libtransport/includes/hicn/transport/core/content_object.h50
-rw-r--r--libtransport/includes/hicn/transport/core/endpoint.h80
-rw-r--r--libtransport/includes/hicn/transport/core/global_object_pool.h122
-rw-r--r--libtransport/includes/hicn/transport/core/interest.h78
-rw-r--r--libtransport/includes/hicn/transport/core/io_module.h127
-rw-r--r--libtransport/includes/hicn/transport/core/name.h6
-rw-r--r--libtransport/includes/hicn/transport/core/packet.h143
-rw-r--r--libtransport/includes/hicn/transport/core/payload_type.h3
-rw-r--r--libtransport/includes/hicn/transport/core/prefix.h8
-rw-r--r--libtransport/includes/hicn/transport/errors/errors.h5
-rw-r--r--libtransport/includes/hicn/transport/http/client_connection.h4
-rw-r--r--libtransport/includes/hicn/transport/interfaces/CMakeLists.txt3
-rw-r--r--libtransport/includes/hicn/transport/interfaces/callbacks.h21
-rw-r--r--libtransport/includes/hicn/transport/interfaces/global_conf_interface.h60
-rw-r--r--libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h5
-rw-r--r--libtransport/includes/hicn/transport/interfaces/portal.h8
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_consumer.h30
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h1
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_options_keys.h11
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_producer.h49
-rw-r--r--libtransport/includes/hicn/transport/interfaces/statistics.h79
-rw-r--r--libtransport/includes/hicn/transport/portability/c_portability.h2
-rw-r--r--libtransport/includes/hicn/transport/portability/platform.h108
-rw-r--r--libtransport/includes/hicn/transport/portability/portability.h2
-rw-r--r--libtransport/includes/hicn/transport/portability/win_portability.h1
-rw-r--r--libtransport/includes/hicn/transport/utils/CMakeLists.txt5
-rw-r--r--libtransport/includes/hicn/transport/utils/conversions.h2
-rw-r--r--libtransport/includes/hicn/transport/utils/enum_iterator.h43
-rw-r--r--libtransport/includes/hicn/transport/utils/event_thread.h63
-rw-r--r--libtransport/includes/hicn/transport/utils/file.h28
-rw-r--r--libtransport/includes/hicn/transport/utils/fixed_block_allocator.h209
-rw-r--r--libtransport/includes/hicn/transport/utils/linux.h4
-rw-r--r--libtransport/includes/hicn/transport/utils/membuf.h32
-rw-r--r--libtransport/includes/hicn/transport/utils/move_wrapper.h39
-rw-r--r--libtransport/includes/hicn/transport/utils/noncopyable.h29
-rw-r--r--libtransport/includes/hicn/transport/utils/object_pool.h25
-rw-r--r--libtransport/includes/hicn/transport/utils/shared_ptr_utils.h28
-rw-r--r--libtransport/includes/hicn/transport/utils/singleton.h39
-rw-r--r--libtransport/includes/hicn/transport/utils/string_utils.h2
-rw-r--r--libtransport/src/CMakeLists.txt28
-rw-r--r--libtransport/src/auth/CMakeLists.txt22
-rw-r--r--libtransport/src/auth/identity.cc116
-rw-r--r--libtransport/src/auth/signer.cc208
-rw-r--r--libtransport/src/auth/verifier.cc335
-rw-r--r--libtransport/src/config.h.in4
-rw-r--r--libtransport/src/core/CMakeLists.txt50
-rw-r--r--libtransport/src/core/content_object.cc45
-rw-r--r--libtransport/src/core/errors.cc49
-rw-r--r--libtransport/src/core/errors.h87
-rw-r--r--libtransport/src/core/facade.h22
-rw-r--r--libtransport/src/core/fec.cc878
-rw-r--r--libtransport/src/core/fec.h65
-rw-r--r--libtransport/src/core/global_configuration.cc173
-rw-r--r--libtransport/src/core/global_configuration.h102
-rw-r--r--libtransport/src/core/interest.cc82
-rw-r--r--libtransport/src/core/io_module.cc84
-rw-r--r--libtransport/src/core/local_connector.cc47
-rw-r--r--libtransport/src/core/local_connector.h62
-rw-r--r--libtransport/src/core/manifest.h19
-rw-r--r--libtransport/src/core/manifest_format.h10
-rw-r--r--libtransport/src/core/manifest_format_fixed.cc43
-rw-r--r--libtransport/src/core/manifest_format_fixed.h19
-rw-r--r--libtransport/src/core/manifest_inline.h37
-rw-r--r--libtransport/src/core/name.cc10
-rw-r--r--libtransport/src/core/packet.cc370
-rw-r--r--libtransport/src/core/pending_interest.h16
-rw-r--r--libtransport/src/core/portal.cc147
-rw-r--r--libtransport/src/core/portal.h285
-rw-r--r--libtransport/src/core/prefix.cc14
-rw-r--r--libtransport/src/core/rs.cc365
-rw-r--r--libtransport/src/core/rs.h338
-rw-r--r--libtransport/src/core/tcp_socket_connector.h3
-rw-r--r--libtransport/src/http/client_connection.cc31
-rw-r--r--libtransport/src/implementation/CMakeLists.txt10
-rw-r--r--libtransport/src/implementation/p2psecure_socket_consumer.cc2
-rw-r--r--libtransport/src/implementation/p2psecure_socket_consumer.h2
-rw-r--r--libtransport/src/implementation/p2psecure_socket_producer.cc149
-rw-r--r--libtransport/src/implementation/p2psecure_socket_producer.h44
-rw-r--r--libtransport/src/implementation/socket.cc26
-rw-r--r--libtransport/src/implementation/socket.h52
-rw-r--r--libtransport/src/implementation/socket_consumer.h194
-rw-r--r--libtransport/src/implementation/socket_producer.h632
-rw-r--r--libtransport/src/implementation/tls_rtc_socket_producer.cc2
-rw-r--r--libtransport/src/implementation/tls_rtc_socket_producer.h7
-rw-r--r--libtransport/src/implementation/tls_socket_consumer.cc8
-rw-r--r--libtransport/src/implementation/tls_socket_consumer.h3
-rw-r--r--libtransport/src/implementation/tls_socket_producer.cc174
-rw-r--r--libtransport/src/implementation/tls_socket_producer.h33
-rw-r--r--libtransport/src/interfaces/CMakeLists.txt6
-rw-r--r--libtransport/src/interfaces/global_configuration.cc50
-rw-r--r--libtransport/src/interfaces/p2psecure_socket_consumer.cc1
-rw-r--r--libtransport/src/interfaces/p2psecure_socket_producer.cc3
-rw-r--r--libtransport/src/interfaces/portal.cc37
-rw-r--r--libtransport/src/interfaces/socket_consumer.cc30
-rw-r--r--libtransport/src/interfaces/socket_producer.cc78
-rw-r--r--libtransport/src/interfaces/tls_rtc_socket_producer.cc3
-rw-r--r--libtransport/src/interfaces/tls_socket_consumer.cc3
-rw-r--r--libtransport/src/interfaces/tls_socket_producer.cc3
-rw-r--r--libtransport/src/io_modules/CMakeLists.txt37
-rw-r--r--libtransport/src/io_modules/forwarder/CMakeLists.txt44
-rw-r--r--libtransport/src/io_modules/forwarder/configuration.h89
-rw-r--r--libtransport/src/io_modules/forwarder/errors.cc52
-rw-r--r--libtransport/src/io_modules/forwarder/errors.h91
-rw-r--r--libtransport/src/io_modules/forwarder/forwarder.cc296
-rw-r--r--libtransport/src/io_modules/forwarder/forwarder.h90
-rw-r--r--libtransport/src/io_modules/forwarder/forwarder_module.cc87
-rw-r--r--libtransport/src/io_modules/forwarder/forwarder_module.h70
-rw-r--r--libtransport/src/io_modules/forwarder/global_id_counter.h54
-rw-r--r--libtransport/src/io_modules/forwarder/udp_tunnel.cc288
-rw-r--r--libtransport/src/io_modules/forwarder/udp_tunnel.h147
-rw-r--r--libtransport/src/io_modules/forwarder/udp_tunnel_listener.cc177
-rw-r--r--libtransport/src/io_modules/forwarder/udp_tunnel_listener.h110
-rw-r--r--libtransport/src/io_modules/loopback/CMakeLists.txt34
-rw-r--r--libtransport/src/io_modules/loopback/local_face.cc69
-rw-r--r--libtransport/src/io_modules/loopback/local_face.h54
-rw-r--r--libtransport/src/io_modules/loopback/loopback_module.cc84
-rw-r--r--libtransport/src/io_modules/loopback/loopback_module.h70
-rw-r--r--libtransport/src/io_modules/memif/CMakeLists.txt56
-rw-r--r--libtransport/src/io_modules/memif/hicn_vapi.c229
-rw-r--r--libtransport/src/io_modules/memif/hicn_vapi.h82
-rw-r--r--libtransport/src/io_modules/memif/memif_connector.cc493
-rw-r--r--libtransport/src/io_modules/memif/memif_connector.h130
-rw-r--r--libtransport/src/io_modules/memif/memif_vapi.c127
-rw-r--r--libtransport/src/io_modules/memif/memif_vapi.h54
-rw-r--r--libtransport/src/io_modules/memif/vpp_forwarder_module.cc263
-rw-r--r--libtransport/src/io_modules/memif/vpp_forwarder_module.h83
-rw-r--r--libtransport/src/io_modules/raw_socket/raw_socket_connector.cc201
-rw-r--r--libtransport/src/io_modules/raw_socket/raw_socket_connector.h80
-rw-r--r--libtransport/src/io_modules/raw_socket/raw_socket_interface.cc56
-rw-r--r--libtransport/src/io_modules/raw_socket/raw_socket_interface.h61
-rw-r--r--libtransport/src/io_modules/udp/CMakeLists.txt47
-rw-r--r--libtransport/src/io_modules/udp/hicn_forwarder_module.cc181
-rw-r--r--libtransport/src/io_modules/udp/hicn_forwarder_module.h86
-rw-r--r--libtransport/src/io_modules/udp/udp_socket_connector.cc211
-rw-r--r--libtransport/src/io_modules/udp/udp_socket_connector.h89
-rw-r--r--libtransport/src/protocols/CMakeLists.txt21
-rw-r--r--libtransport/src/protocols/byte_stream_reassembly.cc49
-rw-r--r--libtransport/src/protocols/byte_stream_reassembly.h4
-rw-r--r--libtransport/src/protocols/data_processing_events.h3
-rw-r--r--libtransport/src/protocols/datagram_reassembly.cc4
-rw-r--r--libtransport/src/protocols/datagram_reassembly.h2
-rw-r--r--libtransport/src/protocols/errors.cc4
-rw-r--r--libtransport/src/protocols/fec_base.h86
-rw-r--r--libtransport/src/protocols/incremental_indexer.cc31
-rw-r--r--libtransport/src/protocols/incremental_indexer.h35
-rw-r--r--libtransport/src/protocols/indexer.cc24
-rw-r--r--libtransport/src/protocols/indexer.h16
-rw-r--r--libtransport/src/protocols/manifest_incremental_indexer.cc215
-rw-r--r--libtransport/src/protocols/manifest_incremental_indexer.h39
-rw-r--r--libtransport/src/protocols/prod_protocol_bytestream.cc390
-rw-r--r--libtransport/src/protocols/prod_protocol_bytestream.h72
-rw-r--r--libtransport/src/protocols/prod_protocol_rtc.cc481
-rw-r--r--libtransport/src/protocols/prod_protocol_rtc.h127
-rw-r--r--libtransport/src/protocols/production_protocol.cc135
-rw-r--r--libtransport/src/protocols/production_protocol.h108
-rw-r--r--libtransport/src/protocols/raaqm.cc58
-rw-r--r--libtransport/src/protocols/raaqm.h15
-rw-r--r--libtransport/src/protocols/raaqm_data_path.cc1
-rw-r--r--libtransport/src/protocols/raaqm_data_path.h1
-rw-r--r--libtransport/src/protocols/rate_estimation.cc1
-rw-r--r--libtransport/src/protocols/rate_estimation.h1
-rw-r--r--libtransport/src/protocols/reassembly.cc1
-rw-r--r--libtransport/src/protocols/reassembly.h2
-rw-r--r--libtransport/src/protocols/rtc/CMakeLists.txt38
-rw-r--r--libtransport/src/protocols/rtc/congestion_detection.cc101
-rw-r--r--libtransport/src/protocols/rtc/congestion_detection.h138
-rw-r--r--libtransport/src/protocols/rtc/probe_handler.cc107
-rw-r--r--libtransport/src/protocols/rtc/probe_handler.h75
-rw-r--r--libtransport/src/protocols/rtc/rtc.cc607
-rw-r--r--libtransport/src/protocols/rtc/rtc.h113
-rw-r--r--libtransport/src/protocols/rtc/rtc_consts.h121
-rw-r--r--libtransport/src/protocols/rtc/rtc_data_path.cc197
-rw-r--r--libtransport/src/protocols/rtc/rtc_data_path.h97
-rw-r--r--libtransport/src/protocols/rtc/rtc_ldr.cc427
-rw-r--r--libtransport/src/protocols/rtc/rtc_ldr.h108
-rw-r--r--libtransport/src/protocols/rtc/rtc_packet.h89
-rw-r--r--libtransport/src/protocols/rtc/rtc_rc.h58
-rw-r--r--libtransport/src/protocols/rtc/rtc_rc_frame.cc79
-rw-r--r--libtransport/src/protocols/rtc/rtc_rc_frame.h46
-rw-r--r--libtransport/src/protocols/rtc/rtc_rc_queue.cc106
-rw-r--r--libtransport/src/protocols/rtc/rtc_rc_queue.h47
-rw-r--r--libtransport/src/protocols/rtc/rtc_state.cc560
-rw-r--r--libtransport/src/protocols/rtc/rtc_state.h253
-rw-r--r--libtransport/src/protocols/rtc/trendline_estimator.cc334
-rw-r--r--libtransport/src/protocols/rtc/trendline_estimator.h147
-rw-r--r--libtransport/src/protocols/transport_protocol.cc132
-rw-r--r--libtransport/src/protocols/transport_protocol.h104
-rw-r--r--libtransport/src/test/CMakeLists.txt13
-rw-r--r--libtransport/src/test/fec_reed_solomon.cc154
-rw-r--r--libtransport/src/test/fec_rely.cc156
-rw-r--r--libtransport/src/test/packet_samples.h58
-rw-r--r--libtransport/src/test/test_auth.cc110
-rw-r--r--libtransport/src/test/test_consumer_producer_rtc.cc176
-rw-r--r--libtransport/src/test/test_core_manifest.cc44
-rw-r--r--libtransport/src/test/test_event_thread.cc106
-rw-r--r--libtransport/src/test/test_fec_reedsolomon.cc291
-rw-r--r--libtransport/src/test/test_interest.cc267
-rw-r--r--libtransport/src/test/test_packet.cc1047
-rw-r--r--libtransport/src/transport.config27
-rw-r--r--libtransport/src/utils/content_store.cc4
-rw-r--r--libtransport/src/utils/content_store.h2
-rw-r--r--libtransport/src/utils/daemonizator.cc1
-rw-r--r--libtransport/src/utils/epoll_event_reactor.cc7
-rw-r--r--libtransport/src/utils/epoll_event_reactor.h2
-rw-r--r--libtransport/src/utils/fd_deadline_timer.h6
-rw-r--r--libtransport/src/utils/membuf.cc44
-rw-r--r--libtransport/src/utils/memory_pool_allocator.h2
-rw-r--r--libtransport/src/utils/min_filter.h5
-rw-r--r--scripts/build-packages.sh20
-rw-r--r--scripts/functions.sh23
-rw-r--r--utils/.clang-format14
-rw-r--r--utils/src/hiperf.cc635
-rw-r--r--utils/src/ping_client.cc55
-rw-r--r--utils/src/ping_server.cc33
276 files changed, 20362 insertions, 3007 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d6d67ec..31f40aa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,7 +35,6 @@ endif ()
option(BUILD_HICNPLUGIN "Build the hicn vpp plugin" OFF)
option(BUILD_SYSREPOPLUGIN "Build the sysrepo plugin" OFF)
option(BUILD_EXTRAS "Build external projects" OFF)
-option(BUILD_WSPLUGIN "Build the hicn plugin for wireshark" OFF)
option(BUILD_TELEMETRY "Build telemetry projects" OFF)
option(BUILD_TESTS "Build unit tests" OFF)
option(DISABLE_EXECUTABLES "Disable executables" OFF)
@@ -72,7 +71,6 @@ list(APPEND dir_options
BUILD_APPS
BUILD_SYSREPOPLUGIN
BUILD_EXTRAS
- BUILD_WSPLUGIN
BUILD_TELEMETRY
)
@@ -85,7 +83,6 @@ set(BUILD_CTRL_DIR ctrl)
set(BUILD_HICNPLUGIN_DIR hicn-plugin)
set(BUILD_SYSREPOPLUGIN_DIR ctrl/sysrepo-plugins)
set(BUILD_EXTRAS_DIR extras/)
-set(BUILD_WSPLUGIN_DIR extras/packethicn)
set(BUILD_TELEMETRY_DIR telemetry)
## Add enabled components
diff --git a/apps/.clang-format b/apps/.clang-format
new file mode 100644
index 0000000..cd21e20
--- /dev/null
+++ b/apps/.clang-format
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2021 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+BasedOnStyle: Google
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
index 5737a1d..9b90118 100644
--- a/apps/CMakeLists.txt
+++ b/apps/CMakeLists.txt
@@ -49,15 +49,11 @@ else()
)
endif()
-set(SUFFIX "")
-if (${LIBTRANSPORT_LIBRARIES} MATCHES ".*-memif.*")
- set(DEPENDENCIES ${LIBMEMIF_SHARED})
- set(SUFFIX "-memif")
+# Worksroung for unresolved symbols in vpp libraries
+if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
set(LINK_FLAGS "-Wl,-unresolved-symbols=ignore-in-shared-libs")
endif()
-set(HICN_APPS "${HICN_APPS}${SUFFIX}")
-
list(APPEND LIBRARIES
${LIBTRANSPORT_LIBRARIES}
${LIBHICNCTRL_LIBRARIES}
diff --git a/apps/higet/higet.cc b/apps/higet/higet.cc
index 7584148..194e616 100644
--- a/apps/higet/higet.cc
+++ b/apps/higet/higet.cc
@@ -14,10 +14,11 @@
*/
#include <hicn/transport/http/client_connection.h>
-#include <fstream>
-#include <map>
+
#include <algorithm>
+#include <fstream>
#include <functional>
+#include <map>
#define ASIO_STANDALONE
#include <asio.hpp>
@@ -334,9 +335,14 @@ int main(int argc, char **argv) {
{"Connection", "Keep-Alive"},
{"Range", range}};
}
+
transport::http::HTTPClientConnection connection;
+
if (!conf.producer_certificate.empty()) {
- connection.setCertificate(conf.producer_certificate);
+ std::shared_ptr<transport::auth::Verifier> verifier =
+ std::make_shared<transport::auth::AsymmetricVerifier>(
+ conf.producer_certificate);
+ connection.setVerifier(verifier);
}
t1 = std::chrono::system_clock::now();
diff --git a/apps/http-proxy/src/forwarder_interface.cc b/apps/http-proxy/src/forwarder_interface.cc
index d80939b..7d8235a 100644
--- a/apps/http-proxy/src/forwarder_interface.cc
+++ b/apps/http-proxy/src/forwarder_interface.cc
@@ -13,9 +13,8 @@
* limitations under the License.
*/
-#include <hicn/http-proxy/forwarder_interface.h>
-
#include <arpa/inet.h>
+#include <hicn/http-proxy/forwarder_interface.h>
#include <hicn/transport/utils/log.h>
#include <chrono>
diff --git a/apps/http-proxy/src/http_proxy.cc b/apps/http-proxy/src/http_proxy.cc
index 262fcb8..c252afe 100644
--- a/apps/http-proxy/src/http_proxy.cc
+++ b/apps/http-proxy/src/http_proxy.cc
@@ -225,6 +225,7 @@ class HTTPClientConnectionCallback : interface::ConsumerSocket::ReadCallback {
const char* reply = nullptr;
if (result) {
reply = HTTPMessageFastParser::http_ok;
+ prefix_hash_ = configured_prefix;
} else {
reply = HTTPMessageFastParser::http_failed;
}
diff --git a/apps/http-proxy/src/icn_receiver.cc b/apps/http-proxy/src/icn_receiver.cc
index 8823907..23e5b56 100644
--- a/apps/http-proxy/src/icn_receiver.cc
+++ b/apps/http-proxy/src/icn_receiver.cc
@@ -189,7 +189,7 @@ void AsyncConsumerProducer::publishContent(const uint8_t* data,
}
it->second.first +=
- producer_socket_.produce(name, data, size, is_last, start_suffix);
+ producer_socket_.produceStream(name, data, size, is_last, start_suffix);
if (is_last) {
it->second.second = false;
diff --git a/cmake/Modules/BuildMacros.cmake b/cmake/Modules/BuildMacros.cmake
index 7119541..4c55f32 100644
--- a/cmake/Modules/BuildMacros.cmake
+++ b/cmake/Modules/BuildMacros.cmake
@@ -21,7 +21,7 @@ macro(build_executable exec)
cmake_parse_arguments(ARG
"NO_INSTALL"
"COMPONENT"
- "SOURCES;LINK_LIBRARIES;DEPENDS;INCLUDE_DIRS;DEFINITIONS;LINK_FLAGS"
+ "SOURCES;LINK_LIBRARIES;DEPENDS;INCLUDE_DIRS;DEFINITIONS;COMPILE_OPTIONS;LINK_FLAGS"
${ARGN}
)
@@ -48,6 +48,10 @@ macro(build_executable exec)
add_dependencies(${exec}-bin ${ARG_DEPENDS})
endif()
+ if (ARG_COMPILE_OPTIONS)
+ target_compile_options(${exec}-bin ${ARG_COMPILE_OPTIONS})
+ endif()
+
if(ARG_DEFINITIONS)
target_compile_definitions(${exec}-bin PRIVATE ${ARG_DEFINITIONS})
endif()
@@ -71,12 +75,17 @@ endmacro()
macro(build_library lib)
cmake_parse_arguments(ARG
- "SHARED;STATIC;MODULE;NO_DEV"
+ "SHARED;STATIC;NO_DEV"
"COMPONENT;"
- "SOURCES;LINK_LIBRARIES;INSTALL_HEADERS;DEPENDS;INCLUDE_DIRS;DEFINITIONS;INSTALL_ROOT_DIR;INSTALL_FULL_PATH_DIR;EMPTY_PREFIX;"
+ "SOURCES;LINK_LIBRARIES;INSTALL_HEADERS;DEPENDS;INCLUDE_DIRS;DEFINITIONS;HEADER_ROOT_DIR;LIBRARY_ROOT_DIR;INSTALL_FULL_PATH_DIR;EMPTY_PREFIX;COMPILE_OPTIONS;VERSION"
${ARGN}
)
+ message(STATUS "Building library ${lib}")
+
+ # Clear target_libs
+ unset(TARGET_LIBS)
+
if (ARG_SHARED)
list(APPEND TARGET_LIBS
${lib}.shared
@@ -91,13 +100,6 @@ macro(build_library lib)
add_library(${lib}.static STATIC ${ARG_SOURCES})
endif()
- if(ARG_MODULE)
- list(APPEND TARGET_LIBS
- ${lib}.module
- )
- add_library(${lib}.module MODULE ${ARG_SOURCES})
- endif()
-
if(NOT ARG_COMPONENT)
set(ARG_COMPONENT hicn)
endif()
@@ -135,13 +137,13 @@ macro(build_library lib)
endif()
if (WIN32)
- target_compile_options(${library} PRIVATE)
+ target_compile_options(${library} PRIVATE ${ARG_COMPILE_OPTIONS})
set_target_properties(${library}
PROPERTIES
WINDOWS_EXPORT_ALL_SYMBOLS TRUE
)
else ()
- target_compile_options(${library} PRIVATE -Wall)
+ target_compile_options(${library} PRIVATE -Wall ${ARG_COMPILE_OPTIONS})
set_target_properties(${library}
PROPERTIES
OUTPUT_NAME ${lib}
@@ -164,7 +166,14 @@ macro(build_library lib)
)
endif()
- set(INSTALL_LIB_PATH ${CMAKE_INSTALL_LIBDIR})
+ if(ARG_VERSION)
+ set_target_properties(${library}
+ PROPERTIES
+ VERSION ${ARG_VERSION}
+ )
+ endif()
+
+ set(INSTALL_LIB_PATH "${CMAKE_INSTALL_LIBDIR}/${ARG_LIBRARY_ROOT_DIR}")
if (ARG_INSTALL_FULL_PATH_DIR)
set(INSTALL_LIB_PATH ${ARG_INSTALL_FULL_PATH_DIR})
@@ -185,8 +194,8 @@ macro(build_library lib)
# install headers
if(ARG_INSTALL_HEADERS)
- if (NOT ARG_INSTALL_ROOT_DIR)
- set(ARG_INSTALL_ROOT_DIR "hicn")
+ if (NOT ARG_HEADER_ROOT_DIR)
+ set(ARG_HEADER_ROOT_DIR "hicn")
endif()
list(APPEND local_comps
@@ -204,7 +213,7 @@ macro(build_library lib)
if ("${dir}" STREQUAL includes)
set(dir "")
endif()
- if ("${dir}" STREQUAL ${ARG_INSTALL_ROOT_DIR})
+ if ("${dir}" STREQUAL ${ARG_HEADER_ROOT_DIR})
set(dir "")
endif()
else()
@@ -217,12 +226,56 @@ macro(build_library lib)
endif()
install(
FILES ${file}
- DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${ARG_INSTALL_ROOT_DIR}/${dir}
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${ARG_HEADER_ROOT_DIR}/${dir}
COMPONENT ${COMPONENT}
)
endforeach()
endif()
endmacro()
+macro (build_module module)
+ cmake_parse_arguments(ARG
+ "SHARED;STATIC;NO_DEV"
+ "COMPONENT;"
+ "SOURCES;LINK_LIBRARIES;INSTALL_HEADERS;DEPENDS;INCLUDE_DIRS;DEFINITIONS;HEADER_ROOT_DIR;LIBRARY_ROOT_DIR;INSTALL_FULL_PATH_DIR;EMPTY_PREFIX;COMPILE_OPTIONS;VERSION"
+ ${ARGN}
+ )
+
+ message(STATUS "Building module ${module}")
+
+ build_library(${module}
+ SHARED
+ SOURCES ${ARG_SOURCES}
+ LINK_LIBRARIES ${ARG_LINK_LIBRARIES}
+ INSTALL_HEADERS ${ARG_INSTALL_HEADERS}
+ DEPENDS ${ARG_DEPENDS}
+ COMPONENT lib${LIBTRANSPORT}
+ INCLUDE_DIRS ${ARG_INCLUDE_DIRS}
+ HEADER_ROOT_DIR ${ARG_HEADER_ROOT_DIR}
+ LIBRARY_ROOT_DIR ${ARG_LIBRARY_ROOT_DIR}
+ INSTALL_FULL_PATH_DIR ${ARG_INSTALL_FULL_PATH_DIR}
+ DEFINITIONS ${ARG_DEFINITIONS}
+ EMPTY_PREFIX ${ARG_EMPTY_PREFIX}
+ COMPILE_OPTIONS ${ARG_COMPILE_OPTIONS}
+ VERSION ${ARG_VERSION}
+ )
+
+ if (${CMAKE_SYSTEM_NAME} MATCHES Darwin)
+ set(LINK_FLAGS "-Wl,-undefined,dynamic_lookup")
+ elseif(${CMAKE_SYSTEM_NAME} MATCHES Linux)
+ set(LINK_FLAGS "-Wl,-unresolved-symbols=ignore-all")
+ else()
+ message(FATAL_ERROR "Trying to build module on a not supportd platform. Aborting.")
+ endif()
+
+ set_target_properties(${module}.shared
+ PROPERTIES
+ LINKER_LANGUAGE C
+ PREFIX ""
+ LINK_FLAGS ${LINK_FLAGS}
+ )
+
+endmacro(build_module)
+
include(IosMacros)
include(WindowsMacros)
diff --git a/cmake/Modules/FindLibFec.cmake b/cmake/Modules/FindLibFec.cmake
new file mode 100644
index 0000000..f8b33ad
--- /dev/null
+++ b/cmake/Modules/FindLibFec.cmake
@@ -0,0 +1,24 @@
+set(LIBFEC_SEARCH_PATH_LIST
+ ${LIBFEC_HOME}
+ $ENV{DEPENDENCIES}
+ $ENV{LIBFEC_HOME}
+ /usr/local
+ /opt
+ /usr
+ )
+
+find_path(LIBFEC_INCLUDE_DIR fec/version.h
+ HINTS ${LIBFEC_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the LibFec includes" )
+
+find_library(LIBFEC_LIBRARY NAMES fec
+ HINTS ${LIBFEC_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the LibFec libraries" )
+
+set(LIBFEC_LIBRARIES ${LIBFEC_LIBRARY})
+set(LIBFEC_INCLUDE_DIRS ${LIBFEC_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibFec DEFAULT_MSG LIBFEC_LIBRARY LIBFEC_INCLUDE_DIR) \ No newline at end of file
diff --git a/cmake/Modules/FindLibRely.cmake b/cmake/Modules/FindLibRely.cmake
new file mode 100644
index 0000000..4b89600
--- /dev/null
+++ b/cmake/Modules/FindLibRely.cmake
@@ -0,0 +1,24 @@
+set(LIBRELY_SEARCH_PATH_LIST
+ ${LIBRELY_HOME}
+ $ENV{DEPENDENCIES}
+ $ENV{LIBRELY_HOME}
+ /usr/local
+ /opt
+ /usr
+ )
+
+find_path(LIBRELY_INCLUDE_DIR rely/version.hpp
+ HINTS ${LIBRELY_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the LibRely includes" )
+
+find_library(LIBRELY_LIBRARY NAMES rely
+ HINTS ${LIBRELY_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the LibRely libraries" )
+
+set(LIBRELY_LIBRARIES ${LIBRELY_LIBRARY})
+set(LIBRELY_INCLUDE_DIRS ${LIBRELY_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibRely DEFAULT_MSG LIBRELY_LIBRARY LIBRELY_INCLUDE_DIR) \ No newline at end of file
diff --git a/cmake/Modules/FindLibconfig++.cmake b/cmake/Modules/FindLibconfig++.cmake
new file mode 100644
index 0000000..865f750
--- /dev/null
+++ b/cmake/Modules/FindLibconfig++.cmake
@@ -0,0 +1,43 @@
+set(LIBCONFIG_SEARCH_PATH_LIST
+ ${LIBCONFIG_HOME}
+ $ENV{LIBCONFIG_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(LIBCONFIG_INCLUDE_DIR libconfig.h++
+ HINTS ${LIBCONFIG_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the libconfig include"
+)
+
+if (WIN32)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ find_library(LIBCONFIG_LIBRARY NAMES libconfig.lib
+ HINTS ${LIBCONFIG_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib/x64
+ DOC "Find the libconfig libraries"
+ )
+ elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ find_library(LIBCONFIG_LIBRARY NAMES libconfig.lib
+ HINTS ${LIBCONFIG_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib/x32
+ DOC "Find the libconfig libraries"
+ )
+ endif()
+else()
+ find_library(LIBCONFIG_CPP_LIBRARY NAMES config++
+ HINTS ${LIBCONFIG_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the libconfig++ libraries"
+ )
+endif()
+
+set(LIBCONFIG_CPP_LIBRARIES ${LIBCONFIG_CPP_LIBRARY})
+set(LIBCONFIG_INCLUDE_DIRS ${LIBCONFIG_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Libconfig++ LIBCONFIG_CPP_LIBRARIES LIBCONFIG_INCLUDE_DIRS)
+
+mark_as_advanced(LIBCONFIG_CPP_LIBRARIES LIBCONFIG_INCLUDE_DIRS)
diff --git a/cmake/Modules/FindLibconfig.cmake b/cmake/Modules/FindLibconfig.cmake
new file mode 100644
index 0000000..55d2a0f
--- /dev/null
+++ b/cmake/Modules/FindLibconfig.cmake
@@ -0,0 +1,43 @@
+set(LIBCONFIG_SEARCH_PATH_LIST
+ ${LIBCONFIG_HOME}
+ $ENV{LIBCONFIG_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(LIBCONFIG_INCLUDE_DIR libconfig.h
+ HINTS ${LIBCONFIG_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the libconfig include"
+)
+
+if (WIN32)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ find_library(LIBCONFIG_LIBRARY NAMES libconfig.lib
+ HINTS ${LIBCONFIG_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib/x64
+ DOC "Find the libconfig libraries"
+ )
+ elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ find_library(LIBCONFIG_LIBRARY NAMES libconfig.lib
+ HINTS ${LIBCONFIG_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib/x32
+ DOC "Find the libconfig libraries"
+ )
+ endif()
+else()
+ find_library(LIBCONFIG_LIBRARY NAMES config
+ HINTS ${LIBCONFIG_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the libconfig libraries"
+ )
+endif()
+
+set(LIBCONFIG_LIBRARIES ${LIBCONFIG_LIBRARY})
+set(LIBCONFIG_INCLUDE_DIRS ${LIBCONFIG_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Libconfig LIBCONFIG_LIBRARIES LIBCONFIG_INCLUDE_DIRS)
+
+mark_as_advanced(LIBCONFIG_LIBRARIES LIBCONFIG_INCLUDE_DIRS)
diff --git a/cmake/Modules/FindLibhicn.cmake b/cmake/Modules/FindLibhicn.cmake
index 38775be..5f241a6 100644
--- a/cmake/Modules/FindLibhicn.cmake
+++ b/cmake/Modules/FindLibhicn.cmake
@@ -44,7 +44,7 @@ find_library(HICN_LIBRARY NAMES hicn
set(HICN_LIBRARIES ${HICN_LIBRARY})
if (${CMAKE_SYSTEM_NAME} STREQUAL "Android")
-set(HICN_LIBRARIES ${HICN_LIBRARIES} log)
+ set(HICN_LIBRARIES ${HICN_LIBRARIES} log)
endif()
set(HICN_INCLUDE_DIRS ${HICN_INCLUDE_DIR})
diff --git a/cmake/Modules/GTestImport.cmake b/cmake/Modules/GTestImport.cmake
index 4e2e18d..d9d1825 100644
--- a/cmake/Modules/GTestImport.cmake
+++ b/cmake/Modules/GTestImport.cmake
@@ -18,6 +18,11 @@ include(ExternalProject)
ExternalProject_Add(gtest
URL https://github.com/google/googletest/archive/v1.10.x.zip
PREFIX ${CMAKE_BINARY_DIR}/gtest
+ BUILD_BYPRODUCTS
+ ${CMAKE_BINARY_DIR}/gtest/src/gtest-build/lib/libgmock_main.a
+ ${CMAKE_BINARY_DIR}/gtest/src/gtest-build/lib/libgmock.a
+ ${CMAKE_BINARY_DIR}/gtest/src/gtest-build/lib/libgtest_main.a
+ ${CMAKE_BINARY_DIR}/gtest/src/gtest-build/lib/libgtest.a
INSTALL_COMMAND ""
)
@@ -37,4 +42,4 @@ macro(add_test_internal test)
endif()
endmacro(add_test_internal)
-enable_testing() \ No newline at end of file
+enable_testing()
diff --git a/cmake/Modules/ServiceScript.cmake b/cmake/Modules/ServiceScript.cmake
index 110aa81..8e7056a 100644
--- a/cmake/Modules/ServiceScript.cmake
+++ b/cmake/Modules/ServiceScript.cmake
@@ -39,4 +39,4 @@ cmake_parse_arguments(ARG
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND ${CMAKE_INSTALL_PREFIX} STREQUAL "/usr")
install (FILES ${script} DESTINATION ${SYSTEMD_SERVICE_FOLDER} COMPONENT ${ARG_COMPONENT})
endif()
-endmacro(install_service_script) \ No newline at end of file
+endmacro(install_service_script)
diff --git a/ctrl/facemgr/CMakeLists.txt b/ctrl/facemgr/CMakeLists.txt
index 8b24810..290f96f 100644
--- a/ctrl/facemgr/CMakeLists.txt
+++ b/ctrl/facemgr/CMakeLists.txt
@@ -58,7 +58,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON)
-find_package_wrapper(Config REQUIRED)
+find_package_wrapper(Libconfig REQUIRED)
find_package_wrapper(LibEvent REQUIRED)
set(FACEMGR facemgr CACHE INTERNAL "" FORCE)
diff --git a/ctrl/facemgr/src/CMakeLists.txt b/ctrl/facemgr/src/CMakeLists.txt
index 4bcad47..3650ef4 100644
--- a/ctrl/facemgr/src/CMakeLists.txt
+++ b/ctrl/facemgr/src/CMakeLists.txt
@@ -64,7 +64,7 @@ set(LIBRARIES
m
${HICN_LIBRARIES}
${LIBHICNCTRL_LIBRARIES}
- ${CONFIG_LIBRARY}
+ ${LIBCONFIG_LIBRARIES}
${LIBEVENT_LIBRARY}
)
@@ -106,7 +106,7 @@ if (DISABLE_SHARED_LIBRARIES)
LINK_LIBRARIES ${LIBRARIES}
COMPONENT ${FACEMGR}
INCLUDE_DIRS ${INCLUDE_DIRS}
- INSTALL_ROOT_DIR hicn
+ HEADER_ROOT_DIR hicn
DEFINITIONS ${COMPILER_DEFINITIONS}
)
else ()
@@ -118,7 +118,7 @@ else ()
LINK_LIBRARIES ${LIBRARIES}
COMPONENT ${FACEMGR}
INCLUDE_DIRS ${INCLUDE_DIRS}
- INSTALL_ROOT_DIR hicn
+ HEADER_ROOT_DIR hicn
DEFINITIONS ${COMPILER_DEFINITIONS}
)
endif ()
diff --git a/ctrl/libhicnctrl/src/CMakeLists.txt b/ctrl/libhicnctrl/src/CMakeLists.txt
index 00661a2..f5d3c49 100644
--- a/ctrl/libhicnctrl/src/CMakeLists.txt
+++ b/ctrl/libhicnctrl/src/CMakeLists.txt
@@ -69,7 +69,7 @@ build_library(${LIBHICNCTRL}
DEPENDS ${DEPENDENCIES}
COMPONENT ${LIBHICNCTRL_COMPONENT}
INCLUDE_DIRS ${INCLUDE_DIRS}
- INSTALL_ROOT_DIR hicn
+ HEADER_ROOT_DIR hicn
DEFINITIONS ${COMPILER_DEFINITIONS}
)
diff --git a/ctrl/libhicnctrl/src/hicn_plugin_api.c b/ctrl/libhicnctrl/src/hicn_plugin_api.c
index 0b0a9ad..231c491 100644
--- a/ctrl/libhicnctrl/src/hicn_plugin_api.c
+++ b/ctrl/libhicnctrl/src/hicn_plugin_api.c
@@ -40,8 +40,18 @@
#include <hicn/util/map.h>
#include <hicn/error.h>
#include <vnet/ip/ip6_packet.h>
+
+
+#if __GNUC__ >= 9
+#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
+#endif
+
#include <vnet/ip/ip46_address.h>
+#if __GNUC__ >= 9
+#pragma GCC diagnostic pop
+#endif
+
#define APP_NAME "hicn_plugin"
#define MAX_OUTSTANDING_REQUESTS 4
#define RESPONSE_QUEUE_SIZE 2
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 6d48ae6..99ea39a 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -22,7 +22,6 @@ on VPP and a client stack is provided to support any mobile and desktop operatin
control
telemetry
utils
- packethicn
apps
diff --git a/extras/CMakeLists.txt b/extras/CMakeLists.txt
index 1cb671c..88668df 100644
--- a/extras/CMakeLists.txt
+++ b/extras/CMakeLists.txt
@@ -23,7 +23,6 @@ set (DESTDIR ${CMAKE_BINARY_DIR}/extras-root)
# add_subdirectory(router-plugin)
add_subdirectory(libmemif)
-add_subdirectory(packethicn)
# add_subdirectory(libyang)
# add_subdirectory(sysrepo)
diff --git a/extras/libmemif/CMakeLists2.patch b/extras/libmemif/CMakeLists2.patch
index 20b67ea..38d520b 100644
--- a/extras/libmemif/CMakeLists2.patch
+++ b/extras/libmemif/CMakeLists2.patch
@@ -37,6 +37,6 @@ build_library(${LIBMEMIF}
SOURCES ${MEMIF_SOURCES}
INSTALL_HEADERS ${MEMIF_HEADERS}
LINK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}
- INSTALL_ROOT_DIR memif
+ HEADER_ROOT_DIR memif
COMPONENT ${COMPONENT}
) \ No newline at end of file
diff --git a/hicn-light/src/hicn/CMakeLists.txt b/hicn-light/src/hicn/CMakeLists.txt
index 82de74a..639bfa1 100644
--- a/hicn-light/src/hicn/CMakeLists.txt
+++ b/hicn-light/src/hicn/CMakeLists.txt
@@ -56,7 +56,7 @@ build_library(${LIBHICN_LIGHT}
DEPENDS ${DEPENDENCIES}
COMPONENT ${HICN_LIGHT}
INCLUDE_DIRS ${HICN_LIGHT_INCLUDE_DIRS}
- INSTALL_ROOT_DIR hicn
+ HEADER_ROOT_DIR hicn
DEFINITIONS ${COMPILER_DEFINITIONS}
)
diff --git a/hicn-light/src/hicn/core/message.c b/hicn-light/src/hicn/core/message.c
index 5d0d04a..c289383 100644
--- a/hicn-light/src/hicn/core/message.c
+++ b/hicn-light/src/hicn/core/message.c
@@ -245,7 +245,8 @@ uint32_t message_GetPathLabel(const Message *message) {
void message_SetPathLabel(Message *message, uint32_t label) {
parcAssertNotNull(message, "Parameter must be non-null");
- messageHandler_SetPathLabel(message->messageHead, label);
+ messageHandler_SetPathLabel(message->messageHead,
+ messageHandler_GetPathLabel(message->messageHead), label);
}
void message_UpdatePathLabel(Message *message, uint8_t outFace) {
diff --git a/hicn-light/src/hicn/core/messageHandler.h b/hicn-light/src/hicn/core/messageHandler.h
index f6b3e4e..b41c9a7 100644
--- a/hicn-light/src/hicn/core/messageHandler.h
+++ b/hicn-light/src/hicn/core/messageHandler.h
@@ -334,7 +334,7 @@ static inline bool messageHandler_IsInterest(const uint8_t *message) {
if (!messageHandler_IsTCP(message)) return false;
bool flag;
- hicn_packet_test_ece((hicn_header_t *)message,
+ hicn_packet_test_ece(HF_INET6_TCP, (hicn_header_t *)message,
&flag); // ECE flag is set to 0 in interest packets
if (flag == false) return true;
return false;
@@ -344,7 +344,7 @@ static inline bool messageHandler_IsData(const uint8_t *message) {
if (!messageHandler_IsTCP(message)) return false;
bool flag;
- hicn_packet_test_ece((hicn_header_t *)message,
+ hicn_packet_test_ece(HF_INET6_TCP, (hicn_header_t *)message,
&flag); // ECE flag is set to 1 in data packets
if (flag == true) return true;
return false;
@@ -505,13 +505,10 @@ static inline uint32_t messageHandler_GetPathLabel(const uint8_t *message) {
}
static inline void messageHandler_SetPathLabel(uint8_t *message,
+ uint32_t old_path_label,
uint32_t new_path_label) {
if (!messageHandler_IsTCP(message)) return;
- uint32_t old_path_label;
- int res = hicn_data_get_path_label((hicn_header_t *)message, &old_path_label);
- if (res < 0) return;
-
hicn_data_set_path_label((hicn_header_t *)message, new_path_label);
messageHandler_UpdateTCPCheckSum(message, (uint16_t *)&old_path_label,
@@ -527,20 +524,11 @@ static inline void messageHandler_UpdatePathLabel(uint8_t *message,
uint32_t pl_new_32bit =
(uint32_t)((((pl_old_8bit << 1) | (pl_old_8bit >> 7)) ^ outFace) << 24UL);
- hicn_data_set_path_label((hicn_header_t *)message, pl_new_32bit);
-
- messageHandler_UpdateTCPCheckSum(message, (uint16_t *)&pl_old_32bit,
- (uint16_t *)&pl_new_32bit, 2);
+ messageHandler_SetPathLabel(message, pl_old_32bit, pl_new_32bit);
}
static inline void messageHandler_ResetPathLabel(uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return;
-
- uint32_t pl_old_32bit = messageHandler_GetPathLabel(message);
- uint32_t pl_new_32bit = 0;
- hicn_data_set_path_label((hicn_header_t *)message, pl_new_32bit);
- messageHandler_UpdateTCPCheckSum(message, (uint16_t *)&pl_old_32bit,
- (uint16_t *)&pl_new_32bit, 2);
+ messageHandler_SetPathLabel(message, messageHandler_GetPathLabel(message), 0);
}
static inline uint16_t messageHandler_GetInterestLifetime(
@@ -703,7 +691,7 @@ static inline uint8_t * messageHandler_CreateProbePacket(hicn_format_t format,
hicn_packet_init_header(format, (hicn_header_t *) pkt);
- hicn_packet_set_dst_port((hicn_header_t *) pkt, BFD_PORT);
+ hicn_packet_set_dst_port(format, (hicn_header_t *) pkt, BFD_PORT);
hicn_interest_set_lifetime ((hicn_header_t *) pkt, probe_lifetime);
return pkt;
@@ -721,10 +709,10 @@ static inline void messageHandler_CreateProbeReply(uint8_t * probe,
uint16_t src_prt;
uint16_t dst_prt;
- hicn_packet_get_src_port((const hicn_header_t *) probe, &src_prt);
- hicn_packet_get_dst_port((const hicn_header_t *) probe, &dst_prt);
- hicn_packet_set_src_port((hicn_header_t *) probe, dst_prt);
- hicn_packet_set_dst_port((hicn_header_t *) probe, src_prt);
+ hicn_packet_get_src_port(format, (const hicn_header_t *) probe, &src_prt);
+ hicn_packet_get_dst_port(format, (const hicn_header_t *) probe, &dst_prt);
+ hicn_packet_set_src_port(format, (hicn_header_t *) probe, dst_prt);
+ hicn_packet_set_dst_port(format, (hicn_header_t *) probe, src_prt);
hicn_data_set_name (format, (hicn_header_t *) probe, &probe_name);
hicn_data_set_locator (format, (hicn_header_t *) probe, &probe_locator);
@@ -746,8 +734,8 @@ static inline void messageHandler_SetProbeName(uint8_t * probe, hicn_format_t fo
static inline bool messageHandler_IsAProbe(const uint8_t *packet){
uint16_t src_prt;
uint16_t dst_prt;
- hicn_packet_get_src_port ((const hicn_header_t *) packet, &src_prt);
- hicn_packet_get_dst_port ((const hicn_header_t *) packet, &dst_prt);
+ hicn_packet_get_src_port (HF_INET6_TCP, (const hicn_header_t *) packet, &src_prt);
+ hicn_packet_get_dst_port (HF_INET6_TCP, (const hicn_header_t *) packet, &dst_prt);
if(dst_prt == BFD_PORT){
//interest probe
diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt
index 14eb23d..d81ed22 100644
--- a/hicn-plugin/src/CMakeLists.txt
+++ b/hicn-plugin/src/CMakeLists.txt
@@ -177,13 +177,6 @@ endif (NOT CMAKE_BUILD_TYPE)
SET(HICN_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} CACHE STRING "hicn_install_prefix")
-if (CMAKE_BUILD_TYPE STREQUAL "Release")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wall -march=native -O3 -g -Wno-address-of-packed-member")
-elseif (CMAKE_BUILD_TYPE STREQUAL "Debug")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -march=native -O0 -g -Wno-address-of-packed-member")
- add_definitions(-DCLIB_DEBUG -fPIC -fstack-protector-all)
-endif()
-
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/hicn)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vapi)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip)
@@ -259,12 +252,19 @@ set_target_properties(hicn_plugin
PROPERTIES
LINKER_LANGUAGE C
INSTALL_RPATH ${VPP_INSTALL_PLUGIN}
+ COMPILE_FLAGS "-march=native -Wno-address-of-packed-member"
PREFIX "")
set_target_properties(hicn_api_test_plugin
PROPERTIES
LINKER_LANGUAGE C
+ COMPILE_FLAGS "-march=native -Wno-address-of-packed-member"
PREFIX "")
+if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
+ target_compile_definitions(hicn_plugin PRIVATE "CLIB_DEBUG")
+ target_compile_definitions(hicn_api_test_plugin PRIVATE "CLIB_DEBUG")
+endif()
+
message (STATUS "hicn-plugin variable ${HICN_PLUGIN}")
install(DIRECTORY
diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c
index 7ddf389..d620543 100644
--- a/hicn-plugin/src/faces/face.c
+++ b/hicn-plugin/src/faces/face.c
@@ -24,6 +24,7 @@
dpo_id_t *face_dpo_vec;
hicn_face_vft_t *face_vft_vec;
char **face_type_names_vec;
+u8 pl_index = 1;
hicn_face_t *hicn_dpoi_face_pool;
diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h
index 234c3fc..95c78b2 100644
--- a/hicn-plugin/src/faces/face.h
+++ b/hicn-plugin/src/faces/face.h
@@ -189,6 +189,9 @@ extern hicn_face_vft_t *face_vft_vec;
/* Vector holding the set of face names */
extern char **face_type_names_vec;
+/* Pathlabel counter */
+extern u8 pl_index;
+
/* First face type registered in the sytem.*/
extern dpo_type_t first_type;
@@ -526,7 +529,7 @@ hicn_iface_add (ip46_address_t * nat_address, int sw_if,
face->dpo.dpoi_proto = DPO_PROTO_NONE;
face->dpo.dpoi_index = adj_index;
face->dpo.dpoi_next_node = 0;
- face->pl_id = (u16) 0;
+ face->pl_id = pl_index++;
face->flags = HICN_FACE_FLAGS_IFACE;
face->locks = 1;
diff --git a/hicn-plugin/src/faces/iface_node.c b/hicn-plugin/src/faces/iface_node.c
index 8d85009..82c0f75 100644
--- a/hicn-plugin/src/faces/iface_node.c
+++ b/hicn-plugin/src/faces/iface_node.c
@@ -535,8 +535,11 @@ hicn_rewrite_iface_data4 (vlib_main_t *vm, vlib_buffer_t *b0,
ip46_address_t temp_addr;
ip46_address_reset (&temp_addr);
hicn_type_t type = hicn_get_buffer (b0)->type;
+ u8 flags = hicn_get_buffer (b0)->flags;
+ u8 reset_pl = flags & HICN_BUFFER_FLAGS_FROM_CS;
int ret = hicn_ops_vft[type.l1]->rewrite_data (
- type, &hicn->protocol, &(iface->nat_addr), &(temp_addr), iface->pl_id);
+ type, &hicn->protocol, &(iface->nat_addr), &(temp_addr),
+ iface->pl_id, reset_pl);
if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED)
{
ensure_offload_flags (b0, 1 /* is_v4 */);
@@ -567,8 +570,11 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0,
ip46_address_t temp_addr;
ip46_address_reset (&temp_addr);
hicn_type_t type = hicn_get_buffer (b0)->type;
+ u8 flags = hicn_get_buffer (b0)->flags;
+ u8 reset_pl = flags & HICN_BUFFER_FLAGS_FROM_CS;
int ret = hicn_ops_vft[type.l1]->rewrite_data (
- type, &hicn->protocol, &(iface->nat_addr), &(temp_addr), iface->pl_id);
+ type, &hicn->protocol, &(iface->nat_addr), &(temp_addr),
+ iface->pl_id, reset_pl);
if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED)
{
diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h
index 3d980bd..437f911 100644
--- a/hicn-plugin/src/hicn.h
+++ b/hicn-plugin/src/hicn.h
@@ -65,6 +65,7 @@ typedef u8 weight_t;
#define HICN_BUFFER_FLAGS_PKT_LESS_TWO_CL 0x02
#define HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL 0x04
#define HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL 0x08
+#define HICN_BUFFER_FLAGS_FROM_CS 0x10
/* The following is stored in the opaque2 field in the vlib_buffer_t */
typedef struct
diff --git a/hicn-plugin/src/interest_hitcs_node.c b/hicn-plugin/src/interest_hitcs_node.c
index c224051..0212fa5 100644
--- a/hicn-plugin/src/interest_hitcs_node.c
+++ b/hicn-plugin/src/interest_hitcs_node.c
@@ -76,6 +76,9 @@ clone_from_cs (vlib_main_t *vm, u32 *bi0_cs, vlib_buffer_t *dest, u8 isv6)
vlib_buffer_advance (cs_buf, buffer_advance);
vlib_buffer_attach_clone (vm, dest, cs_buf);
}
+
+ /* Set fag for packet coming from CS */
+ hicn_get_buffer (dest)->flags |= HICN_BUFFER_FLAGS_FROM_CS;
}
static uword
diff --git a/hicn-plugin/vapi/CMakeLists.txt b/hicn-plugin/vapi/CMakeLists.txt
index 03fd489..9464cd9 100644
--- a/hicn-plugin/vapi/CMakeLists.txt
+++ b/hicn-plugin/vapi/CMakeLists.txt
@@ -42,7 +42,7 @@ build_library(${SAFE_VAPI}
LINK_LIBRARIES ${LIBRARIES}
COMPONENT ${HICN_PLUGIN}
INCLUDE_DIRS ${INCLUDE_DIRS}
- INSTALL_ROOT_DIR /
+ HEADER_ROOT_DIR /
DEFINITIONS ${COMPILER_DEFINITIONS}
)
diff --git a/lib/.clang-format b/lib/.clang-format
new file mode 100644
index 0000000..8b5c955
--- /dev/null
+++ b/lib/.clang-format
@@ -0,0 +1,21 @@
+# Minimal clang-format version is 8
+
+BasedOnStyle: GNU
+UseTab: Always
+SpaceAfterCStyleCast: true
+SortIncludes: false
+AlignConsecutiveMacros: true
+BreakBeforeTernaryOperators: false
+BreakBeforeBinaryOperators: None
+ContinuationIndentWidth: 2
+
+ForEachMacros:
+ - 'clib_bitmap_foreach'
+ - 'pool_foreach'
+ - 'pool_foreach_index'
+ - 'vec_foreach'
+ - 'vec_foreach_backwards'
+ - 'vec_foreach_index'
+ - 'vec_foreach_index_backwards'
+ - 'vlib_foreach_rx_tx'
+
diff --git a/lib/includes/hicn/base.h b/lib/includes/hicn/base.h
index f38001d..797912f 100644
--- a/lib/includes/hicn/base.h
+++ b/lib/includes/hicn/base.h
@@ -22,6 +22,7 @@
#define HICN_BASE_H
#include "common.h"
+#include <netinet/in.h>
/* Default header fields */
#define HICN_DEFAULT_TTL 254
@@ -105,6 +106,17 @@ HICN_TYPE(int x, int y, int z, int t)
#define HICN_TYPE_NONE HICN_TYPE(IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE)
/**
+ * @brief Check if type is none.
+ * @return 1 if none, 0 otherwise
+ */
+always_inline int
+hicn_type_is_none(hicn_type_t type)
+{
+ return (type.l1 == IPPROTO_NONE) && (type.l2 == IPPROTO_NONE) &&
+ (type.l3 == IPPROTO_NONE) && (type.l4 == IPPROTO_NONE);
+}
+
+/**
* @brief hICN Payload type
*
* This type distinguishes several types of data packet, which can either carry
@@ -127,7 +139,7 @@ typedef enum
* NOTE: this computation is not (yet) part of the hICN specification.
*/
-#define HICN_PATH_LABEL_MASK 0xF000 /* 1000 0000 0000 0000 */
+#define HICN_PATH_LABEL_MASK 0x000000ff
#define HICN_PATH_LABEL_SIZE 8
/**
@@ -143,8 +155,8 @@ update_pathlabel (hicn_pathlabel_t current_label, hicn_faceid_t face_id,
hicn_pathlabel_t * new_label)
{
hicn_pathlabel_t pl_face_id =
- (hicn_pathlabel_t) ((face_id & HICN_PATH_LABEL_MASK) >>
- (16 - HICN_PATH_LABEL_SIZE));
+ (hicn_pathlabel_t) (face_id & HICN_PATH_LABEL_MASK);
+
*new_label =
((current_label << 1) | (current_label >> (HICN_PATH_LABEL_SIZE - 1))) ^
pl_face_id;
diff --git a/lib/includes/hicn/common.h b/lib/includes/hicn/common.h
index 6904c63..a5ca287 100644
--- a/lib/includes/hicn/common.h
+++ b/lib/includes/hicn/common.h
@@ -143,8 +143,17 @@ struct iovec
#include <vnet/ip/ip4_packet.h> // ip4_address_t
#include <vnet/ip/ip6_packet.h> // ip6_address_t
+
+#if __GNUC__ >= 9
+#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
+#endif
+
#include <vnet/ip/ip46_address.h>
+#if __GNUC__ >= 9
+#pragma GCC diagnostic pop
+#endif
+
#else
diff --git a/lib/includes/hicn/compat.h b/lib/includes/hicn/compat.h
index 2796983..35b6e6f 100644
--- a/lib/includes/hicn/compat.h
+++ b/lib/includes/hicn/compat.h
@@ -34,15 +34,15 @@
/* HICN format options */
#define HFO_INET 1 << 0
#define HFO_INET6 1 << 1
-#define HFO_TCP 1 << 2
+#define HFO_TCP 1 << 2
#define HFO_ICMP 1 << 3
-#define HFO_AH 1 << 4
+#define HFO_AH 1 << 4
#define _is_ipv4(format) ((format & HFO_INET))
#define _is_ipv6(format) ((format & HFO_INET6) >> 1)
-#define _is_tcp(format) ((format & HFO_TCP) >> 2)
-#define _is_icmp(format) ((format & HFO_ICMP) >> 3)
-#define _is_ah(format) ((format & HFO_AH) >> 4)
+#define _is_tcp(format) ((format & HFO_TCP) >> 2)
+#define _is_icmp(format) ((format & HFO_ICMP) >> 3)
+#define _is_ah(format) ((format & HFO_AH) >> 4)
typedef enum
{
@@ -54,28 +54,30 @@ typedef enum
HF_INET_TCP_AH = HFO_INET | HFO_TCP | HFO_AH,
HF_INET6_TCP_AH = HFO_INET6 | HFO_TCP | HFO_AH,
HF_INET_ICMP_AH = HFO_INET | HFO_ICMP | HFO_AH,
- HF_INET6_ICMP_AH = HFO_INET6 | HFO_ICMP | HFO_AH
+ HF_INET6_ICMP_AH = HFO_INET6 | HFO_ICMP | HFO_AH,
} hicn_format_t;
/**
- * Minimum required header length to determine the type and length of a supposed
- * hICN packet.
- * This should be equal to the maximum value over all possible hICN packet
- * formats, and less than the minimum possible IP packet size.
+ * Minimum required header length to determine the type and length of a
+ * supposed hICN packet. This should be equal to the maximum value over all
+ * possible hICN packet formats, and less than the minimum possible IP packet
+ * size.
*/
-#define HICN_V6_MIN_HDR_LEN 6 /* bytes */
-#define HICN_V4_MIN_HDR_LEN 4 /* bytes */
+#define HICN_V6_MIN_HDR_LEN 6 /* bytes */
+#define HICN_V4_MIN_HDR_LEN 4 /* bytes */
-// #define HICN_MIN_HDR_LEN ((HICN_V6_MIN_HDR_LEN > HICN_V4_MIN_HDR_LEN) ? HICN_V6_MIN_HDR_LEN : HICN_V4_MIN_HDR_LEN)
+// #define HICN_MIN_HDR_LEN ((HICN_V6_MIN_HDR_LEN > HICN_V4_MIN_HDR_LEN) ?
+// HICN_V6_MIN_HDR_LEN : HICN_V4_MIN_HDR_LEN)
#define HICN_MIN_HDR_LEN HICN_V6_MIN_HDR_LEN
/**
* @brief Parse packet headers and return hICN format
* @param [in] format - hICN Format
- * @param [in, out] packet - Buffer containing the hICN header to be initialized
+ * @param [in, out] packet - Buffer containing the hICN header to be
+ * initialized
* @return hICN error code
*/
-int hicn_packet_init_header (hicn_format_t format, hicn_header_t * packet);
+int hicn_packet_init_header (hicn_format_t format, hicn_header_t *packet);
/**
* @brief Parse packet headers and return hICN format
@@ -83,8 +85,8 @@ int hicn_packet_init_header (hicn_format_t format, hicn_header_t * packet);
* @param [out] format - hICN format
* @return hICN error code
*/
-int hicn_packet_get_format (const hicn_header_t * packet,
- hicn_format_t * format);
+int hicn_packet_get_format (const hicn_header_t *packet,
+ hicn_format_t *format);
/**
* @brief Update checksums in packet headers
@@ -92,19 +94,18 @@ int hicn_packet_get_format (const hicn_header_t * packet,
* @param [in,out] packet - packet header
* @return hICN error code
*/
-int hicn_packet_compute_checksum (hicn_format_t format,
- hicn_header_t * packet);
+int hicn_packet_compute_checksum (hicn_format_t format, hicn_header_t *packet);
/**
- * @brief compute the checksum of the packet header, adding init_sum to the final value
+ * @brief compute the checksum of the packet header, adding init_sum to the
+ * final value
* @param [in] format - hICN format
* @param [in,out] packet - packet header
* @param [in] init_sum - value to add to the final checksum
* @return hICN error code
*/
int hicn_packet_compute_header_checksum (hicn_format_t format,
- hicn_header_t * packet,
- u16 init_sum);
+ hicn_header_t *packet, u16 init_sum);
/**
* @brief Verify checksums in packet headers
@@ -112,8 +113,9 @@ int hicn_packet_compute_header_checksum (hicn_format_t format,
* @param [in,out] packet - packet header
* @return hICN error code
*/
-int hicn_packet_check_integrity (hicn_format_t format,
- hicn_header_t * packet);
+int hicn_packet_check_integrity_no_payload (hicn_format_t format,
+ hicn_header_t *packet,
+ u16 init_sum);
// this is not accounted here
/**
@@ -123,7 +125,7 @@ int hicn_packet_check_integrity (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_get_header_length_from_format (hicn_format_t format,
- size_t * header_length);
+ size_t *header_length);
/**
* @brief Return total length of hicn headers (before payload)
@@ -133,8 +135,8 @@ int hicn_packet_get_header_length_from_format (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_get_header_length (hicn_format_t format,
- const hicn_header_t * packet,
- size_t * header_length);
+ const hicn_header_t *packet,
+ size_t *header_length);
/**
* @brief Return payload length
@@ -144,8 +146,8 @@ int hicn_packet_get_header_length (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_get_payload_length (hicn_format_t format,
- const hicn_header_t * packet,
- size_t * payload_length);
+ const hicn_header_t *packet,
+ size_t *payload_length);
/**
* @brief Sets payload length
@@ -155,7 +157,7 @@ int hicn_packet_get_payload_length (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_set_payload_length (hicn_format_t format,
- hicn_header_t * packet,
+ hicn_header_t *packet,
const size_t payload_length);
/**
@@ -164,8 +166,8 @@ int hicn_packet_set_payload_length (hicn_format_t format,
* @param [in] packet_2 - Second packet
* @return 0 if both packets are considered equal, any other value otherwise.
*/
-int hicn_packet_compare (const hicn_header_t * packet1,
- const hicn_header_t * packet2);
+int hicn_packet_compare (const hicn_header_t *packet1,
+ const hicn_header_t *packet2);
/**
* @brief Retrieve the name of an interest/data packet
@@ -176,8 +178,8 @@ int hicn_packet_compare (const hicn_header_t * packet1,
* data packet (0)
* @return hICN error code
*/
-int hicn_packet_get_name (hicn_format_t format, const hicn_header_t * packet,
- hicn_name_t * name, u8 is_interest);
+int hicn_packet_get_name (hicn_format_t format, const hicn_header_t *packet,
+ hicn_name_t *name, u8 is_interest);
/**
* @brief Sets the name of an interest/data packet
@@ -188,8 +190,8 @@ int hicn_packet_get_name (hicn_format_t format, const hicn_header_t * packet,
* data packet (0)
* @return hICN error code
*/
-int hicn_packet_set_name (hicn_format_t format, hicn_header_t * packet,
- const hicn_name_t * name, u8 is_interest);
+int hicn_packet_set_name (hicn_format_t format, hicn_header_t *packet,
+ const hicn_name_t *name, u8 is_interest);
/**
* @brief Sets the payload of a packet
@@ -203,8 +205,8 @@ int hicn_packet_set_name (hicn_format_t format, hicn_header_t * packet,
* - The buffer holding payload is assumed sufficiently large
* - This function updates header fields with the new length, but no checksum.
*/
-int hicn_packet_set_payload (hicn_format_t format, hicn_header_t * packet,
- const u8 * payload, u16 payload_length);
+int hicn_packet_set_payload (hicn_format_t format, hicn_header_t *packet,
+ const u8 *payload, u16 payload_length);
/**
* @brief Retrieves the payload of a packet
@@ -212,16 +214,17 @@ int hicn_packet_set_payload (hicn_format_t format, hicn_header_t * packet,
* @param [in] packet - packet header
* @param [out] payload - pointer to buffer for storing the result
* @param [out] payload_length - size of the retreived payload
- * @param [in] hard_copy - Flag : if true (eg. 1), a copy of the payload is made
- * into the payload buffer, otherwise (0) the pointer is changed to point to the payload offset in the packet.
+ * @param [in] hard_copy - Flag : if true (eg. 1), a copy of the payload is
+ * made into the payload buffer, otherwise (0) the pointer is changed to point
+ * to the payload offset in the packet.
* @return hICN error code
*
* NOTE:
* - The buffer holding payload is assumed sufficiently large
*/
-int hicn_packet_get_payload (hicn_format_t format,
- const hicn_header_t * packet, u8 ** payload,
- size_t * payload_size, bool hard_copy);
+int hicn_packet_get_payload (hicn_format_t format, const hicn_header_t *packet,
+ u8 **payload, size_t *payload_size,
+ bool hard_copy);
/**
* @brief Retrieve the locator of an interest / data packet
@@ -232,9 +235,8 @@ int hicn_packet_get_payload (hicn_format_t format,
* data packet (0)
* @return hICN error code
*/
-int hicn_packet_get_locator (hicn_format_t format,
- const hicn_header_t * packet,
- ip_address_t * prefix, bool is_interest);
+int hicn_packet_get_locator (hicn_format_t format, const hicn_header_t *packet,
+ ip_address_t *prefix, bool is_interest);
/**
* @brief Sets the locator of an interest / data packet
@@ -245,9 +247,8 @@ int hicn_packet_get_locator (hicn_format_t format,
* data packet (0)
* @return hICN error code
*/
-int hicn_packet_set_locator (hicn_format_t format, hicn_header_t * packet,
- const ip_address_t * prefix,
- bool is_interest);
+int hicn_packet_set_locator (hicn_format_t format, hicn_header_t *packet,
+ const ip_address_t *prefix, bool is_interest);
/**
* @brief Retrieves the signature size
@@ -257,8 +258,8 @@ int hicn_packet_set_locator (hicn_format_t format, hicn_header_t * packet,
* @return hICN error code
*/
int hicn_packet_get_signature_size (hicn_format_t format,
- const hicn_header_t * packet,
- size_t * bytes);
+ const hicn_header_t *packet,
+ size_t *bytes);
/**
* @brief Sets the signature size
@@ -268,7 +269,7 @@ int hicn_packet_get_signature_size (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_set_signature_size (hicn_format_t format,
- hicn_header_t * packet, size_t bytes);
+ hicn_header_t *packet, size_t bytes);
/**
* @brief Sets the signature size
@@ -278,7 +279,7 @@ int hicn_packet_set_signature_size (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_set_signature_timestamp (hicn_format_t format,
- hicn_header_t * h,
+ hicn_header_t *h,
uint64_t signature_timestamp);
/**
@@ -289,8 +290,8 @@ int hicn_packet_set_signature_timestamp (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_get_signature_timestamp (hicn_format_t format,
- const hicn_header_t * h,
- uint64_t * signature_timestamp);
+ const hicn_header_t *h,
+ uint64_t *signature_timestamp);
/**
* @brief Sets the signature size
@@ -300,7 +301,7 @@ int hicn_packet_get_signature_timestamp (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_set_validation_algorithm (hicn_format_t format,
- hicn_header_t * h,
+ hicn_header_t *h,
uint8_t validation_algorithm);
/**
@@ -311,8 +312,8 @@ int hicn_packet_set_validation_algorithm (hicn_format_t format,
* @return hICN error code
*/
int hicn_packet_get_validation_algorithm (hicn_format_t format,
- const hicn_header_t * h,
- uint8_t * validation_algorithm);
+ const hicn_header_t *h,
+ uint8_t *validation_algorithm);
/**
* @brief Sets the signature size
@@ -321,8 +322,8 @@ int hicn_packet_get_validation_algorithm (hicn_format_t format,
* @param [in] key_id - Key id to set
* @return hICN error code
*/
-int hicn_packet_set_key_id (hicn_format_t format, hicn_header_t * h,
- uint8_t * key_id);
+int hicn_packet_set_key_id (hicn_format_t format, hicn_header_t *h,
+ uint8_t *key_id);
/**
* @brief Sets the signature size
@@ -331,8 +332,8 @@ int hicn_packet_set_key_id (hicn_format_t format, hicn_header_t * h,
* @param [out] key_id - Retrieved key id
* @return hICN error code
*/
-int hicn_packet_get_key_id (hicn_format_t format, hicn_header_t * h,
- uint8_t ** key_id, uint8_t * key_id_length);
+int hicn_packet_get_key_id (hicn_format_t format, hicn_header_t *h,
+ uint8_t **key_id, uint8_t *key_id_length);
/**
* @brief Retrieves the packet hop limit
@@ -340,7 +341,7 @@ int hicn_packet_get_key_id (hicn_format_t format, hicn_header_t * h,
* @param [out] hops - Retrieved hop limit
* @return hICN error code
*/
-int hicn_packet_get_hoplimit (const hicn_header_t * packet, u8 * hops);
+int hicn_packet_get_hoplimit (const hicn_header_t *packet, u8 *hops);
/**
* @brief Sets the packet hop limit
@@ -348,107 +349,111 @@ int hicn_packet_get_hoplimit (const hicn_header_t * packet, u8 * hops);
* @param [in] hops - Hop limit to set
* @return hICN error code
*/
-int hicn_packet_set_hoplimit (hicn_header_t * packet, u8 hops);
+int hicn_packet_set_hoplimit (hicn_header_t *packet, u8 hops);
-int hicn_packet_copy_header (hicn_format_t format,
- const hicn_header_t * packet,
- hicn_header_t * destination, bool copy_ah);
+int hicn_packet_copy_header (hicn_format_t format, const hicn_header_t *packet,
+ hicn_header_t *destination, bool copy_ah);
-int hicn_packet_get_lifetime (const hicn_header_t * packet, u32 * lifetime);
-int hicn_packet_set_lifetime (hicn_header_t * packet, u32 lifetime);
-int hicn_packet_get_reserved_bits (const hicn_header_t * packet,
- u8 * reserved_bits);
-int hicn_packet_set_reserved_bits (hicn_header_t * packet,
+int hicn_packet_get_lifetime (const hicn_header_t *packet, u32 *lifetime);
+int hicn_packet_set_lifetime (hicn_header_t *packet, u32 lifetime);
+int hicn_packet_get_reserved_bits (const hicn_header_t *packet,
+ u8 *reserved_bits);
+int hicn_packet_set_reserved_bits (hicn_header_t *packet,
const u8 reserved_bits);
-int hicn_packet_get_payload_type (const hicn_header_t * packet,
- hicn_payload_type_t * payload_type);
-int hicn_packet_set_payload_type (hicn_header_t * packet,
+int hicn_packet_get_payload_type (const hicn_header_t *packet,
+ hicn_payload_type_t *payload_type);
+int hicn_packet_set_payload_type (hicn_header_t *packet,
const hicn_payload_type_t payload_type);
-int hicn_packet_set_syn (hicn_header_t * packet);
-int hicn_packet_reset_syn (hicn_header_t * packet);
-int hicn_packet_test_syn (const hicn_header_t * packet, bool * flag);
-int hicn_packet_set_ack (hicn_header_t * packet);
-int hicn_packet_reset_ack (hicn_header_t * packet);
-int hicn_packet_test_ack (const hicn_header_t * packet, bool * flag);
-int hicn_packet_set_rst (hicn_header_t * packet);
-int hicn_packet_reset_rst (hicn_header_t * packet);
-int hicn_packet_test_rst (const hicn_header_t * packet, bool * flag);
-int hicn_packet_set_fin (hicn_header_t * packet);
-int hicn_packet_reset_fin (hicn_header_t * packet);
-int hicn_packet_test_fin (const hicn_header_t * packet, bool * flag);
-int hicn_packet_set_ece (hicn_header_t * packet);
-int hicn_packet_reset_ece (hicn_header_t * packet);
-int hicn_packet_test_ece (const hicn_header_t * packet, bool * flag);
-
-int hicn_packet_set_src_port (hicn_header_t * packet, u16 src_port);
-int hicn_packet_get_src_port (const hicn_header_t * packet, u16 * src_port);
-int hicn_packet_set_dst_port (hicn_header_t * packet, u16 dst_port);
-int hicn_packet_get_dst_port (const hicn_header_t * packet, u16 * dst_port);
-int hicn_packet_get_signature (hicn_format_t format, hicn_header_t * packet,
- uint8_t ** sign_buf);
+int hicn_packet_set_syn (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_reset_syn (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_test_syn (hicn_format_t format, const hicn_header_t *packet,
+ bool *flag);
+int hicn_packet_set_ack (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_reset_ack (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_test_ack (hicn_format_t format, const hicn_header_t *packet,
+ bool *flag);
+int hicn_packet_set_rst (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_reset_rst (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_test_rst (hicn_format_t format, const hicn_header_t *packet,
+ bool *flag);
+int hicn_packet_set_fin (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_reset_fin (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_test_fin (hicn_format_t format, const hicn_header_t *packet,
+ bool *flag);
+int hicn_packet_set_ece (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_reset_ece (hicn_format_t format, hicn_header_t *packet);
+int hicn_packet_test_ece (hicn_format_t format, const hicn_header_t *packet,
+ bool *flag);
+
+int hicn_packet_set_src_port (hicn_format_t format, hicn_header_t *packet,
+ u16 src_port);
+int hicn_packet_get_src_port (hicn_format_t format,
+ const hicn_header_t *packet, u16 *src_port);
+int hicn_packet_set_dst_port (hicn_format_t format, hicn_header_t *packet,
+ u16 dst_port);
+int hicn_packet_get_dst_port (hicn_format_t format,
+ const hicn_header_t *packet, u16 *dst_port);
+int hicn_packet_get_signature (hicn_format_t format, hicn_header_t *packet,
+ uint8_t **sign_buf);
/* Interest */
int hicn_interest_get_name (hicn_format_t format,
- const hicn_header_t * interest,
- hicn_name_t * name);
-int hicn_interest_set_name (hicn_format_t format, hicn_header_t * interest,
- const hicn_name_t * name);
+ const hicn_header_t *interest, hicn_name_t *name);
+int hicn_interest_set_name (hicn_format_t format, hicn_header_t *interest,
+ const hicn_name_t *name);
int hicn_interest_get_locator (hicn_format_t format,
- const hicn_header_t * interest,
- ip_address_t * prefix);
-int hicn_interest_set_locator (hicn_format_t format, hicn_header_t * interest,
- const ip_address_t * prefix);
-int hicn_interest_compare (const hicn_header_t * interest_1,
- const hicn_header_t * interest_2);
-int hicn_interest_set_lifetime (hicn_header_t * interest, u32 lifetime);
-int hicn_interest_get_lifetime (const hicn_header_t * interest,
- u32 * lifetime);
+ const hicn_header_t *interest,
+ ip_address_t *prefix);
+int hicn_interest_set_locator (hicn_format_t format, hicn_header_t *interest,
+ const ip_address_t *prefix);
+int hicn_interest_compare (const hicn_header_t *interest_1,
+ const hicn_header_t *interest_2);
+int hicn_interest_set_lifetime (hicn_header_t *interest, u32 lifetime);
+int hicn_interest_get_lifetime (const hicn_header_t *interest, u32 *lifetime);
int hicn_interest_get_header_length (hicn_format_t format,
- const hicn_header_t * interest,
- size_t * header_length);
+ const hicn_header_t *interest,
+ size_t *header_length);
int hicn_interest_get_payload_length (hicn_format_t format,
- const hicn_header_t * interest,
- size_t * payload_length);
-int hicn_interest_set_payload (hicn_format_t format, hicn_header_t * interest,
- const u8 * payload, size_t payload_length);
+ const hicn_header_t *interest,
+ size_t *payload_length);
+int hicn_interest_set_payload (hicn_format_t format, hicn_header_t *interest,
+ const u8 *payload, size_t payload_length);
int hicn_interest_get_payload (hicn_format_t format,
- const hicn_header_t * interest, u8 ** payload,
- size_t * payload_size, bool hard_copy);
-int hicn_interest_reset_for_hash (hicn_format_t format,
- hicn_header_t * packet);
+ const hicn_header_t *interest, u8 **payload,
+ size_t *payload_size, bool hard_copy);
+int hicn_interest_reset_for_hash (hicn_format_t format, hicn_header_t *packet);
/* Data */
-int hicn_data_get_name (hicn_format_t format, const hicn_header_t * data,
- hicn_name_t * name);
-int hicn_data_set_name (hicn_format_t format, hicn_header_t * data,
- const hicn_name_t * name);
-int hicn_data_get_locator (hicn_format_t format, const hicn_header_t * data,
- ip_address_t * prefix);
-int hicn_data_set_locator (hicn_format_t format, hicn_header_t * data,
- const ip_address_t * prefix);
-int hicn_data_compare (const hicn_header_t * data_1,
- const hicn_header_t * data_2);
-int hicn_data_get_expiry_time (const hicn_header_t * data, u32 * expiry_time);
-int hicn_data_set_expiry_time (hicn_header_t * data, u32 expiry_time);
-int hicn_data_get_header_length (hicn_format_t format, hicn_header_t * data,
- size_t * header_length);
+int hicn_data_get_name (hicn_format_t format, const hicn_header_t *data,
+ hicn_name_t *name);
+int hicn_data_set_name (hicn_format_t format, hicn_header_t *data,
+ const hicn_name_t *name);
+int hicn_data_get_locator (hicn_format_t format, const hicn_header_t *data,
+ ip_address_t *prefix);
+int hicn_data_set_locator (hicn_format_t format, hicn_header_t *data,
+ const ip_address_t *prefix);
+int hicn_data_compare (const hicn_header_t *data_1,
+ const hicn_header_t *data_2);
+int hicn_data_get_expiry_time (const hicn_header_t *data, u32 *expiry_time);
+int hicn_data_set_expiry_time (hicn_header_t *data, u32 expiry_time);
+int hicn_data_get_header_length (hicn_format_t format, hicn_header_t *data,
+ size_t *header_length);
int hicn_data_get_payload_length (hicn_format_t format,
- const hicn_header_t * data,
- size_t * payload_length);
-int hicn_data_get_path_label (const hicn_header_t * data, u32 * path_label);
-int hicn_data_set_path_label (hicn_header_t * data, u32 path_label);
-int hicn_data_get_payload (hicn_format_t format, const hicn_header_t * data,
- u8 ** payload, size_t * payload_size,
- bool hard_copy);
-int hicn_data_set_payload (hicn_format_t format, hicn_header_t * data,
- const u8 * payload, size_t payload_length);
-int hicn_data_get_payload_type (const hicn_header_t * data,
- hicn_payload_type_t * payload_type);
-int hicn_data_set_payload_type (hicn_header_t * data,
+ const hicn_header_t *data,
+ size_t *payload_length);
+int hicn_data_get_path_label (const hicn_header_t *data, u32 *path_label);
+int hicn_data_set_path_label (hicn_header_t *data, u32 path_label);
+int hicn_data_get_payload (hicn_format_t format, const hicn_header_t *data,
+ u8 **payload, size_t *payload_size, bool hard_copy);
+int hicn_data_set_payload (hicn_format_t format, hicn_header_t *data,
+ const u8 *payload, size_t payload_length);
+int hicn_data_get_payload_type (const hicn_header_t *data,
+ hicn_payload_type_t *payload_type);
+int hicn_data_set_payload_type (hicn_header_t *data,
hicn_payload_type_t payload_type);
-int hicn_data_reset_for_hash (hicn_format_t format, hicn_header_t * packet);
+int hicn_data_reset_for_hash (hicn_format_t format, hicn_header_t *packet);
#endif /* HICN_COMPAT_H */
diff --git a/lib/includes/hicn/ops.h b/lib/includes/hicn/ops.h
index e8feff9..7d4ae86 100644
--- a/lib/includes/hicn/ops.h
+++ b/lib/includes/hicn/ops.h
@@ -253,7 +253,7 @@ typedef struct hicn_ops_s
* @param [in,out] h - Buffer holding the packet
* @param [in] partial_csum - Partial checksum (set to 0, used internally to
* carry intermediate values from IP pseudo-header)
- * @param [in] payload_length - Payload length (can be set to 0, retrieved
+ * @param [in] payload_length - Payload length (can be set to ~0, retrieved
* and used internally to carry payload length across protocol headers)
* @return hICN error code
*/
@@ -264,9 +264,8 @@ typedef struct hicn_ops_s
* @brief Validate all checksums in packet headers
* @param [in] type - hICN packet type
* @param [in] h - Buffer holding the packet
- * @param [in] partial_csum - Partial checksum (set to 0, used internally to
- * carry intermediate values from IP pseudo-header)
- * @param [in] payload_length - Payload length (can be set to 0, retrieved
+ * @param [in] partial_csum - Partial checksum, or zero if no partial checksum available
+ * @param [in] payload_length - Payload length (can be set to ~0, retrieved
* and used internally to carry payload length across protocol headers)
* @return hICN error code
*/
@@ -294,12 +293,15 @@ typedef struct hicn_ops_s
* @param [in] addr_old - Old locator (set to NULL, used internally to
* compute incremental checksums)
* @param [in] face_id - Face identifier used to update pathlabel
+ * @param [in] reset_pl - If not zero, reset the current pathlabel
+ * before update it
* @return hICN error code
*/
int (*rewrite_data) (hicn_type_t type, hicn_protocol_t * h,
const ip46_address_t * addr_new,
ip46_address_t * addr_old,
- const hicn_faceid_t face_id);
+ const hicn_faceid_t face_id,
+ u8 reset_pl);
/**
* @brief Return the packet length
@@ -610,7 +612,7 @@ PAYLOAD (hicn_type_t type, const hicn_protocol_t * h)
int protocol ## _rewrite_interest(hicn_type_t type, hicn_protocol_t * h, const ip46_address_t * addr_new, ip46_address_t * addr_old) { return HICN_LIB_ERROR_ ## error ; }
#define DECLARE_rewrite_data(protocol, error) \
- int protocol ## _rewrite_data(hicn_type_t type, hicn_protocol_t * h, const ip46_address_t * addr_new, ip46_address_t * addr_old, const hicn_faceid_t face_id) { return HICN_LIB_ERROR_ ## error ; }
+ int protocol ## _rewrite_data(hicn_type_t type, hicn_protocol_t * h, const ip46_address_t * addr_new, ip46_address_t * addr_old, const hicn_faceid_t face_id, u8 reset_pl) { return HICN_LIB_ERROR_ ## error ; }
#define DECLARE_get_length(protocol, error) \
int protocol ## _get_length(hicn_type_t type, const hicn_protocol_t * h, size_t * length) { return HICN_LIB_ERROR_ ## error ; }
diff --git a/lib/src/CMakeLists.txt b/lib/src/CMakeLists.txt
index 7eecaf7..49b735f 100644
--- a/lib/src/CMakeLists.txt
+++ b/lib/src/CMakeLists.txt
@@ -42,7 +42,7 @@ if (DISABLE_SHARED_LIBRARIES)
COMPONENT lib${LIBHICN}
INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../includes
DEFINITIONS ${COMPILER_DEFINITIONS}
- INSTALL_ROOT_DIR hicn
+ HEADER_ROOT_DIR hicn
INSTALL_HEADERS ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} ${LIBHICN_HEADER_FILES_UTIL}
LINK_LIBRARIES ${WSOCK32_LIBRARY} ${WS2_32_LIBRARY}
)
@@ -53,7 +53,7 @@ else ()
COMPONENT lib${LIBHICN}
INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../includes
DEFINITIONS ${COMPILER_DEFINITIONS}
- INSTALL_ROOT_DIR hicn
+ HEADER_ROOT_DIR hicn
INSTALL_HEADERS ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} ${LIBHICN_HEADER_FILES_UTIL}
LINK_LIBRARIES ${WSOCK32_LIBRARY} ${WS2_32_LIBRARY}
)
diff --git a/lib/src/common.c b/lib/src/common.c
index 228a59d..562771e 100644
--- a/lib/src/common.c
+++ b/lib/src/common.c
@@ -119,7 +119,7 @@ hicn_packet_dump (const uint8_t * buffer, size_t len)
// Output description if given.
if (len == 0)
{
- TRACE (" ZERO LENGTH\n");
+ printf (" ZERO LENGTH\n");
return;
}
@@ -132,14 +132,14 @@ hicn_packet_dump (const uint8_t * buffer, size_t len)
{
// Just don't print ASCII for the zeroth line.
if (i != 0)
- TRACE (" %s\n", buff);
+ printf (" %s\n", buff);
// Output the offset.
- TRACE (" %04x ", i);
+ printf (" %04x ", i);
}
// Now the hex code for the specific character.
- TRACE (" %02x", pc[i]);
+ printf (" %02x", pc[i]);
// And store a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e))
@@ -152,12 +152,12 @@ hicn_packet_dump (const uint8_t * buffer, size_t len)
// Pad out last line if not exactly 16 characters.
while ((i % 16) != 0)
{
- TRACE (" ");
+ printf (" ");
i++;
}
// And print the final ASCII bit.
- TRACE (" %s\n", buff);
+ printf (" %s\n", buff);
}
/*
diff --git a/lib/src/compat.c b/lib/src/compat.c
index 615175e..779a473 100644
--- a/lib/src/compat.c
+++ b/lib/src/compat.c
@@ -20,8 +20,8 @@
#ifndef _WIN32
#include <netinet/in.h>
#endif
-#include <string.h> // memset
-#include <stddef.h> // offsetof
+#include <string.h> // memset
+#include <stddef.h> // offsetof
#include <hicn/common.h>
#include <hicn/compat.h>
@@ -30,13 +30,13 @@
#include <hicn/name.h>
#include <hicn/ops.h>
-#define member_size(type, member) sizeof(((type *)0)->member)
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+#define member_size(type, member) sizeof (((type *) 0)->member)
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a)))
#define HICN_NAME_COMPONENT_SIZE 2
int
-hicn_packet_get_format (const hicn_header_t * h, hicn_format_t * format)
+hicn_packet_get_format (const hicn_header_t *h, hicn_format_t *format)
{
*format = HF_UNSPEC;
@@ -122,7 +122,7 @@ hicn_format_to_type (hicn_format_t format)
* This function is used to wrap old API calls to new ones
*/
hicn_type_t
-hicn_header_to_type (const hicn_header_t * h)
+hicn_header_to_type (const hicn_header_t *h)
{
hicn_format_t format;
hicn_packet_get_format (h, &format);
@@ -130,39 +130,47 @@ hicn_header_to_type (const hicn_header_t * h)
}
int
-hicn_packet_init_header (hicn_format_t format, hicn_header_t * packet)
+hicn_packet_init_header (hicn_format_t format, hicn_header_t *packet)
{
hicn_type_t type = hicn_format_to_type (format);
+
+ if (hicn_type_is_none (type))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
return hicn_ops_vft[type.l1]->init_packet_header (type, &packet->protocol);
}
int
-hicn_packet_compute_checksum (hicn_format_t format, hicn_header_t * h)
+hicn_packet_compute_checksum (hicn_format_t format, hicn_header_t *h)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->update_checksums (type, &h->protocol, 0, 0);
+ return hicn_ops_vft[type.l1]->update_checksums (type, &h->protocol, 0, ~0);
}
int
-hicn_packet_compute_header_checksum (hicn_format_t format, hicn_header_t * h,
+hicn_packet_compute_header_checksum (hicn_format_t format, hicn_header_t *h,
u16 init_sum)
{
hicn_type_t type = hicn_format_to_type (format);
- /* payload_length == ~0: ignore payload */
- return hicn_ops_vft[type.l1]->update_checksums (type, &h->protocol,
- init_sum, ~0);
+ /* payload_length == 0: ignore payload */
+ return hicn_ops_vft[type.l1]->update_checksums (type, &h->protocol, init_sum,
+ 0);
}
int
-hicn_packet_check_integrity (hicn_format_t format, hicn_header_t * h)
+hicn_packet_check_integrity_no_payload (hicn_format_t format, hicn_header_t *h,
+ u16 init_sum)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->verify_checksums (type, &h->protocol, 0, 0);
+ return hicn_ops_vft[type.l1]->verify_checksums (type, &h->protocol, init_sum,
+ 0);
}
int
hicn_packet_get_header_length_from_format (hicn_format_t format,
- size_t * header_length)
+ size_t *header_length)
{
*header_length = _is_ipv4 (format) * IPV4_HDRLEN;
*header_length += _is_ipv6 (format) * IPV6_HDRLEN;
@@ -174,8 +182,8 @@ hicn_packet_get_header_length_from_format (hicn_format_t format,
}
int
-hicn_packet_get_header_length (hicn_format_t format, const hicn_header_t * h,
- size_t * header_length)
+hicn_packet_get_header_length (hicn_format_t format, const hicn_header_t *h,
+ size_t *header_length)
{
hicn_packet_get_header_length_from_format (format, header_length);
int is_ah = _is_ah (format);
@@ -184,15 +192,15 @@ hicn_packet_get_header_length (hicn_format_t format, const hicn_header_t * h,
// The signature payload is expressed as number of 32 bits words
if (is_ah && is_ipv4)
*header_length += (h->v4ah.ah.payloadlen) << 2;
- else if(is_ah && is_ipv6)
+ else if (is_ah && is_ipv6)
*header_length += (h->v6ah.ah.payloadlen) << 2;
return HICN_LIB_ERROR_NONE;
}
int
-hicn_packet_get_payload_length (hicn_format_t format, const hicn_header_t * h,
- size_t * payload_length)
+hicn_packet_get_payload_length (hicn_format_t format, const hicn_header_t *h,
+ size_t *payload_length)
{
hicn_type_t type = hicn_format_to_type (format);
return hicn_ops_vft[type.l1]->get_payload_length (type, &h->protocol,
@@ -200,7 +208,7 @@ hicn_packet_get_payload_length (hicn_format_t format, const hicn_header_t * h,
}
int
-hicn_packet_set_payload_length (hicn_format_t format, hicn_header_t * h,
+hicn_packet_set_payload_length (hicn_format_t format, hicn_header_t *h,
const size_t payload_length)
{
hicn_type_t type = hicn_format_to_type (format);
@@ -209,8 +217,8 @@ hicn_packet_set_payload_length (hicn_format_t format, hicn_header_t * h,
}
int
-hicn_packet_compare (const hicn_header_t * packet1,
- const hicn_header_t * packet2)
+hicn_packet_compare (const hicn_header_t *packet1,
+ const hicn_header_t *packet2)
{
hicn_type_t type1 = hicn_header_to_type (packet1);
hicn_type_t type2 = hicn_header_to_type (packet2);
@@ -233,25 +241,23 @@ hicn_packet_compare (const hicn_header_t * packet1,
return HICN_LIB_ERROR_UNEXPECTED;
return memcmp ((u8 *) packet1, (u8 *) packet2, len1);
-
}
int
-hicn_packet_get_name (hicn_format_t format, const hicn_header_t * h,
- hicn_name_t * name, u8 is_interest)
+hicn_packet_get_name (hicn_format_t format, const hicn_header_t *h,
+ hicn_name_t *name, u8 is_interest)
{
hicn_type_t type = hicn_format_to_type (format);
if (is_interest)
- return hicn_ops_vft[type.l1]->get_interest_name (type, &h->protocol,
- name);
+ return hicn_ops_vft[type.l1]->get_interest_name (type, &h->protocol, name);
else
return hicn_ops_vft[type.l1]->get_data_name (type, &h->protocol, name);
}
int
-hicn_packet_set_name (hicn_format_t format, hicn_header_t * h,
- const hicn_name_t * name, u8 is_interest)
+hicn_packet_set_name (hicn_format_t format, hicn_header_t *h,
+ const hicn_name_t *name, u8 is_interest)
{
hicn_type_t type = hicn_format_to_type (format);
@@ -261,23 +267,21 @@ hicn_packet_set_name (hicn_format_t format, hicn_header_t * h,
#endif /* HICN_VPP_PLUGIN */
if (is_interest)
- return hicn_ops_vft[type.l1]->set_interest_name (type, &h->protocol,
- name);
+ return hicn_ops_vft[type.l1]->set_interest_name (type, &h->protocol, name);
else
return hicn_ops_vft[type.l1]->set_data_name (type, &h->protocol, name);
}
int
-hicn_packet_set_payload (hicn_format_t format, hicn_header_t * h,
- const u8 * payload, u16 payload_length)
+hicn_packet_set_payload (hicn_format_t format, hicn_header_t *h,
+ const u8 *payload, u16 payload_length)
{
hicn_type_t type = hicn_format_to_type (format);
size_t header_length;
int rc;
- rc =
- hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol,
- &header_length);
+ rc = hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol,
+ &header_length);
if (rc < 0)
return rc;
@@ -288,22 +292,20 @@ hicn_packet_set_payload (hicn_format_t format, hicn_header_t * h,
}
int
-hicn_packet_get_payload (hicn_format_t format, const hicn_header_t * h,
- u8 ** payload, size_t * payload_size, bool hard_copy)
+hicn_packet_get_payload (hicn_format_t format, const hicn_header_t *h,
+ u8 **payload, size_t *payload_size, bool hard_copy)
{
size_t header_length, payload_length;
int rc;
hicn_type_t type = hicn_format_to_type (format);
- rc =
- hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol,
- &header_length);
+ rc = hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol,
+ &header_length);
if (rc < 0)
return rc;
- rc =
- hicn_ops_vft[type.l1]->get_payload_length (type, &h->protocol,
- &payload_length);
+ rc = hicn_ops_vft[type.l1]->get_payload_length (type, &h->protocol,
+ &payload_length);
if (rc < 0)
return rc;
@@ -320,23 +322,21 @@ hicn_packet_get_payload (hicn_format_t format, const hicn_header_t * h,
}
int
-hicn_packet_get_locator (hicn_format_t format, const hicn_header_t * h,
- ip_address_t * address, bool is_interest)
+hicn_packet_get_locator (hicn_format_t format, const hicn_header_t *h,
+ ip_address_t *address, bool is_interest)
{
int is_ipv4 = (format & HFO_INET);
int is_ipv6 = (format & HFO_INET6) >> 1;
if (is_ipv4)
{
- address->v4.as_inaddr = is_interest
- ? h->v4.ip.saddr.as_inaddr
- : h->v4.ip.daddr.as_inaddr;
+ address->v4.as_inaddr =
+ is_interest ? h->v4.ip.saddr.as_inaddr : h->v4.ip.daddr.as_inaddr;
}
else if (is_ipv6)
{
- address->v6.as_in6addr = is_interest
- ? h->v6.ip.saddr.as_in6addr
- : h->v6.ip.daddr.as_in6addr;
+ address->v6.as_in6addr =
+ is_interest ? h->v6.ip.saddr.as_in6addr : h->v6.ip.daddr.as_in6addr;
}
else
{
@@ -347,25 +347,25 @@ hicn_packet_get_locator (hicn_format_t format, const hicn_header_t * h,
}
int
-hicn_packet_set_locator (hicn_format_t format, hicn_header_t * h,
- const ip_address_t * address, bool is_interest)
+hicn_packet_set_locator (hicn_format_t format, hicn_header_t *h,
+ const ip_address_t *address, bool is_interest)
{
int is_ipv4 = (format & HFO_INET);
int is_ipv6 = (format & HFO_INET6) >> 1;
if (is_ipv6)
{
- if (is_interest)
- h->v6.ip.saddr.as_in6addr = address->v6.as_in6addr;
- else
- h->v6.ip.daddr.as_in6addr = address->v6.as_in6addr;
+ if (is_interest)
+ h->v6.ip.saddr.as_in6addr = address->v6.as_in6addr;
+ else
+ h->v6.ip.daddr.as_in6addr = address->v6.as_in6addr;
}
else if (is_ipv4)
{
- if (is_interest)
- h->v4.ip.saddr.as_inaddr = address->v4.as_inaddr;
- else
- h->v4.ip.daddr.as_inaddr = address->v4.as_inaddr;
+ if (is_interest)
+ h->v4.ip.saddr.as_inaddr = address->v4.as_inaddr;
+ else
+ h->v4.ip.daddr.as_inaddr = address->v4.as_inaddr;
}
else
{
@@ -376,79 +376,78 @@ hicn_packet_set_locator (hicn_format_t format, hicn_header_t * h,
}
int
-hicn_packet_get_signature_size (hicn_format_t format, const hicn_header_t * h,
- size_t * bytes)
+hicn_packet_get_signature_size (hicn_format_t format, const hicn_header_t *h,
+ size_t *bytes)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_signature_size (type, &h->protocol,
- bytes);
+ return hicn_ops_vft[type.l1]->get_signature_size (type, &h->protocol, bytes);
}
int
-hicn_packet_set_signature_size (hicn_format_t format, hicn_header_t * h,
+hicn_packet_set_signature_size (hicn_format_t format, hicn_header_t *h,
size_t bytes)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_signature_size (type, &h->protocol,
- bytes);
+ return hicn_ops_vft[type.l1]->set_signature_size (type, &h->protocol, bytes);
}
int
-hicn_packet_set_signature_timestamp (hicn_format_t format, hicn_header_t * h,
- uint64_t signature_timestamp)
+hicn_packet_set_signature_timestamp (hicn_format_t format, hicn_header_t *h,
+ uint64_t signature_timestamp)
{
hicn_type_t type = hicn_format_to_type (format);
return hicn_ops_vft[type.l1]->set_signature_timestamp (type, &h->protocol,
- signature_timestamp);
+ signature_timestamp);
}
int
-hicn_packet_get_signature_timestamp (hicn_format_t format, const hicn_header_t * h,
- uint64_t *signature_timestamp)
+hicn_packet_get_signature_timestamp (hicn_format_t format,
+ const hicn_header_t *h,
+ uint64_t *signature_timestamp)
{
hicn_type_t type = hicn_format_to_type (format);
return hicn_ops_vft[type.l1]->get_signature_timestamp (type, &h->protocol,
- signature_timestamp);
+ signature_timestamp);
}
int
-hicn_packet_set_validation_algorithm (hicn_format_t format, hicn_header_t * h,
- uint8_t validation_algorithm)
+hicn_packet_set_validation_algorithm (hicn_format_t format, hicn_header_t *h,
+ uint8_t validation_algorithm)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_validation_algorithm (type, &h->protocol,
- validation_algorithm);
+ return hicn_ops_vft[type.l1]->set_validation_algorithm (
+ type, &h->protocol, validation_algorithm);
}
int
-hicn_packet_get_validation_algorithm (hicn_format_t format, const hicn_header_t * h,
- uint8_t * validation_algorithm)
+hicn_packet_get_validation_algorithm (hicn_format_t format,
+ const hicn_header_t *h,
+ uint8_t *validation_algorithm)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_validation_algorithm (type, &h->protocol,
- validation_algorithm);
+ return hicn_ops_vft[type.l1]->get_validation_algorithm (
+ type, &h->protocol, validation_algorithm);
}
int
-hicn_packet_set_key_id (hicn_format_t format, hicn_header_t * h,
- uint8_t *key_id)
+hicn_packet_set_key_id (hicn_format_t format, hicn_header_t *h,
+ uint8_t *key_id)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_key_id (type, &h->protocol,
- key_id);
+ return hicn_ops_vft[type.l1]->set_key_id (type, &h->protocol, key_id);
}
int
-hicn_packet_get_key_id (hicn_format_t format, hicn_header_t * h,
- uint8_t ** key_id, uint8_t *key_id_length)
+hicn_packet_get_key_id (hicn_format_t format, hicn_header_t *h,
+ uint8_t **key_id, uint8_t *key_id_length)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_key_id (type, &h->protocol,
- key_id, key_id_length);
+ return hicn_ops_vft[type.l1]->get_key_id (type, &h->protocol, key_id,
+ key_id_length);
}
int
-hicn_packet_get_hoplimit (const hicn_header_t * h, u8 * hops)
+hicn_packet_get_hoplimit (const hicn_header_t *h, u8 *hops)
{
switch (HICN_IP_VERSION (h))
{
@@ -466,7 +465,7 @@ hicn_packet_get_hoplimit (const hicn_header_t * h, u8 * hops)
}
int
-hicn_packet_set_hoplimit (hicn_header_t * h, u8 hops)
+hicn_packet_set_hoplimit (hicn_header_t *h, u8 hops)
{
switch (HICN_IP_VERSION (h))
{
@@ -483,9 +482,8 @@ hicn_packet_set_hoplimit (hicn_header_t * h, u8 hops)
return HICN_LIB_ERROR_NONE;
}
-
int
-hicn_packet_get_lifetime (const hicn_header_t * h, u32 * lifetime)
+hicn_packet_get_lifetime (const hicn_header_t *h, u32 *lifetime)
{
hicn_type_t type = hicn_header_to_type (h);
return hicn_ops_vft[type.l1]->get_lifetime (type, &h->protocol,
@@ -493,7 +491,7 @@ hicn_packet_get_lifetime (const hicn_header_t * h, u32 * lifetime)
}
int
-hicn_packet_set_lifetime (hicn_header_t * h, u32 lifetime)
+hicn_packet_set_lifetime (hicn_header_t *h, u32 lifetime)
{
hicn_type_t type = hicn_header_to_type (h);
return hicn_ops_vft[type.l1]->set_lifetime (type, &h->protocol,
@@ -501,15 +499,15 @@ hicn_packet_set_lifetime (hicn_header_t * h, u32 lifetime)
}
int
-hicn_packet_get_reserved_bits (const hicn_header_t * h, u8 * reserved_bits)
+hicn_packet_get_reserved_bits (const hicn_header_t *h, u8 *reserved_bits)
{
switch (HICN_IP_VERSION (h))
{
case 6:
- *reserved_bits = (u8)(h->v6.tcp.reserved);
+ *reserved_bits = (u8) (h->v6.tcp.reserved);
break;
case 4:
- *reserved_bits = (u8)(h->v4.tcp.reserved);
+ *reserved_bits = (u8) (h->v4.tcp.reserved);
break;
default:
return HICN_LIB_ERROR_UNEXPECTED;
@@ -519,7 +517,7 @@ hicn_packet_get_reserved_bits (const hicn_header_t * h, u8 * reserved_bits)
}
int
-hicn_packet_set_reserved_bits (hicn_header_t * h, const u8 reserved_bits)
+hicn_packet_set_reserved_bits (hicn_header_t *h, const u8 reserved_bits)
{
switch (HICN_IP_VERSION (h))
{
@@ -537,16 +535,18 @@ hicn_packet_set_reserved_bits (hicn_header_t * h, const u8 reserved_bits)
}
int
-hicn_packet_get_payload_type (const hicn_header_t * h,
- hicn_payload_type_t * payload_type)
+hicn_packet_get_payload_type (const hicn_header_t *h,
+ hicn_payload_type_t *payload_type)
{
switch (HICN_IP_VERSION (h))
{
case 6:
- *payload_type = ((h->v6.tcp.flags & HICN_TCP_FLAG_URG) == HICN_TCP_FLAG_URG);
+ *payload_type =
+ ((h->v6.tcp.flags & HICN_TCP_FLAG_URG) == HICN_TCP_FLAG_URG);
break;
case 4:
- *payload_type = ((h->v4.tcp.flags & HICN_TCP_FLAG_URG) == HICN_TCP_FLAG_URG);
+ *payload_type =
+ ((h->v4.tcp.flags & HICN_TCP_FLAG_URG) == HICN_TCP_FLAG_URG);
break;
default:
return HICN_LIB_ERROR_UNEXPECTED;
@@ -561,7 +561,7 @@ hicn_packet_get_payload_type (const hicn_header_t * h,
}
int
-hicn_packet_set_payload_type (hicn_header_t * h,
+hicn_packet_set_payload_type (hicn_header_t *h,
hicn_payload_type_t payload_type)
{
if (payload_type != HPT_DATA && payload_type != HPT_MANIFEST)
@@ -591,8 +591,13 @@ hicn_packet_set_payload_type (hicn_header_t * h,
}
int
-hicn_packet_set_syn (hicn_header_t * h)
+hicn_packet_set_syn (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -608,8 +613,13 @@ hicn_packet_set_syn (hicn_header_t * h)
}
int
-hicn_packet_reset_syn (hicn_header_t * h)
+hicn_packet_reset_syn (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -625,8 +635,13 @@ hicn_packet_reset_syn (hicn_header_t * h)
}
int
-hicn_packet_test_syn (const hicn_header_t * h, bool * flag)
+hicn_packet_test_syn (hicn_format_t format, const hicn_header_t *h, bool *flag)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -642,8 +657,13 @@ hicn_packet_test_syn (const hicn_header_t * h, bool * flag)
}
int
-hicn_packet_set_ack (hicn_header_t * h)
+hicn_packet_set_ack (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -659,8 +679,13 @@ hicn_packet_set_ack (hicn_header_t * h)
}
int
-hicn_packet_reset_ack (hicn_header_t * h)
+hicn_packet_reset_ack (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -676,8 +701,13 @@ hicn_packet_reset_ack (hicn_header_t * h)
}
int
-hicn_packet_test_ack (const hicn_header_t * h, bool * flag)
+hicn_packet_test_ack (hicn_format_t format, const hicn_header_t *h, bool *flag)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -693,8 +723,13 @@ hicn_packet_test_ack (const hicn_header_t * h, bool * flag)
}
int
-hicn_packet_set_rst (hicn_header_t * h)
+hicn_packet_set_rst (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -710,8 +745,13 @@ hicn_packet_set_rst (hicn_header_t * h)
}
int
-hicn_packet_reset_rst (hicn_header_t * h)
+hicn_packet_reset_rst (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -727,8 +767,13 @@ hicn_packet_reset_rst (hicn_header_t * h)
}
int
-hicn_packet_test_rst (const hicn_header_t * h, bool * flag)
+hicn_packet_test_rst (hicn_format_t format, const hicn_header_t *h, bool *flag)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -744,8 +789,13 @@ hicn_packet_test_rst (const hicn_header_t * h, bool * flag)
}
int
-hicn_packet_set_fin (hicn_header_t * h)
+hicn_packet_set_fin (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -761,8 +811,13 @@ hicn_packet_set_fin (hicn_header_t * h)
}
int
-hicn_packet_reset_fin (hicn_header_t * h)
+hicn_packet_reset_fin (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -778,8 +833,13 @@ hicn_packet_reset_fin (hicn_header_t * h)
}
int
-hicn_packet_test_fin (const hicn_header_t * h, bool * flag)
+hicn_packet_test_fin (hicn_format_t format, const hicn_header_t *h, bool *flag)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -795,8 +855,13 @@ hicn_packet_test_fin (const hicn_header_t * h, bool * flag)
}
int
-hicn_packet_set_ece (hicn_header_t * h)
+hicn_packet_set_ece (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -812,8 +877,13 @@ hicn_packet_set_ece (hicn_header_t * h)
}
int
-hicn_packet_reset_ece (hicn_header_t * h)
+hicn_packet_reset_ece (hicn_format_t format, hicn_header_t *h)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -829,8 +899,13 @@ hicn_packet_reset_ece (hicn_header_t * h)
}
int
-hicn_packet_test_ece (const hicn_header_t * h, bool * flag)
+hicn_packet_test_ece (hicn_format_t format, const hicn_header_t *h, bool *flag)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -846,8 +921,13 @@ hicn_packet_test_ece (const hicn_header_t * h, bool * flag)
}
int
-hicn_packet_set_src_port (hicn_header_t * h, u16 src_port)
+hicn_packet_set_src_port (hicn_format_t format, hicn_header_t *h, u16 src_port)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -863,8 +943,14 @@ hicn_packet_set_src_port (hicn_header_t * h, u16 src_port)
}
int
-hicn_packet_get_src_port (const hicn_header_t * h, u16 * src_port)
+hicn_packet_get_src_port (hicn_format_t format, const hicn_header_t *h,
+ u16 *src_port)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -880,8 +966,13 @@ hicn_packet_get_src_port (const hicn_header_t * h, u16 * src_port)
}
int
-hicn_packet_set_dst_port (hicn_header_t * h, u16 dst_port)
+hicn_packet_set_dst_port (hicn_format_t format, hicn_header_t *h, u16 dst_port)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -897,8 +988,14 @@ hicn_packet_set_dst_port (hicn_header_t * h, u16 dst_port)
}
int
-hicn_packet_get_dst_port (const hicn_header_t * h, u16 * dst_port)
+hicn_packet_get_dst_port (hicn_format_t format, const hicn_header_t *h,
+ u16 *dst_port)
{
+ if (!_is_tcp (format))
+ {
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+
switch (HICN_IP_VERSION (h))
{
case 6:
@@ -914,8 +1011,8 @@ hicn_packet_get_dst_port (const hicn_header_t * h, u16 * dst_port)
}
int
-hicn_packet_copy_header (hicn_format_t format, const hicn_header_t * packet,
- hicn_header_t * destination, bool copy_ah)
+hicn_packet_copy_header (hicn_format_t format, const hicn_header_t *packet,
+ hicn_header_t *destination, bool copy_ah)
{
size_t header_length = _is_ipv4 (format) * IPV4_HDRLEN;
header_length += _is_ipv6 (format) * IPV6_HDRLEN;
@@ -929,95 +1026,95 @@ hicn_packet_copy_header (hicn_format_t format, const hicn_header_t * packet,
}
#define _INTEREST 1
-#define _DATA 0
+#define _DATA 0
/* Interest */
int
-hicn_interest_get_name (hicn_format_t format, const hicn_header_t * interest,
- hicn_name_t * name)
+hicn_interest_get_name (hicn_format_t format, const hicn_header_t *interest,
+ hicn_name_t *name)
{
return hicn_packet_get_name (format, interest, name, _INTEREST);
}
int
-hicn_interest_set_name (hicn_format_t format, hicn_header_t * interest,
- const hicn_name_t * name)
+hicn_interest_set_name (hicn_format_t format, hicn_header_t *interest,
+ const hicn_name_t *name)
{
- int ret_err = hicn_packet_reset_ece (interest); //interest packet -> ece flag unset
+ int ret_err =
+ hicn_packet_reset_ece (format, interest); // interest packet -> ece flag unset
if (ret_err < 0)
return HICN_LIB_ERROR_UNEXPECTED;
return hicn_packet_set_name (format, interest, name, _INTEREST);
}
int
-hicn_interest_get_locator (hicn_format_t format,
- const hicn_header_t * interest,
- ip_address_t * address)
+hicn_interest_get_locator (hicn_format_t format, const hicn_header_t *interest,
+ ip_address_t *address)
{
return hicn_packet_get_locator (format, interest, address, _INTEREST);
}
int
-hicn_interest_set_locator (hicn_format_t format, hicn_header_t * interest,
- const ip_address_t * address)
+hicn_interest_set_locator (hicn_format_t format, hicn_header_t *interest,
+ const ip_address_t *address)
{
return hicn_packet_set_locator (format, interest, address, _INTEREST);
}
int
-hicn_interest_compare (const hicn_header_t * interest_1,
- const hicn_header_t * interest_2)
+hicn_interest_compare (const hicn_header_t *interest_1,
+ const hicn_header_t *interest_2)
{
return hicn_packet_compare (interest_1, interest_2);
}
int
-hicn_interest_get_lifetime (const hicn_header_t * interest, u32 * lifetime)
+hicn_interest_get_lifetime (const hicn_header_t *interest, u32 *lifetime)
{
return hicn_packet_get_lifetime (interest, lifetime);
}
int
-hicn_interest_set_lifetime (hicn_header_t * interest, u32 lifetime)
+hicn_interest_set_lifetime (hicn_header_t *interest, u32 lifetime)
{
return hicn_packet_set_lifetime (interest, lifetime);
}
int
hicn_interest_get_header_length (hicn_format_t format,
- const hicn_header_t * interest,
- size_t * header_length)
+ const hicn_header_t *interest,
+ size_t *header_length)
{
return hicn_packet_get_header_length (format, interest, header_length);
}
int
hicn_interest_get_payload_length (hicn_format_t format,
- const hicn_header_t * interest,
- size_t * payload_length)
+ const hicn_header_t *interest,
+ size_t *payload_length)
{
return hicn_packet_get_payload_length (format, interest, payload_length);
}
int
-hicn_interest_get_payload (hicn_format_t format,
- const hicn_header_t * interest, u8 ** payload,
- size_t * payload_size, bool hard_copy)
+hicn_interest_get_payload (hicn_format_t format, const hicn_header_t *interest,
+ u8 **payload, size_t *payload_size, bool hard_copy)
{
return hicn_packet_get_payload (format, interest, payload, payload_size,
hard_copy);
}
int
-hicn_interest_set_payload (hicn_format_t format, hicn_header_t * interest,
- const u8 * payload, size_t payload_length)
+hicn_interest_set_payload (hicn_format_t format, hicn_header_t *interest,
+ const u8 *payload, size_t payload_length)
{
- return hicn_packet_set_payload (format, interest, payload, (u16)payload_length);
+ return hicn_packet_set_payload (format, interest, payload,
+ (u16) payload_length);
}
int
-hicn_interest_reset_for_hash (hicn_format_t format, hicn_header_t * packet)
+hicn_interest_reset_for_hash (hicn_format_t format, hicn_header_t *packet)
{
hicn_type_t type = hicn_format_to_type (format);
return hicn_ops_vft[type.l1]->reset_interest_for_hash (type,
@@ -1027,85 +1124,84 @@ hicn_interest_reset_for_hash (hicn_format_t format, hicn_header_t * packet)
/* Data */
int
-hicn_data_get_name (hicn_format_t format, const hicn_header_t * data,
- hicn_name_t * name)
+hicn_data_get_name (hicn_format_t format, const hicn_header_t *data,
+ hicn_name_t *name)
{
return hicn_packet_get_name (format, data, name, _DATA);
}
int
-hicn_data_set_name (hicn_format_t format, hicn_header_t * data,
- const hicn_name_t * name)
+hicn_data_set_name (hicn_format_t format, hicn_header_t *data,
+ const hicn_name_t *name)
{
- int ret_err = hicn_packet_set_ece (data); //data packet -> ece flag set
+ int ret_err = hicn_packet_set_ece (format, data); // data packet -> ece flag set
if (ret_err < 0)
return HICN_LIB_ERROR_UNEXPECTED;
return hicn_packet_set_name (format, data, name, _DATA);
}
int
-hicn_data_get_locator (hicn_format_t format, const hicn_header_t * data,
- ip_address_t * address)
+hicn_data_get_locator (hicn_format_t format, const hicn_header_t *data,
+ ip_address_t *address)
{
return hicn_packet_get_locator (format, data, address, _DATA);
}
int
-hicn_data_set_locator (hicn_format_t format, hicn_header_t * data,
- const ip_address_t * address)
+hicn_data_set_locator (hicn_format_t format, hicn_header_t *data,
+ const ip_address_t *address)
{
return hicn_packet_set_locator (format, data, address, _DATA);
}
int
-hicn_data_compare (const hicn_header_t * data_1, const hicn_header_t * data_2)
+hicn_data_compare (const hicn_header_t *data_1, const hicn_header_t *data_2)
{
return hicn_packet_compare (data_1, data_2);
}
int
-hicn_data_get_expiry_time (const hicn_header_t * data, u32 * expiry_time)
+hicn_data_get_expiry_time (const hicn_header_t *data, u32 *expiry_time)
{
return hicn_packet_get_lifetime (data, expiry_time);
}
int
-hicn_data_set_expiry_time (hicn_header_t * data, u32 expiry_time)
+hicn_data_set_expiry_time (hicn_header_t *data, u32 expiry_time)
{
return hicn_packet_set_lifetime (data, (hicn_lifetime_t) expiry_time);
}
int
-hicn_data_get_header_length (hicn_format_t format, hicn_header_t * data,
- size_t * header_length)
+hicn_data_get_header_length (hicn_format_t format, hicn_header_t *data,
+ size_t *header_length)
{
return hicn_packet_get_header_length (format, data, header_length);
}
int
-hicn_data_get_payload_length (hicn_format_t format,
- const hicn_header_t * data,
- size_t * payload_length)
+hicn_data_get_payload_length (hicn_format_t format, const hicn_header_t *data,
+ size_t *payload_length)
{
return hicn_packet_get_payload_length (format, data, payload_length);
}
int
-hicn_data_set_payload_type (hicn_header_t * data,
+hicn_data_set_payload_type (hicn_header_t *data,
hicn_payload_type_t payload_type)
{
return hicn_packet_set_payload_type (data, payload_type);
}
int
-hicn_data_get_payload_type (const hicn_header_t * data,
- hicn_payload_type_t * payload_type)
+hicn_data_get_payload_type (const hicn_header_t *data,
+ hicn_payload_type_t *payload_type)
{
return hicn_packet_get_payload_type (data, payload_type);
}
int
-hicn_data_get_path_label (const hicn_header_t * data, u32 * path_label)
+hicn_data_get_path_label (const hicn_header_t *data, u32 *path_label)
{
hicn_type_t type = hicn_header_to_type (data);
return hicn_ops_vft[type.l1]->get_data_pathlabel (type, &data->protocol,
@@ -1113,7 +1209,7 @@ hicn_data_get_path_label (const hicn_header_t * data, u32 * path_label)
}
int
-hicn_data_set_path_label (hicn_header_t * data, u32 path_label)
+hicn_data_set_path_label (hicn_header_t *data, u32 path_label)
{
hicn_type_t type = hicn_header_to_type (data);
return hicn_ops_vft[type.l1]->set_data_pathlabel (type, &data->protocol,
@@ -1121,34 +1217,34 @@ hicn_data_set_path_label (hicn_header_t * data, u32 path_label)
}
int
-hicn_data_set_payload (hicn_format_t format, hicn_header_t * data,
- const u8 * payload, size_t payload_length)
+hicn_data_set_payload (hicn_format_t format, hicn_header_t *data,
+ const u8 *payload, size_t payload_length)
{
- return hicn_packet_set_payload (format, data, payload, (u16)payload_length);
+ return hicn_packet_set_payload (format, data, payload, (u16) payload_length);
}
int
-hicn_data_get_payload (hicn_format_t format, const hicn_header_t * data,
- u8 ** payload, size_t * payload_size, bool hard_copy)
+hicn_data_get_payload (hicn_format_t format, const hicn_header_t *data,
+ u8 **payload, size_t *payload_size, bool hard_copy)
{
return hicn_packet_get_payload (format, data, payload, payload_size,
hard_copy);
}
int
-hicn_data_reset_for_hash (hicn_format_t format, hicn_header_t * packet)
+hicn_data_reset_for_hash (hicn_format_t format, hicn_header_t *packet)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->reset_data_for_hash (type,
- &packet->protocol);
-
+ return hicn_ops_vft[type.l1]->reset_data_for_hash (type, &packet->protocol);
}
-int hicn_packet_get_signature(hicn_format_t format, hicn_header_t * packet, uint8_t ** sign_buf)
+int
+hicn_packet_get_signature (hicn_format_t format, hicn_header_t *packet,
+ uint8_t **sign_buf)
{
hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_signature (type,
- &packet->protocol, sign_buf);
+ return hicn_ops_vft[type.l1]->get_signature (type, &packet->protocol,
+ sign_buf);
}
/*
diff --git a/lib/src/name.c b/lib/src/name.c
index 9388c35..54b2a76 100644
--- a/lib/src/name.c
+++ b/lib/src/name.c
@@ -242,7 +242,7 @@ hicn_name_hash (const hicn_name_t * name, u32 * hash, bool consider_suffix)
int
hicn_name_empty (hicn_name_t * name)
{
- return name->type == HNT_UNSPEC ? HICN_LIB_ERROR_NONE : 1;
+ return name->type == HNT_UNSPEC ? 1 : 0;
}
int
diff --git a/lib/src/protocol/ah.c b/lib/src/protocol/ah.c
index da08d1e..03f3af0 100644
--- a/lib/src/protocol/ah.c
+++ b/lib/src/protocol/ah.c
@@ -113,7 +113,7 @@ ah_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
int
ah_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
const ip46_address_t * addr_new, ip46_address_t * addr_old,
- const hicn_faceid_t face_id)
+ const hicn_faceid_t face_id, u8 reset_pl)
{
/* Nothing to do on signature */
return HICN_LIB_ERROR_NONE;
diff --git a/lib/src/protocol/icmp.c b/lib/src/protocol/icmp.c
index b24c0f1..a163534 100644
--- a/lib/src/protocol/icmp.c
+++ b/lib/src/protocol/icmp.c
@@ -118,7 +118,7 @@ icmp_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
int
icmp_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
const ip46_address_t * addr_new, ip46_address_t * addr_old,
- const hicn_faceid_t face_id)
+ const hicn_faceid_t face_id, u8 reset_pl)
{
return HICN_LIB_ERROR_NOT_IMPLEMENTED;
// u16 *icmp_checksum = &(h->icmp.csum);
diff --git a/lib/src/protocol/ipv4.c b/lib/src/protocol/ipv4.c
index 7819072..73ce12e 100644
--- a/lib/src/protocol/ipv4.c
+++ b/lib/src/protocol/ipv4.c
@@ -324,7 +324,7 @@ ipv4_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
int
ipv4_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
const ip46_address_t * addr_new, ip46_address_t * addr_old,
- const hicn_faceid_t face_id)
+ const hicn_faceid_t face_id, u8 reset_pl)
{
// ASSERT(addr_old == NULL);
addr_old->ip4 = h->ipv4.daddr;
@@ -336,7 +336,7 @@ ipv4_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
h->ipv4.csum = 0;
h->ipv4.csum = csum (&h->ipv4, IPV4_HDRLEN, 0);
- return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id);
+ return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id, reset_pl);
}
int
diff --git a/lib/src/protocol/ipv6.c b/lib/src/protocol/ipv6.c
index f23b01c..bf81234 100644
--- a/lib/src/protocol/ipv6.c
+++ b/lib/src/protocol/ipv6.c
@@ -220,19 +220,13 @@ ipv6_update_checksums (hicn_type_t type, hicn_protocol_t * h,
u16 partial_csum, size_t payload_length)
{
/* Retrieve payload length if not specified */
- if (payload_length == 0)
+ if (payload_length == ~0)
{
int rc = ipv6_get_payload_length (type, h, &payload_length);
if (rc < 0)
return rc;
}
- /* Ignore the payload if payload_length = ~0 */
- if (payload_length == ~0)
- {
- payload_length = 0;
- }
-
/* Build pseudo-header */
ipv6_pseudo_header_t psh;
psh.ip_src = h->ipv6.saddr;
@@ -258,7 +252,7 @@ ipv6_verify_checksums (hicn_type_t type, hicn_protocol_t * h,
u16 partial_csum, size_t payload_length)
{
/* Retrieve payload length if not specified */
- if (payload_length == 0)
+ if (payload_length == ~0)
{
int rc = ipv6_get_payload_length (type, h, &payload_length);
if (rc < 0)
@@ -276,7 +270,11 @@ ipv6_verify_checksums (hicn_type_t type, hicn_protocol_t * h,
pseudo.protocol = h->ipv6.nxt;
/* Compute partial checksum based on pseudo-header */
- partial_csum = csum (&pseudo, IPV6_PSHDRLEN, 0);
+ if (partial_csum != 0)
+ {
+ partial_csum = ~partial_csum;
+ }
+ partial_csum = csum (&pseudo, IPV6_PSHDRLEN, partial_csum);
return CHILD_OPS (verify_checksums, type, h, partial_csum, payload_length);
}
@@ -296,13 +294,13 @@ ipv6_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
int
ipv6_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
const ip46_address_t * addr_new, ip46_address_t * addr_old,
- const hicn_faceid_t face_id)
+ const hicn_faceid_t face_id, u8 reset_pl)
{
// ASSERT(addr_old == NULL);
addr_old->ip6 = h->ipv6.daddr;
h->ipv6.daddr = addr_new->ip6;
- return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id);
+ return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id, reset_pl);
}
int
diff --git a/lib/src/protocol/tcp.c b/lib/src/protocol/tcp.c
index c6099bf..95f93c6 100644
--- a/lib/src/protocol/tcp.c
+++ b/lib/src/protocol/tcp.c
@@ -170,12 +170,12 @@ tcp_update_data_pathlabel (hicn_type_t type, hicn_protocol_t * h,
const hicn_faceid_t face_id)
{
hicn_pathlabel_t pl =
- (hicn_pathlabel_t) ((h->tcp.pathlabel & HICN_PATH_LABEL_MASK) >> (32 -
- HICN_PATH_LABEL_SIZE));
+ (hicn_pathlabel_t) (h->tcp.seq_ack >> (32 - HICN_PATH_LABEL_SIZE));
+
hicn_pathlabel_t new_pl;
update_pathlabel (pl, face_id, &new_pl);
- h->tcp.pathlabel = new_pl;
+ h->tcp.seq_ack = (new_pl << (32 - HICN_PATH_LABEL_SIZE));
return HICN_LIB_ERROR_NONE;
}
@@ -249,7 +249,12 @@ int
tcp_verify_checksums (hicn_type_t type, hicn_protocol_t * h, u16 partial_csum,
size_t payload_length)
{
- if (csum (h, TCP_HDRLEN + payload_length, ~partial_csum) != 0)
+ if (PREDICT_TRUE (partial_csum != 0))
+ {
+ partial_csum = ~partial_csum;
+ }
+
+ if (csum (h, TCP_HDRLEN + payload_length, partial_csum) != 0)
return HICN_LIB_ERROR_CORRUPTED_PACKET;
return CHILD_OPS (verify_checksums, type, h, 0, payload_length);
}
@@ -307,11 +312,19 @@ tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
int
tcp_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
const ip46_address_t * addr_new, ip46_address_t * addr_old,
- const hicn_faceid_t face_id)
+ const hicn_faceid_t face_id, u8 reset_pl)
{
+
u16 *tcp_checksum = &(h->tcp.csum);
int ret = check_tcp_checksum(*tcp_checksum);
+ /*
+ * update path label
+ */
+ u16 old_pl = h->tcp.seq_ack;
+ if(reset_pl) h->tcp.seq_ack = 0;
+ tcp_update_data_pathlabel (type, h, face_id);
+
if (ret)
{
return ret;
@@ -330,9 +343,8 @@ tcp_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
csum = ip_csum_add_even (csum, (ip_csum_t) (addr_new->ip6.as_u64[0]));
csum = ip_csum_add_even (csum, (ip_csum_t) (addr_new->ip6.as_u64[1]));
- csum = ip_csum_sub_even (csum, h->tcp.pathlabel);
- tcp_update_data_pathlabel (type, h, face_id);
- csum = ip_csum_add_even (csum, h->tcp.pathlabel);
+ csum = ip_csum_sub_even (csum, old_pl);
+ csum = ip_csum_add_even (csum, h->tcp.seq_ack);
*tcp_checksum = ip_csum_fold (csum);
diff --git a/libtransport/CMakeLists.txt b/libtransport/CMakeLists.txt
index e86fa5d..3f828c4 100644
--- a/libtransport/CMakeLists.txt
+++ b/libtransport/CMakeLists.txt
@@ -44,23 +44,9 @@ set(TRANSPORT_LOG_LEVEL "INFO" CACHE STRING "Set log level")
set(TRANSPORT_ROOT_PATH "src")
-set(TRANSPORT_CORE ${TRANSPORT_ROOT_PATH}/core)
-set(TRANSPORT_TRANSPORT ${TRANSPORT_ROOT_PATH}/transport)
-set(TRANSPORT_ERRORS ${TRANSPORT_ROOT_PATH}/errors)
-set(TRANSPORT_UTILS ${TRANSPORT_ROOT_PATH}/utils)
-set(TRANSPORT_HTTP ${TRANSPORT_ROOT_PATH}/http)
-set(TRANSPORT_PORTABILITY ${TRANSPORT_ROOT_PATH}/portability)
-set(TRANSPORT_INTERFACES ${TRANSPORT_ROOT_PATH}/interfaces)
-
set(LIBTRANSPORT hicntransport)
if ((BUILD_HICNPLUGIN OR BUILD_MEMIF_CONNECTOR) AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(__vpp__ 1)
- set(LIBTRANSPORT ${LIBTRANSPORT}-memif)
- find_package(Vpp REQUIRED)
-
- list(APPEND LIBTRANSPORT_INTERNAL_INCLUDE_DIRS
- ${VPP_INCLUDE_DIRS}
- )
endif ()
set(LIBTRANSPORT ${LIBTRANSPORT} CACHE INTERNAL "" FORCE)
@@ -70,29 +56,15 @@ set(LIBTRANSPORT_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src CACHE INTERNAL ""
include(WindowsMacros)
include(IosMacros)
+
find_package_wrapper(Libparc REQUIRED)
find_package_wrapper(Asio REQUIRED)
find_package(OpenSSL REQUIRED)
-
-if (${OPENSSL_VERSION} VERSION_EQUAL "1.1.1a" OR ${OPENSSL_VERSION} VERSION_GREATER "1.1.1a")
- set(SECURE_HICNTRANSPORT 1)
-endif()
-
-if (__vpp__)
- find_package(Libmemif REQUIRED)
-endif()
+find_package(Threads REQUIRED)
+find_package(OpenSSL REQUIRED)
+find_package(Libconfig++ REQUIRED)
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
- if (__vpp__)
- find_package(HicnPlugin REQUIRED)
- find_package(SafeVapi REQUIRED)
-
- list(APPEND LIBRARIES
- ${LIBMEMIF_LIBRARIES}
- ${SAFE_VAPI_LIBRARIES}
- )
- endif()
-
find_package_wrapper(Libhicn REQUIRED)
else()
if (DISABLE_SHARED_LIBRARIES)
@@ -109,33 +81,11 @@ else()
list(APPEND DEPENDENCIES
${LIBHICN_SHARED}
)
-
- if (__vpp__)
- list(APPEND DEPENDENCIES
- ${SAFE_VAPI_SHARED}
- )
-
- list(APPEND LIBRARIES
- ${LIBMEMIF_LIBRARIES}
- ${SAFE_VAPI_LIBRARIES}
- )
- endif()
endif()
endif()
-list(APPEND LIBTRANSPORT_INTERNAL_INCLUDE_DIRS
- ${LIBMEMIF_INCLUDE_DIRS}
- ${SAFE_VAPI_INCLUDE_DIRS}
-)
-
include(Packaging)
-find_package(Threads REQUIRED)
-
-if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
- find_package(OpenSSL REQUIRED)
-endif ()
-
list(APPEND LIBRARIES
${HICN_LIBRARIES}
${LIBPARC_LIBRARIES}
@@ -144,6 +94,7 @@ list(APPEND LIBRARIES
${ANDROID_LIBRARIES}
${OPENSSL_LIBRARIES}
${WINDOWS_LIBRARIES}
+ ${LIBCONFIG_CPP_LIBRARIES}
)
# Include dirs -- Order does matter!
@@ -155,6 +106,7 @@ list(APPEND LIBTRANSPORT_INTERNAL_INCLUDE_DIRS
${ASIO_INCLUDE_DIRS}
${WINDOWS_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
+ ${CONFIG_INCLUDE_DIRS}
)
add_subdirectory(includes/hicn/transport)
diff --git a/libtransport/includes/hicn/transport/CMakeLists.txt b/libtransport/includes/hicn/transport/CMakeLists.txt
index 1099e70..ca53bdf 100644
--- a/libtransport/includes/hicn/transport/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/CMakeLists.txt
@@ -22,7 +22,7 @@ add_subdirectory(errors)
add_subdirectory(http)
add_subdirectory(interfaces)
add_subdirectory(portability)
-add_subdirectory(security)
+add_subdirectory(auth)
add_subdirectory(utils)
set(LIBTRANSPORT_INCLUDE_DIRS
@@ -35,4 +35,4 @@ set(LIBHICNTRANSPORT_TO_INSTALL_HEADER_FILES
${HEADER_FILES} ""
CACHE INTERNAL
"" FORCE
-) \ No newline at end of file
+)
diff --git a/libtransport/includes/hicn/transport/auth/CMakeLists.txt b/libtransport/includes/hicn/transport/auth/CMakeLists.txt
new file mode 100644
index 0000000..d855125
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright (c) 2017-2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/common.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hash.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hash_type.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hasher.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_suite.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/identity.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/key_id.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/policies.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/signer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/verifier.h
+)
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE)
diff --git a/libtransport/includes/hicn/transport/auth/common.h b/libtransport/includes/hicn/transport/auth/common.h
new file mode 100644
index 0000000..911bcbc
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/common.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/packet.h>
+
+namespace transport {
+namespace auth {
+
+using Hash = std::vector<uint8_t>;
+using HashEntry = std::pair<CryptoHashType, Hash>;
+using PacketPtr = core::Packet *;
+using Suffix = uint32_t;
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/crypto_hash.h b/libtransport/includes/hicn/transport/auth/crypto_hash.h
new file mode 100644
index 0000000..26c251b
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/crypto_hash.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/errors/runtime_exception.h>
+#include <hicn/transport/portability/portability.h>
+#include <hicn/transport/auth/crypto_hash_type.h>
+#include <hicn/transport/utils/array.h>
+
+extern "C" {
+#include <parc/security/parc_CryptoHash.h>
+};
+
+#include <cstring>
+#include <unordered_map>
+
+namespace transport {
+namespace auth {
+
+class CryptoHasher;
+
+struct EnumClassHash {
+ template <typename T>
+ std::size_t operator()(T t) const {
+ return static_cast<std::size_t>(t);
+ }
+};
+
+static std::unordered_map<CryptoHashType, std::size_t, EnumClassHash>
+ hash_size_map = {{CryptoHashType::SHA_256, 32},
+ {CryptoHashType::CRC32C, 4},
+ {CryptoHashType::SHA_512, 64}};
+
+class Signer;
+class Verifier;
+
+class CryptoHash {
+ friend class CryptoHasher;
+ friend class Signer;
+ friend class Verifier;
+
+ public:
+ CryptoHash() : hash_(nullptr) {}
+
+ CryptoHash(const CryptoHash& other) {
+ if (other.hash_) {
+ hash_ = parcCryptoHash_Acquire(other.hash_);
+ }
+ }
+
+ CryptoHash(CryptoHash&& other) {
+ if (other.hash_) {
+ hash_ = parcCryptoHash_Acquire(other.hash_);
+ }
+ }
+
+ template <typename T>
+ CryptoHash(const T* buffer, std::size_t length, CryptoHashType hash_type) {
+ hash_ = parcCryptoHash_CreateFromArray(
+ static_cast<PARCCryptoHashType>(hash_type), buffer, length);
+ }
+
+ ~CryptoHash() {
+ if (hash_) {
+ parcCryptoHash_Release(&hash_);
+ }
+ }
+
+ CryptoHash& operator=(const CryptoHash& other) {
+ if (other.hash_) {
+ hash_ = parcCryptoHash_Acquire(other.hash_);
+ }
+
+ return *this;
+ }
+
+ template <typename T>
+ utils::Array<T> getDigest() const {
+ return utils::Array<T>(
+ static_cast<T*>(parcBuffer_Overlay(parcCryptoHash_GetDigest(hash_), 0)),
+ parcBuffer_Remaining(parcCryptoHash_GetDigest(hash_)));
+ }
+
+ CryptoHashType getType() {
+ return static_cast<CryptoHashType>(parcCryptoHash_GetDigestType(hash_));
+ }
+
+ template <typename T>
+ static bool compareBinaryDigest(const T* digest1, const T* digest2,
+ CryptoHashType hash_type) {
+ if (hash_size_map.find(hash_type) == hash_size_map.end()) {
+ return false;
+ }
+
+ return !static_cast<bool>(
+ std::memcmp(digest1, digest2, hash_size_map[hash_type]));
+ }
+
+ TRANSPORT_ALWAYS_INLINE void display() {
+ parcBuffer_Display(parcCryptoHash_GetDigest(hash_), 2);
+ }
+
+ private:
+ PARCCryptoHash* hash_;
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/crypto_hash_type.h b/libtransport/includes/hicn/transport/auth/crypto_hash_type.h
new file mode 100644
index 0000000..9d79262
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/crypto_hash_type.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+extern "C" {
+#include <parc/security/parc_CryptoHashType.h>
+};
+
+#include <cstdint>
+
+namespace transport {
+namespace auth {
+
+enum class CryptoHashType : uint8_t {
+ SHA_256 = PARCCryptoHashType_SHA256,
+ SHA_512 = PARCCryptoHashType_SHA512,
+ CRC32C = PARCCryptoHashType_CRC32C,
+ NULL_HASH = PARCCryptoHashType_NULL
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/crypto_hasher.h b/libtransport/includes/hicn/transport/auth/crypto_hasher.h
new file mode 100644
index 0000000..ada1a6e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/crypto_hasher.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/auth/crypto_hash.h>
+
+extern "C" {
+#include <parc/security/parc_CryptoHasher.h>
+};
+
+namespace transport {
+namespace auth {
+
+class CryptoHasher {
+ public:
+ CryptoHasher(CryptoHashType hash_type)
+ : hasher_(parcCryptoHasher_Create(
+ static_cast<PARCCryptoHashType>(hash_type))),
+ managed_(true) {}
+
+ CryptoHasher(PARCCryptoHasher* hasher) : hasher_(hasher), managed_(false) {}
+
+ ~CryptoHasher() {
+ if (managed_) {
+ parcCryptoHasher_Release(&hasher_);
+ }
+ }
+
+ CryptoHasher& init() {
+ if (parcCryptoHasher_Init(hasher_) == -1) {
+ throw errors::RuntimeException("Cryptohash init failed.");
+ }
+
+ return *this;
+ }
+
+ template <typename T>
+ CryptoHasher& updateBytes(const T* buffer, std::size_t length) {
+ if (parcCryptoHasher_UpdateBytes(hasher_, buffer, length) == -1) {
+ throw errors::RuntimeException("Cryptohash updateBytes failed.");
+ }
+ return *this;
+ }
+
+ CryptoHash finalize() {
+ CryptoHash hash;
+ hash.hash_ = parcCryptoHasher_Finalize(hasher_);
+ return hash;
+ }
+
+ private:
+ PARCCryptoHasher* hasher_;
+ bool managed_;
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/crypto_suite.h b/libtransport/includes/hicn/transport/auth/crypto_suite.h
new file mode 100644
index 0000000..11df6ac
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/crypto_suite.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+extern "C" {
+#include <parc/security/parc_CryptoSuite.h>
+};
+
+#include <cstdint>
+
+namespace transport {
+namespace auth {
+
+enum class CryptoSuite : uint8_t {
+ RSA_SHA256 = PARCCryptoSuite_RSA_SHA256,
+ DSA_SHA256 = PARCCryptoSuite_DSA_SHA256,
+ RSA_SHA512 = PARCCryptoSuite_RSA_SHA512,
+ HMAC_SHA256 = PARCCryptoSuite_HMAC_SHA256,
+ HMAC_SHA512 = PARCCryptoSuite_HMAC_SHA512,
+ NULL_CRC32C = PARCCryptoSuite_NULL_CRC32C,
+ ECDSA_256K1 = PARCCryptoSuite_ECDSA_SHA256,
+ UNKNOWN = PARCCryptoSuite_UNKNOWN
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/identity.h b/libtransport/includes/hicn/transport/auth/identity.h
new file mode 100644
index 0000000..1915795
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/identity.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017-2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/auth/signer.h>
+
+extern "C" {
+#include <parc/security/parc_Identity.h>
+#include <parc/security/parc_IdentityFile.h>
+#include <parc/security/parc_Pkcs12KeyStore.h>
+#include <parc/security/parc_Security.h>
+};
+
+namespace transport {
+namespace auth {
+
+class Identity {
+ // This class holds several information about a client, including its public
+ // key.
+ public:
+ // Generate a new identity from the given parameters. The identity will be
+ // saved in 'keystore_path' and encrypted using 'keystore_pwd'.
+ Identity(const std::string &keystore_path, const std::string &keystore_pwd,
+ CryptoSuite suite, unsigned int signature_len,
+ unsigned int validity_days, const std::string &subject_name);
+
+ // Create an identity from an already existing keystore path.
+ Identity(std::string &keystore_path, std::string &keystore_pwd,
+ CryptoHashType hash_type);
+
+ Identity(const Identity &other);
+ Identity(Identity &&other);
+ ~Identity();
+
+ // Return the asymmetric signer object created from the public key.
+ std::shared_ptr<AsymmetricSigner> getSigner() const;
+
+ // Return the key store filename.
+ std::string getFilename() const;
+
+ // Return the key store password.
+ std::string getPassword() const;
+
+ // Generate a new random identity.
+ static Identity generateIdentity(const std::string &subject_name = "");
+
+ private:
+ PARCIdentity *identity_;
+ std::shared_ptr<AsymmetricSigner> signer_;
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/key_id.h b/libtransport/includes/hicn/transport/auth/key_id.h
new file mode 100644
index 0000000..3aa0933
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/key_id.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <utility>
+
+namespace transport {
+namespace auth {
+
+using KeyId = std::pair<uint8_t *, uint8_t>;
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/policies.h b/libtransport/includes/hicn/transport/auth/policies.h
new file mode 100644
index 0000000..00464d5
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/policies.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace transport {
+namespace auth {
+
+/**
+ * These policies allows the verifier to tell the transport what action to
+ * perform after verification.
+ */
+enum class VerificationPolicy {
+ ABORT,
+ ACCEPT,
+ DROP,
+ UNKNOWN,
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/signer.h b/libtransport/includes/hicn/transport/auth/signer.h
new file mode 100644
index 0000000..fd5c4e6
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/signer.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017-2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/auth/common.h>
+#include <hicn/transport/errors/errors.h>
+
+extern "C" {
+#include <parc/security/parc_PublicKeySigner.h>
+#include <parc/security/parc_Security.h>
+#include <parc/security/parc_Signer.h>
+#include <parc/security/parc_SymmetricKeySigner.h>
+}
+
+namespace transport {
+namespace auth {
+
+class Signer {
+ // The base class from which all signer classes derive.
+ public:
+ Signer();
+
+ Signer(PARCSigner *signer);
+
+ virtual ~Signer();
+
+ // Sign a packet.
+ virtual void signPacket(PacketPtr packet);
+
+ // Set the signer object used to sign packets.
+ void setSigner(PARCSigner *signer);
+
+ // Return the signature size.
+ size_t getSignatureSize() const;
+
+ // Return the crypto suite associated to the signer.
+ CryptoSuite getCryptoSuite() const;
+
+ // Return the hash algorithm associated to the signer.
+ CryptoHashType getCryptoHashType() const;
+
+ // Return the PARC signer.
+ PARCSigner *getParcSigner() const;
+
+ // Return the PARC key store containing the signer key.
+ PARCKeyStore *getParcKeyStore() const;
+
+ protected:
+ PARCSigner *signer_;
+ PARCKeyId *key_id_;
+};
+
+class AsymmetricSigner : public Signer {
+ // This class uses asymmetric verification to sign packets. The public key
+ // must be given from a PARCKeyStore.
+ public:
+ AsymmetricSigner() = default;
+ AsymmetricSigner(PARCSigner *signer) : Signer(signer){};
+
+ // Construct an AsymmetricSigner from a key store and a given crypto suite.
+ AsymmetricSigner(CryptoSuite suite, PARCKeyStore *key_store);
+};
+
+class SymmetricSigner : public Signer {
+ // This class uses symmetric verification to sign packets. The symmetric
+ // key is derived from a passphrase.
+ public:
+ SymmetricSigner() = default;
+ SymmetricSigner(PARCSigner *signer) : Signer(signer){};
+
+ // Construct an SymmetricSigner from a key store and a given crypto suite.
+ SymmetricSigner(CryptoSuite suite, PARCKeyStore *key_store);
+
+ // Construct an AsymmetricSigner from a passphrase and a given crypto suite.
+ SymmetricSigner(CryptoSuite suite, const std::string &passphrase);
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/verifier.h b/libtransport/includes/hicn/transport/auth/verifier.h
new file mode 100644
index 0000000..e6e5619
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/verifier.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2017-2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/auth/common.h>
+#include <hicn/transport/auth/policies.h>
+#include <hicn/transport/core/content_object.h>
+#include <hicn/transport/errors/errors.h>
+#include <hicn/transport/interfaces/callbacks.h>
+
+#include <algorithm>
+
+extern "C" {
+#include <parc/security/parc_CertificateFactory.h>
+#include <parc/security/parc_InMemoryVerifier.h>
+#include <parc/security/parc_Security.h>
+#include <parc/security/parc_SymmetricKeySigner.h>
+#include <parc/security/parc_Verifier.h>
+}
+
+namespace transport {
+namespace auth {
+
+class Verifier {
+ // The base class from which all verifier classes derive.
+ public:
+ // The VerificationFailedCallback will be called by the transport if a data
+ // packet (either a manifest or a content object) cannot be verified. The
+ // application decides what to do then by returning a VerificationPolicy
+ // object.
+ using VerificationFailedCallback = std::function<auth::VerificationPolicy(
+ const core::ContentObject &content_object, std::error_code ec)>;
+
+ // The list of VerificationPolicy that will trigger the
+ // VerificationFailedCallback.
+ static const std::vector<VerificationPolicy> DEFAULT_FAILED_POLICIES;
+
+ Verifier();
+
+ virtual ~Verifier();
+
+ // Verify a single packet and return whether or not the packet signature is
+ // valid.
+ virtual bool verifyPacket(PacketPtr packet);
+
+ // Verify a batch of packets. Return a vector with the same size as the packet
+ // list, element i of that vector will contain the VerificationPolicy for
+ // packet i.
+ virtual std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets);
+ VerificationPolicy verifyPackets(PacketPtr packet) {
+ return verifyPackets(std::vector<PacketPtr>{packet}).front();
+ }
+
+ // Verify that a batch of packets are valid using a map from packet suffixes
+ // to hashes. A packet is considered valid if its hash correspond to the hash
+ // present in the map. Return a vector with the same size as the packet list,
+ // element i of that vector will contain the VerificationPolicy for packet i.
+ virtual std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets,
+ const std::unordered_map<Suffix, HashEntry> &suffix_map);
+ VerificationPolicy verifyPackets(
+ PacketPtr packet,
+ const std::unordered_map<Suffix, HashEntry> &suffix_map) {
+ return verifyPackets(std::vector<PacketPtr>{packet}, suffix_map).front();
+ }
+
+ // Add a general PARC key which can be used to verify packet signatures.
+ void addKey(PARCKey *key);
+
+ // Set the hasher object used to compute packet hashes.
+ void setHasher(PARCCryptoHasher *hasher);
+
+ // Set the callback for the case packet verification fails.
+ void setVerificationFailedCallback(
+ VerificationFailedCallback verification_failed_cb,
+ const std::vector<VerificationPolicy> &failed_policies =
+ DEFAULT_FAILED_POLICIES);
+
+ // Retrieve the VerificationFailedCallback function.
+ void getVerificationFailedCallback(
+ VerificationFailedCallback **verification_failed_cb);
+
+ static size_t getSignatureSize(const PacketPtr);
+
+ protected:
+ PARCCryptoHasher *hasher_;
+ PARCVerifier *verifier_;
+ VerificationFailedCallback verification_failed_cb_;
+ std::vector<VerificationPolicy> failed_policies_;
+
+ // Internally compute a packet hash using the hasher object.
+ virtual CryptoHash computeHash(PacketPtr packet);
+
+ // Call VerificationFailedCallback if it is set and update the packet policy.
+ void callVerificationFailedCallback(PacketPtr packet,
+ VerificationPolicy &policy);
+};
+
+class VoidVerifier : public Verifier {
+ // This class is the default socket verifier. It ignores completely the packet
+ // signature and always returns true.
+ public:
+ bool verifyPacket(PacketPtr packet) override;
+
+ std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets) override;
+
+ std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets,
+ const std::unordered_map<Suffix, HashEntry> &suffix_map) override;
+};
+
+class AsymmetricVerifier : public Verifier {
+ // This class uses asymmetric verification to validate packets. The public key
+ // can be set directly or extracted from a certificate.
+ public:
+ AsymmetricVerifier() = default;
+
+ // Add a public key to the verifier.
+ AsymmetricVerifier(PARCKey *pub_key);
+
+ // Construct an AsymmetricVerifier from a certificate file.
+ AsymmetricVerifier(const std::string &cert_path);
+
+ // Extract the public key of a certificate file.
+ void setCertificate(const std::string &cert_path);
+};
+
+class SymmetricVerifier : public Verifier {
+ // This class uses symmetric verification to validate packets. The symmetric
+ // key is derived from a passphrase.
+ public:
+ SymmetricVerifier() = default;
+
+ // Construct a SymmetricVerifier from a passphrase.
+ SymmetricVerifier(const std::string &passphrase);
+
+ ~SymmetricVerifier();
+
+ // Create and set a symmetric key from a passphrase.
+ void setPassphrase(const std::string &passphrase);
+
+ // Construct a signer object. Passphrase must be set beforehand.
+ void setSigner(const PARCCryptoSuite &suite);
+
+ virtual std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets) override;
+
+ protected:
+ PARCBuffer *passphrase_;
+ PARCSigner *signer_;
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/core/CMakeLists.txt b/libtransport/includes/hicn/transport/core/CMakeLists.txt
index cb10745..2553b7d 100644
--- a/libtransport/includes/hicn/transport/core/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/core/CMakeLists.txt
@@ -20,6 +20,10 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/packet.h
${CMAKE_CURRENT_SOURCE_DIR}/payload_type.h
${CMAKE_CURRENT_SOURCE_DIR}/prefix.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/io_module.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/connector.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/endpoint.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/global_object_pool.h
)
set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/core/connector.h b/libtransport/includes/hicn/transport/core/connector.h
new file mode 100644
index 0000000..dcf38cd
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/connector.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/connector_stats.h>
+#include <hicn/transport/core/content_object.h>
+#include <hicn/transport/core/endpoint.h>
+#include <hicn/transport/core/global_object_pool.h>
+#include <hicn/transport/core/interest.h>
+#include <hicn/transport/core/packet.h>
+#include <hicn/transport/portability/platform.h>
+#include <hicn/transport/utils/membuf.h>
+#include <hicn/transport/utils/object_pool.h>
+#include <hicn/transport/utils/ring_buffer.h>
+#include <hicn/transport/utils/shared_ptr_utils.h>
+
+#include <deque>
+#include <functional>
+
+namespace transport {
+
+namespace core {
+
+class Connector : public std::enable_shared_from_this<Connector> {
+ public:
+ enum class Type : uint8_t {
+ SOCKET_CONNECTOR,
+ MEMIF_CONNECTOR,
+ LOOPBACK_CONNECTOR,
+ };
+
+ enum class State : std::uint8_t {
+ CLOSED,
+ CONNECTING,
+ CONNECTED,
+ };
+
+ enum class Role : std::uint8_t { CONSUMER, PRODUCER };
+
+ public:
+ static constexpr std::size_t queue_size = 4096;
+ static constexpr std::uint32_t invalid_connector = ~0;
+
+#ifdef LINUX
+ static constexpr std::uint16_t max_burst = 256;
+#endif
+
+ using Ptr = std::shared_ptr<Connector>;
+ using PacketQueue = std::deque<Packet::Ptr>;
+ using PacketReceivedCallback = std::function<void(
+ Connector *, utils::MemBuf &, const std::error_code &)>;
+ using PacketSentCallback =
+ std::function<void(Connector *, const std::error_code &)>;
+ using OnCloseCallback = std::function<void(Connector *)>;
+ using OnReconnectCallback = std::function<void(Connector *)>;
+ using Id = std::uint64_t;
+
+ template <typename ReceiveCallback, typename SentCallback, typename OnClose,
+ typename OnReconnect>
+ Connector(ReceiveCallback &&receive_callback, SentCallback &&packet_sent,
+ OnClose &&close_callback, OnReconnect &&on_reconnect)
+ : receive_callback_(std::forward<ReceiveCallback &&>(receive_callback)),
+ sent_callback_(std::forward<SentCallback &&>(packet_sent)),
+ on_close_callback_(std::forward<OnClose &&>(close_callback)),
+ on_reconnect_callback_(std::forward<OnReconnect &&>(on_reconnect)),
+ state_(State::CLOSED),
+ connector_id_(invalid_connector) {}
+
+ virtual ~Connector(){};
+
+ template <typename ReceiveCallback>
+ void setReceiveCallback(ReceiveCallback &&callback) {
+ receive_callback_ = std::forward<ReceiveCallback &&>(callback);
+ }
+
+ template <typename SentCallback>
+ void setSentCallback(SentCallback &&callback) {
+ sent_callback_ = std::forward<SentCallback &&>(callback);
+ }
+
+ template <typename OnClose>
+ void setOnCloseCallback(OnClose &&callback) {
+ on_close_callback_ = std::forward<OnClose &&>(callback);
+ }
+
+ template <typename OnReconnect>
+ void setReconnectCallback(const OnReconnect &&callback) {
+ on_reconnect_callback_ = std::forward<OnReconnect>(callback);
+ }
+
+ const PacketReceivedCallback &getReceiveCallback() const {
+ return receive_callback_;
+ }
+
+ const PacketSentCallback &getSentCallback() { return sent_callback_; }
+
+ const OnCloseCallback &getOnCloseCallback() { return on_close_callback_; }
+
+ const OnReconnectCallback &getOnReconnectCallback() {
+ return on_reconnect_callback_;
+ }
+
+ virtual void send(Packet &packet) = 0;
+
+ virtual void send(const uint8_t *packet, std::size_t len) = 0;
+
+ virtual void close() = 0;
+
+ virtual State state() { return state_; };
+
+ virtual bool isConnected() { return state_ == State::CONNECTED; }
+
+ void setConnectorId(Id connector_id) { connector_id_ = connector_id; }
+
+ Id getConnectorId() { return connector_id_; }
+
+ void setConnectorName(std::string connector_name) {
+ connector_name_ = connector_name;
+ }
+
+ std::string getConnectorName() { return connector_name_; }
+
+ Endpoint getLocalEndpoint() { return local_endpoint_; }
+
+ Endpoint getRemoteEndpoint() { return remote_endpoint_; }
+
+ void setRole(Role r) { role_ = r; }
+
+ Role getRole() { return role_; }
+
+ static utils::MemBuf::Ptr getPacketFromBuffer(uint8_t *buffer,
+ std::size_t size) {
+ utils::MemBuf::Ptr ret;
+
+ auto format = Packet::getFormatFromBuffer(buffer, size);
+
+ if (TRANSPORT_EXPECT_TRUE(format != HF_UNSPEC && !_is_icmp(format))) {
+ if (Packet::isInterest(buffer)) {
+ ret = core::PacketManager<>::getInstance()
+ .getPacketFromExistingBuffer<Interest>(buffer, size);
+ } else {
+ ret = core::PacketManager<>::getInstance()
+ .getPacketFromExistingBuffer<ContentObject>(buffer, size);
+ }
+ } else {
+ ret = core::PacketManager<>::getInstance().getMemBuf(buffer, size);
+ }
+
+ return ret;
+ }
+
+ static std::pair<uint8_t *, std::size_t> getRawBuffer() {
+ return core::PacketManager<>::getInstance().getRawBuffer();
+ }
+
+ protected:
+ inline void sendSuccess(const utils::MemBuf &packet) {
+ stats_.tx_packets_.fetch_add(1, std::memory_order_relaxed);
+ stats_.tx_bytes_.fetch_add(packet.length(), std::memory_order_relaxed);
+ }
+
+ inline void receiveSuccess(const utils::MemBuf &packet) {
+ stats_.rx_packets_.fetch_add(1, std::memory_order_relaxed);
+ stats_.rx_bytes_.fetch_add(packet.length(), std::memory_order_relaxed);
+ }
+
+ inline void sendFailed() {
+ stats_.drops_.fetch_add(1, std::memory_order_relaxed);
+ }
+
+ protected:
+ PacketQueue output_buffer_;
+
+ // Connector events
+ PacketReceivedCallback receive_callback_;
+ PacketSentCallback sent_callback_;
+ OnCloseCallback on_close_callback_;
+ OnReconnectCallback on_reconnect_callback_;
+
+ // Connector state
+ std::atomic<State> state_;
+ Id connector_id_;
+
+ // Endpoints
+ Endpoint local_endpoint_;
+ Endpoint remote_endpoint_;
+
+ // Connector name
+ std::string connector_name_;
+
+ // Connector role
+ Role role_;
+
+ // Stats
+ AtomicConnectorStats stats_;
+};
+
+} // namespace core
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/core/connector_stats.h b/libtransport/includes/hicn/transport/core/connector_stats.h
new file mode 100644
index 0000000..1985331
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/connector_stats.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace transport {
+namespace core {
+
+struct AtomicConnectorStats {
+ AtomicConnectorStats()
+ : tx_packets_(0), tx_bytes_(0), rx_packets_(0), rx_bytes_(0), drops_(0) {}
+ std::atomic<uint64_t> tx_packets_;
+ std::atomic<uint64_t> tx_bytes_;
+ std::atomic<uint64_t> rx_packets_;
+ std::atomic<uint64_t> rx_bytes_;
+ std::atomic<uint64_t> drops_;
+};
+
+struct ConnectorStats {
+ ConnectorStats()
+ : tx_packets_(0), tx_bytes_(0), rx_packets_(0), rx_bytes_(0), drops_(0) {}
+ std::uint64_t tx_packets_;
+ std::uint64_t tx_bytes_;
+ std::uint64_t rx_packets_;
+ std::uint64_t rx_bytes_;
+ std::uint64_t drops_;
+};
+
+using TableEntry = std::tuple<std::string, std::uint64_t, std::uint64_t,
+ std::uint64_t, std::uint64_t, std::uint64_t>;
+using StatisticTable = std::vector<TableEntry>;
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/core/content_object.h b/libtransport/includes/hicn/transport/core/content_object.h
index 822790e..805bc81 100644
--- a/libtransport/includes/hicn/transport/core/content_object.h
+++ b/libtransport/includes/hicn/transport/core/content_object.h
@@ -17,6 +17,7 @@
#include <hicn/transport/core/name.h>
#include <hicn/transport/core/packet.h>
+#include <hicn/transport/utils/shared_ptr_utils.h>
namespace transport {
@@ -27,24 +28,53 @@ namespace core {
class ContentObject : public Packet {
public:
- using Ptr = utils::ObjectPool<ContentObject>::Ptr;
+ using Ptr = std::shared_ptr<ContentObject>;
using HICNContentObject = hicn_header_t;
- ContentObject(Packet::Format format = HF_INET6_TCP);
+ ContentObject(Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
- ContentObject(const Name &name, Packet::Format format = HF_INET6_TCP);
+ ContentObject(const Name &name, Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
- ContentObject(const Name &name, hicn_format_t format, const uint8_t *payload,
+ ContentObject(const Name &name, hicn_format_t format,
+ std::size_t additional_header_size, const uint8_t *payload,
std::size_t payload_size);
- ContentObject(const uint8_t *buffer, std::size_t size);
- ContentObject(MemBufPtr &&buffer);
-
- ContentObject(const ContentObject &content_object) = delete;
+ template <typename... Args>
+ ContentObject(CopyBufferOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
+ 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ template <typename... Args>
+ ContentObject(WrapBufferOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
+ 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ template <typename... Args>
+ ContentObject(CreateOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
+ 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ ContentObject(const ContentObject &content_object);
+
+ ContentObject &operator=(const ContentObject &other);
ContentObject(ContentObject &&content_object);
- ~ContentObject() override;
+ ~ContentObject();
const Name &getName() const override;
@@ -66,6 +96,8 @@ class ContentObject : public Packet {
uint32_t getLifetime() const override;
+ auto shared_from_this() { return utils::shared_from(this); }
+
private:
void resetForHash() override;
};
diff --git a/libtransport/includes/hicn/transport/core/endpoint.h b/libtransport/includes/hicn/transport/core/endpoint.h
new file mode 100644
index 0000000..4a19744
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/endpoint.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifndef ASIO_STANDALONE
+#define ASIO_STANDALONE
+#endif
+#include <asio.hpp>
+
+namespace transport {
+
+namespace core {
+
+const uint16_t INVALID_PORT = 0xffff;
+
+class Endpoint {
+ public:
+ Endpoint() : address_(), port_(INVALID_PORT) {}
+
+ Endpoint(const Endpoint &other)
+ : address_(other.address_), port_(other.port_) {}
+
+ Endpoint(Endpoint &&other)
+ : address_(std::move(other.address_)), port_(other.port_) {}
+
+ Endpoint(std::string ip_address, uint32_t port)
+ : address_(asio::ip::address::from_string(ip_address)), port_(port) {}
+
+ Endpoint(asio::ip::udp::endpoint endpoint)
+ : address_(endpoint.address()), port_(endpoint.port()) {}
+
+ ~Endpoint() = default;
+
+ Endpoint &operator=(const Endpoint &other) {
+ address_ = other.address_;
+ port_ = other.port_;
+ return *this;
+ }
+
+ Endpoint &operator=(Endpoint &&other) {
+ address_ = std::move(other.address_);
+ port_ = std::move(other.port_);
+ return *this;
+ }
+
+#if 0
+ template <typename Ip, typename Port>
+ Endpoint(Ip &&ip_address, Port &&port)
+ : address_(std::forward<Ip &&>(ip_address)),
+ port_(std::forward<Port &&>(port)) {}
+#endif
+
+ asio::ip::address getAddress() { return address_; }
+ uint16_t getPort() { return port_; }
+
+ void setAddress(uint32_t address) {
+ address_ = asio::ip::address(asio::ip::address_v4(address));
+ }
+
+ void setPort(uint16_t port) { port_ = port; }
+
+ private:
+ asio::ip::address address_;
+ uint16_t port_;
+};
+} // namespace core
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/core/global_object_pool.h b/libtransport/includes/hicn/transport/core/global_object_pool.h
new file mode 100644
index 0000000..e0b6e37
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/global_object_pool.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/packet.h>
+#include <hicn/transport/utils/fixed_block_allocator.h>
+#include <hicn/transport/utils/singleton.h>
+
+#include <array>
+#include <mutex>
+
+namespace transport {
+
+namespace core {
+
+template <std::size_t packet_pool_size = 1024, std::size_t chunk_size = 2048>
+class PacketManager
+ : public utils::Singleton<PacketManager<packet_pool_size, chunk_size>> {
+ friend class utils::Singleton<PacketManager<packet_pool_size, chunk_size>>;
+
+ public:
+ using MemoryPool = utils::FixedBlockAllocator<chunk_size, packet_pool_size>;
+ using RawBuffer = std::pair<uint8_t *, std::size_t>;
+
+ struct PacketStorage {
+ std::array<uint8_t, 256> packet_and_shared_ptr;
+ std::max_align_t align;
+ };
+
+ utils::MemBuf::Ptr getMemBuf() {
+ utils::MemBuf *memory = nullptr;
+
+ memory = reinterpret_cast<utils::MemBuf *>(memory_pool_.allocateBlock());
+
+ utils::STLAllocator<utils::MemBuf, MemoryPool> allocator(memory,
+ &memory_pool_);
+ auto offset = offsetof(PacketStorage, align);
+ auto ret = std::allocate_shared<utils::MemBuf>(
+ allocator, utils::MemBuf::WRAP_BUFFER, (uint8_t *)memory + offset, 0,
+ chunk_size - offset);
+ ret->clear();
+
+ return ret;
+ }
+
+ utils::MemBuf::Ptr getMemBuf(uint8_t *buffer, std::size_t length) {
+ auto offset = offsetof(PacketStorage, align);
+ auto memory = buffer - offset;
+ utils::STLAllocator<utils::MemBuf, MemoryPool> allocator(
+ (utils::MemBuf *)memory, &memory_pool_);
+ auto ret = std::allocate_shared<utils::MemBuf>(
+ allocator, utils::MemBuf::WRAP_BUFFER, (uint8_t *)buffer, length,
+ chunk_size - offset);
+
+ return ret;
+ }
+
+ template <
+ typename PacketType, typename... Args,
+ typename = std::enable_if_t<std::is_base_of<Packet, PacketType>::value>>
+ typename PacketType::Ptr getPacket(Args &&...args) {
+ PacketType *memory = nullptr;
+
+ memory = reinterpret_cast<PacketType *>(memory_pool_.allocateBlock());
+ utils::STLAllocator<PacketType, MemoryPool> allocator(memory,
+ &memory_pool_);
+ auto offset = offsetof(PacketStorage, align);
+ auto ret = std::allocate_shared<PacketType>(
+ allocator, PacketType::CREATE, (uint8_t *)memory + offset, 0,
+ chunk_size - offset, std::forward<Args>(args)...);
+
+ return ret;
+ }
+
+ std::pair<uint8_t *, std::size_t> getRawBuffer() {
+ uint8_t *memory = nullptr;
+ memory = reinterpret_cast<uint8_t *>(memory_pool_.allocateBlock());
+
+ auto offset = offsetof(PacketStorage, align);
+ memory += offset;
+
+ return std::make_pair(memory, chunk_size - offset);
+ }
+
+ template <typename PacketType, typename... Args>
+ typename PacketType::Ptr getPacketFromExistingBuffer(uint8_t *buffer,
+ std::size_t length,
+ Args &&...args) {
+ auto offset = offsetof(PacketStorage, align);
+ auto memory = reinterpret_cast<PacketType *>(buffer - offset);
+ utils::STLAllocator<PacketType, MemoryPool> allocator(memory,
+ &memory_pool_);
+ auto ret = std::allocate_shared<PacketType>(
+ allocator, PacketType::WRAP_BUFFER, (uint8_t *)buffer, length,
+ chunk_size - offset, std::forward<Args>(args)...);
+
+ return ret;
+ }
+
+ private:
+ PacketManager(std::size_t size = packet_pool_size)
+ : memory_pool_(MemoryPool::getInstance()), size_(0) {}
+ MemoryPool &memory_pool_;
+ std::atomic<size_t> size_;
+};
+
+} // end namespace core
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/core/interest.h b/libtransport/includes/hicn/transport/core/interest.h
index c572afb..b41b0c9 100644
--- a/libtransport/includes/hicn/transport/core/interest.h
+++ b/libtransport/includes/hicn/transport/core/interest.h
@@ -17,6 +17,9 @@
#include <hicn/transport/core/name.h>
#include <hicn/transport/core/packet.h>
+#include <hicn/transport/utils/shared_ptr_utils.h>
+
+#include <set>
namespace transport {
@@ -24,25 +27,57 @@ namespace core {
class Interest
: public Packet /*, public std::enable_shared_from_this<Interest>*/ {
- public:
- using Ptr = utils::ObjectPool<Interest>::Ptr;
-
- Interest(Packet::Format format = HF_INET6_TCP);
-
- Interest(const Name &interest_name, Packet::Format format = HF_INET6_TCP);
+ private:
+ struct InterestManifestHeader {
+ /* This can be 16 bits, but we use 32 bits for alignment */
+ uint32_t n_suffixes;
+ /* Followed by the list of prefixes to ask */
+ /* ... */
+ };
- Interest(const uint8_t *buffer, std::size_t size);
- Interest(MemBufPtr &&buffer);
+ public:
+ using Ptr = std::shared_ptr<Interest>;
+
+ Interest(Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
+
+ Interest(const Name &interest_name, Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
+
+ Interest(MemBuf &&buffer);
+
+ template <typename... Args>
+ Interest(CopyBufferOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_interest_get_name(format_, packet_start_,
+ name_.getStructReference()) < 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ template <typename... Args>
+ Interest(WrapBufferOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_interest_get_name(format_, packet_start_,
+ name_.getStructReference()) < 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ template <typename... Args>
+ Interest(CreateOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {}
+
+ /* Move constructor */
+ Interest(Interest &&other_interest);
- /*
- * Enforce zero-copy.
- */
- Interest(const Interest &other_interest) = delete;
- Interest &operator=(const Interest &other_interest) = delete;
+ /* Copy constructor */
+ Interest(const Interest &other_interest);
- Interest(Interest &&other_interest);
+ /* Assginemnt operator */
+ Interest &operator=(const Interest &other);
- ~Interest() override;
+ ~Interest();
const Name &getName() const override;
@@ -60,8 +95,21 @@ class Interest
uint32_t getLifetime() const override;
+ bool hasManifest();
+
+ void appendSuffix(std::uint32_t suffix);
+
+ void encodeSuffixes();
+
+ uint32_t *firstSuffix();
+
+ uint32_t numberOfSuffixes();
+
+ auto shared_from_this() { return utils::shared_from(this); }
+
private:
void resetForHash() override;
+ std::set<uint32_t> suffix_set_;
};
} // end namespace core
diff --git a/libtransport/includes/hicn/transport/core/io_module.h b/libtransport/includes/hicn/transport/core/io_module.h
new file mode 100644
index 0000000..d4c3bb0
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/io_module.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/connector.h>
+#include <hicn/transport/core/packet.h>
+#include <hicn/transport/core/prefix.h>
+#include <hicn/transport/portability/portability.h>
+#include <hicn/transport/utils/chrono_typedefs.h>
+#include <hicn/transport/utils/membuf.h>
+
+#include <deque>
+
+#ifndef ASIO_STANDALONE
+#define ASIO_STANDALONE
+#endif
+#include <asio/io_service.hpp>
+
+namespace transport {
+
+namespace core {
+
+typedef struct {
+ uint64_t rx_packets;
+ uint64_t tx_packets;
+ uint64_t rx_bytes;
+ uint64_t tx_bytes;
+ uint64_t rx_errors;
+ uint64_t tx_errors;
+} Counters;
+
+class Connector;
+
+class IoModule {
+ protected:
+ IoModule()
+ : inet_address_({}),
+ inet6_address_({}),
+ mtu_(1500),
+ output_interface_(""),
+ content_store_reserved_(5000) {
+ inet_address_.v4.as_u32 = htonl(0x7f00001);
+ inet6_address_.v6.as_u8[15] = 0x01;
+ }
+
+ public:
+ static IoModule *load(const char *);
+ static bool unload(IoModule *);
+
+ public:
+ virtual ~IoModule();
+
+ virtual void connect(bool is_consumer = true) = 0;
+
+ virtual bool isConnected() = 0;
+
+ virtual void init(Connector::PacketReceivedCallback &&receive_callback,
+ Connector::OnReconnectCallback &&reconnect_callback,
+ asio::io_service &io_service,
+ const std::string &app_name = "Libtransport") = 0;
+
+ virtual void registerRoute(const Prefix &prefix) = 0;
+
+ virtual std::uint32_t getMtu() = 0;
+
+ virtual bool isControlMessage(const uint8_t *message) = 0;
+
+ virtual void processControlMessageReply(utils::MemBuf &packet_buffer) = 0;
+
+ virtual void closeConnection() = 0;
+
+ virtual void send(Packet &packet) {
+ counters_.tx_packets++;
+ counters_.tx_bytes += packet.payloadSize() + packet.headerSize();
+
+ if (_is_ipv4(packet.getFormat())) {
+ packet.setLocator(inet_address_);
+ } else {
+ packet.setLocator(inet6_address_);
+ }
+ }
+
+ virtual void send(const uint8_t *packet, std::size_t len) = 0;
+
+ void setContentStoreSize(uint32_t cs_size) {
+ content_store_reserved_ = cs_size;
+ }
+
+ uint32_t getContentStoreSize() const { return content_store_reserved_; }
+
+ void setOutputInterface(const std::string &interface) {
+ output_interface_ = interface;
+ }
+
+ const std::string &getOutputInterface() { return output_interface_; }
+
+#ifndef ANDROID
+ private:
+ void *handle_;
+#endif
+
+ protected:
+ ip_address_t inet_address_;
+ ip_address_t inet6_address_;
+ uint16_t mtu_;
+ std::string output_interface_;
+ uint32_t content_store_reserved_;
+ Counters counters_;
+};
+
+extern "C" IoModule *createModule();
+
+} // namespace core
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/core/name.h b/libtransport/includes/hicn/transport/core/name.h
index ea72797..0335822 100644
--- a/libtransport/includes/hicn/transport/core/name.h
+++ b/libtransport/includes/hicn/transport/core/name.h
@@ -77,6 +77,8 @@ class Name {
operator bool() const;
+ bool isValid() const;
+
std::string toString() const;
bool equals(const Name &name, bool consider_segment = true) const;
@@ -125,14 +127,14 @@ struct compare2 {};
template <>
struct compare2<transport::core::Name> {
- size_t operator()(const transport::core::Name &name1, const transport::core::Name &name2) const;
+ size_t operator()(const transport::core::Name &name1,
+ const transport::core::Name &name2) const;
};
} // end namespace core
} // end namespace transport
-
namespace std {
template <>
struct hash<transport::core::Name> {
diff --git a/libtransport/includes/hicn/transport/core/packet.h b/libtransport/includes/hicn/transport/core/packet.h
index 91f9579..68daea8 100644
--- a/libtransport/includes/hicn/transport/core/packet.h
+++ b/libtransport/includes/hicn/transport/core/packet.h
@@ -19,21 +19,15 @@
#include <hicn/transport/core/payload_type.h>
#include <hicn/transport/errors/malformed_packet_exception.h>
#include <hicn/transport/portability/portability.h>
-#include <hicn/transport/security/crypto_hasher.h>
-#include <hicn/transport/security/crypto_suite.h>
-#include <hicn/transport/security/key_id.h>
+#include <hicn/transport/auth/crypto_hasher.h>
+#include <hicn/transport/auth/crypto_suite.h>
+#include <hicn/transport/auth/key_id.h>
#include <hicn/transport/utils/branch_prediction.h>
#include <hicn/transport/utils/log.h>
#include <hicn/transport/utils/membuf.h>
#include <hicn/transport/utils/object_pool.h>
-namespace utils {
-class Signer;
-class Verifier;
-} // namespace utils
-
namespace transport {
-
namespace core {
/*
@@ -45,11 +39,13 @@ namespace core {
* \_______________________________________|
*/
-class Packet : public std::enable_shared_from_this<Packet> {
- friend class utils::Signer;
- friend class utils::Verifier;
+class Packet : public utils::MemBuf,
+ public std::enable_shared_from_this<Packet> {
+ friend class auth::Signer;
+ friend class auth::Verifier;
public:
+ using Ptr = std::shared_ptr<Packet>;
using MemBufPtr = std::shared_ptr<utils::MemBuf>;
using Format = hicn_format_t;
static constexpr size_t default_mtu = 1500;
@@ -59,24 +55,29 @@ class Packet : public std::enable_shared_from_this<Packet> {
* the eventual payload will be added by prepending the payload buffer
* to the buffer chain whose the fist buffer is the header itself.
*/
- Packet(Format format = HF_UNSPEC);
+ Packet(Format format = HF_INET6_TCP, std::size_t additional_header_size = 0);
/**
* Create new IP packet using raw buffer.
*/
- Packet(const uint8_t *buffer, std::size_t size);
- Packet(MemBufPtr &&buffer);
- /*
- * Enforce zero-copy lifestyle.
- */
- Packet(const Packet &other) = delete;
- Packet &operator=(const Packet &other) = delete;
+ /* Copy buffer */
+ Packet(CopyBufferOp, const uint8_t *buffer, std::size_t size);
+ /* Wrap buffer */
+ Packet(WrapBufferOp, uint8_t *buffer, std::size_t length, std::size_t size);
+ /* Create new using pre-allocated buffer */
+ Packet(CreateOp, uint8_t *buffer, std::size_t length, std::size_t size,
+ Format format = HF_INET6_TCP, std::size_t additional_header_size = 0);
+ /* Move MemBuf */
+ Packet(MemBuf &&buffer);
+
+ Packet(Packet &&other);
/*
- * Move constructor.
+ * Copy constructor and assignemnt operators.
*/
- Packet(Packet &&other);
+ Packet(const Packet &other);
+ Packet &operator=(const Packet &other);
friend bool operator==(const Packet &l_packet, const Packet &r_packet);
@@ -98,36 +99,35 @@ class Packet : public std::enable_shared_from_this<Packet> {
static bool isInterest(const uint8_t *buffer);
+ bool isInterest();
+
static Format getFormatFromBuffer(const uint8_t *buffer, std::size_t length) {
Format format = HF_UNSPEC;
-
- if (TRANSPORT_EXPECT_FALSE(
- hicn_packet_get_format((const hicn_header_t *)buffer, &format) <
- 0)) {
- TRANSPORT_LOGE(
- "Error while getting format from packet buffer. Packet will be "
- "discarded.");
- hicn_packet_dump(buffer, length);
- }
-
+ hicn_packet_get_format((const hicn_header_t *)buffer, &format);
return format;
}
- TRANSPORT_ALWAYS_INLINE void replace(MemBufPtr &&buffer) {
- packet_ = std::move(buffer);
- packet_start_ = reinterpret_cast<hicn_header_t *>(packet_->writableData());
- header_head_ = packet_.get();
- payload_head_ = nullptr;
- format_ = getFormatFromBuffer(reinterpret_cast<uint8_t *>(packet_start_),
- packet_->length());
+ void reset() {
+ clear();
+ packet_start_ = reinterpret_cast<hicn_header_t *>(writableData());
+ header_offset_ = 0;
+ format_ = HF_UNSPEC;
+ payload_type_ = PayloadType::UNSPECIFIED;
name_.clear();
+
+ if (isChained()) {
+ separateChain(next(), prev());
+ }
}
+ void setFormat(Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
+
std::size_t payloadSize() const;
std::size_t headerSize() const;
- const std::shared_ptr<utils::MemBuf> acquireMemBufReference() const;
+ std::shared_ptr<utils::MemBuf> acquireMemBufReference();
virtual const Name &getName() const = 0;
@@ -145,25 +145,8 @@ class Packet : public std::enable_shared_from_this<Packet> {
Packet &appendPayload(std::unique_ptr<utils::MemBuf> &&payload);
- Packet &appendHeader(std::unique_ptr<utils::MemBuf> &&header);
-
- Packet &appendHeader(const uint8_t *buffer, std::size_t length);
-
std::unique_ptr<utils::MemBuf> getPayload() const;
- std::pair<const uint8_t *, std::size_t> getPayloadReference() const {
- int signature_size = 0;
-
- if (_is_ah(format_)) {
- signature_size = (uint32_t)getSignatureSize();
- }
-
- auto header_size = getHeaderSizeFromFormat(format_, signature_size);
- auto payload_length = payloadSize();
-
- return std::make_pair(packet_->data() + header_size, payload_length);
- }
-
Packet &updateLength(std::size_t length = 0);
PayloadType getPayloadType() const;
@@ -174,35 +157,38 @@ class Packet : public std::enable_shared_from_this<Packet> {
void dump() const;
+ static void dump(uint8_t *buffer, std::size_t length);
+
virtual void setLocator(const ip_address_t &locator) = 0;
virtual ip_address_t getLocator() const = 0;
- void setSignatureTimestamp(const uint64_t &timestamp);
+ /**
+ * @brief Set signature timestamp, in milliseconds.
+ */
+ void setSignatureTimestamp(const uint64_t &timestamp_milliseconds);
uint64_t getSignatureTimestamp() const;
- void setValidationAlgorithm(const utils::CryptoSuite &validation_algorithm);
+ void setValidationAlgorithm(const auth::CryptoSuite &validation_algorithm);
- utils::CryptoSuite getValidationAlgorithm() const;
+ auth::CryptoSuite getValidationAlgorithm() const;
- void setKeyId(const utils::KeyId &key_id);
+ void setKeyId(const auth::KeyId &key_id);
- utils::KeyId getKeyId() const;
+ auth::KeyId getKeyId() const;
- virtual utils::CryptoHash computeDigest(
- utils::CryptoHashType algorithm) const;
+ virtual auth::CryptoHash computeDigest(auth::CryptoHashType algorithm) const;
void setChecksum() {
- uint16_t partial_csum = 0;
-
- for (utils::MemBuf *current = header_head_->next();
- current && current != header_head_; current = current->next()) {
- if (partial_csum != 0) {
- partial_csum = ~partial_csum;
- }
- partial_csum = csum(current->data(), current->length(), partial_csum);
+ uint16_t partial_csum =
+ csum(data() + HICN_V6_TCP_HDRLEN, length() - HICN_V6_TCP_HDRLEN, 0);
+
+ for (utils::MemBuf *current = next(); current != this;
+ current = current->next()) {
+ partial_csum = csum(current->data(), current->length(), ~partial_csum);
}
+
if (hicn_packet_compute_header_checksum(format_, packet_start_,
partial_csum) < 0) {
throw errors::MalformedPacketException();
@@ -234,12 +220,12 @@ class Packet : public std::enable_shared_from_this<Packet> {
Packet &setTTL(uint8_t hops);
uint8_t getTTL() const;
- void separateHeaderPayload();
- void resetPayload();
-
private:
virtual void resetForHash() = 0;
void setSignatureSize(std::size_t size_bytes);
+ void prependPayload(const uint8_t **buffer, std::size_t *size);
+
+ bool authenticationHeader() const { return _is_ah(format_); }
std::size_t getSignatureSize() const {
size_t size_bytes;
@@ -256,12 +242,11 @@ class Packet : public std::enable_shared_from_this<Packet> {
uint8_t *getSignature() const;
protected:
- Name name_;
- MemBufPtr packet_;
hicn_header_t *packet_start_;
- utils::MemBuf *header_head_;
- utils::MemBuf *payload_head_;
+ std::size_t header_offset_;
mutable Format format_;
+ Name name_;
+ mutable PayloadType payload_type_;
static const core::Name base_name;
};
diff --git a/libtransport/includes/hicn/transport/core/payload_type.h b/libtransport/includes/hicn/transport/core/payload_type.h
index fa79db3..8c918f7 100644
--- a/libtransport/includes/hicn/transport/core/payload_type.h
+++ b/libtransport/includes/hicn/transport/core/payload_type.h
@@ -20,8 +20,9 @@ namespace transport {
namespace core {
enum class PayloadType : uint16_t {
- CONTENT_OBJECT = HPT_DATA,
+ DATA = HPT_DATA,
MANIFEST = HPT_MANIFEST,
+ UNSPECIFIED = HPT_UNSPEC
};
} // end namespace core
diff --git a/libtransport/includes/hicn/transport/core/prefix.h b/libtransport/includes/hicn/transport/core/prefix.h
index c3805f1..7ef667b 100644
--- a/libtransport/includes/hicn/transport/core/prefix.h
+++ b/libtransport/includes/hicn/transport/core/prefix.h
@@ -35,9 +35,9 @@ class Prefix {
Prefix(const core::Name &content_name, uint16_t prefix_length);
- std::unique_ptr<Sockaddr> toSockaddr();
+ std::unique_ptr<Sockaddr> toSockaddr() const;
- uint16_t getPrefixLength();
+ uint16_t getPrefixLength() const;
Prefix &setPrefixLength(uint16_t prefix_length);
@@ -58,13 +58,13 @@ class Prefix {
Prefix &setNetwork(std::string &network);
- int getAddressFamily();
+ int getAddressFamily() const;
Prefix &setAddressFamily(int address_family);
Name makeRandomName() const;
- ip_prefix_t &toIpPrefixStruct();
+ const ip_prefix_t &toIpPrefixStruct() const;
private:
static bool checkPrefixLengthAndAddressFamily(uint16_t prefix_length,
diff --git a/libtransport/includes/hicn/transport/errors/errors.h b/libtransport/includes/hicn/transport/errors/errors.h
index 512e357..b659820 100644
--- a/libtransport/includes/hicn/transport/errors/errors.h
+++ b/libtransport/includes/hicn/transport/errors/errors.h
@@ -15,10 +15,13 @@
#pragma once
+#include <hicn/transport/errors/indexing_exception.h>
#include <hicn/transport/errors/invalid_ip_address_exception.h>
+#include <hicn/transport/errors/malformed_ahpacket_exception.h>
#include <hicn/transport/errors/malformed_name_exception.h>
#include <hicn/transport/errors/malformed_packet_exception.h>
#include <hicn/transport/errors/not_implemented_exception.h>
#include <hicn/transport/errors/null_pointer_exception.h>
#include <hicn/transport/errors/runtime_exception.h>
-#include <hicn/transport/errors/tokenizer_exception.h> \ No newline at end of file
+#include <hicn/transport/errors/tokenizer_exception.h>
+#include <hicn/transport/errors/unexpected_manifest_exception.h>
diff --git a/libtransport/includes/hicn/transport/http/client_connection.h b/libtransport/includes/hicn/transport/http/client_connection.h
index 262756a..7e78e9c 100644
--- a/libtransport/includes/hicn/transport/http/client_connection.h
+++ b/libtransport/includes/hicn/transport/http/client_connection.h
@@ -68,7 +68,7 @@ class HTTPClientConnection {
HTTPClientConnection &setTimeout(const std::chrono::seconds &timeout);
- HTTPClientConnection &setCertificate(const std::string &cert_path);
+ HTTPClientConnection &setVerifier(std::shared_ptr<auth::Verifier> verifier);
private:
class Implementation;
@@ -77,4 +77,4 @@ class HTTPClientConnection {
} // end namespace http
-} // end namespace transport \ No newline at end of file
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt b/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt
index 7370ad1..08f8809 100644
--- a/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt
@@ -16,12 +16,11 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/socket_consumer.h
${CMAKE_CURRENT_SOURCE_DIR}/socket_producer.h
- ${CMAKE_CURRENT_SOURCE_DIR}/rtc_socket_producer.h
${CMAKE_CURRENT_SOURCE_DIR}/publication_options.h
${CMAKE_CURRENT_SOURCE_DIR}/socket_options_default_values.h
${CMAKE_CURRENT_SOURCE_DIR}/socket_options_keys.h
${CMAKE_CURRENT_SOURCE_DIR}/callbacks.h
- ${CMAKE_CURRENT_SOURCE_DIR}/verification_policy.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/global_conf_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/statistics.h
${CMAKE_CURRENT_SOURCE_DIR}/portal.h
)
diff --git a/libtransport/includes/hicn/transport/interfaces/callbacks.h b/libtransport/includes/hicn/transport/interfaces/callbacks.h
index 6ae0779..95b4d19 100644
--- a/libtransport/includes/hicn/transport/interfaces/callbacks.h
+++ b/libtransport/includes/hicn/transport/interfaces/callbacks.h
@@ -16,7 +16,7 @@
#pragma once
#include <hicn/transport/interfaces/statistics.h>
-#include <hicn/transport/interfaces/verification_policy.h>
+#include <hicn/transport/auth/policies.h>
#include <functional>
#include <system_error>
@@ -75,25 +75,6 @@ using ConsumerContentObjectCallback =
std::function<void(ConsumerSocket &, const core::ContentObject &)>;
/**
- * The ConsumerContentObjectVerificationCallback will be called by the transport
- * if an application is willing to verify each content object. Note that a
- * better alternative is to instrument the transport to perform the verification
- * autonomously, without requiring the intervention of the application.
- */
-using ConsumerContentObjectVerificationCallback =
- std::function<bool(ConsumerSocket &, const core::ContentObject &)>;
-
-/**
- * The ConsumerContentObjectVerificationFailedCallback will be caled by the
- * transport if a data packet (either manifest or content object) cannot be
- * verified. The application here decides what to do by returning a
- * VerificationFailedPolicy object.
- */
-using ConsumerContentObjectVerificationFailedCallback =
- std::function<VerificationPolicy(
- ConsumerSocket &, const core::ContentObject &, std::error_code ec)>;
-
-/**
* The ProducerContentObjectCallback will be called in different parts of the
* consumer socket processing pipeline, with a ProducerSocket and an
* ContentObject as parameters.
diff --git a/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h b/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h
new file mode 100644
index 0000000..a9fe6fa
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+/**
+ * Global configuration interface.
+ */
+
+namespace transport {
+namespace interface {
+namespace global_config {
+
+static const constexpr char io_module_section[] = "io_module";
+void parseConfigurationFile(const std::string& path = "");
+
+class ConfigurationObject {
+ public:
+ /**
+ * Set configuration.
+ */
+ void set();
+
+ /**
+ * Get configuration.
+ */
+ void get();
+
+ /**
+ * Get configuration key
+ */
+ virtual std::string getKey() const = 0;
+};
+
+class IoModuleConfiguration : public ConfigurationObject {
+ public:
+ std::string getKey() const override { return io_module_section; }
+
+ std::string name;
+ std::vector<std::string> search_path;
+};
+
+} // namespace global_config
+} // namespace interface
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h
index 6f0d48b..7b284c5 100644
--- a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h
+++ b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h
@@ -16,8 +16,7 @@
#pragma once
#include <hicn/transport/interfaces/socket_producer.h>
-
-#include <hicn/transport/security/identity.h>
+#include <hicn/transport/auth/identity.h>
namespace transport {
@@ -27,7 +26,7 @@ class P2PSecureProducerSocket : public ProducerSocket {
public:
P2PSecureProducerSocket();
P2PSecureProducerSocket(bool rtc,
- const std::shared_ptr<utils::Identity> &identity);
+ const std::shared_ptr<auth::Identity> &identity);
~P2PSecureProducerSocket() = default;
};
diff --git a/libtransport/includes/hicn/transport/interfaces/portal.h b/libtransport/includes/hicn/transport/interfaces/portal.h
index 724cd75..22c8591 100644
--- a/libtransport/includes/hicn/transport/interfaces/portal.h
+++ b/libtransport/includes/hicn/transport/interfaces/portal.h
@@ -23,7 +23,6 @@
#define ASIO_STANDALONE
#endif
#include <asio/io_service.hpp>
-
#include <functional>
#define UNSET_CALLBACK 0
@@ -71,8 +70,7 @@ class Portal {
*/
class ConsumerCallback {
public:
- virtual void onContentObject(core::Interest::Ptr &&i,
- core::ContentObject::Ptr &&c) = 0;
+ virtual void onContentObject(core::Interest &i, core::ContentObject &c) = 0;
virtual void onTimeout(core::Interest::Ptr &&i) = 0;
virtual void onError(std::error_code ec) = 0;
};
@@ -83,12 +81,12 @@ class Portal {
*/
class ProducerCallback {
public:
- virtual void onInterest(core::Interest::Ptr &&i) = 0;
+ virtual void onInterest(core::Interest &i) = 0;
virtual void onError(std::error_code ec) = 0;
};
using OnContentObjectCallback =
- std::function<void(core::Interest::Ptr &&, core::ContentObject::Ptr &&)>;
+ std::function<void(core::Interest &, core::ContentObject &)>;
using OnInterestTimeoutCallback = std::function<void(core::Interest::Ptr &&)>;
Portal();
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_consumer.h b/libtransport/includes/hicn/transport/interfaces/socket_consumer.h
index 2447f9b..621e7ce 100644
--- a/libtransport/includes/hicn/transport/interfaces/socket_consumer.h
+++ b/libtransport/includes/hicn/transport/interfaces/socket_consumer.h
@@ -21,7 +21,7 @@
#include <hicn/transport/interfaces/callbacks.h>
#include <hicn/transport/interfaces/socket_options_default_values.h>
#include <hicn/transport/interfaces/socket_options_keys.h>
-#include <hicn/transport/security/verifier.h>
+#include <hicn/transport/auth/verifier.h>
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
@@ -208,14 +208,6 @@ class ConsumerSocket {
int asyncConsume(const Name &name);
/**
- * Verify the packets containing a key after the origin of the key has been
- * validated by the client.
- *
- * @return true if all packets are valid, false otherwise
- */
- bool verifyKeyPackets();
-
- /**
* Stops the consumer socket. If several downloads are queued (using
* asyncConsume), this call stops just the current one.
*/
@@ -251,14 +243,6 @@ class ConsumerSocket {
int setSocketOption(int socket_option_key,
ConsumerContentObjectCallback socket_option_value);
- int setSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback socket_option_value);
-
- int setSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationCallback socket_option_value);
-
int setSocketOption(int socket_option_key,
ConsumerInterestCallback socket_option_value);
@@ -267,7 +251,7 @@ class ConsumerSocket {
int setSocketOption(
int socket_option_key,
- const std::shared_ptr<utils::Verifier> &socket_option_value);
+ const std::shared_ptr<auth::Verifier> &socket_option_value);
int setSocketOption(int socket_option_key,
const std::string &socket_option_value);
@@ -286,21 +270,13 @@ class ConsumerSocket {
int getSocketOption(int socket_option_key,
ConsumerContentObjectCallback **socket_option_value);
- int getSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback **socket_option_value);
-
- int getSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationCallback **socket_option_value);
-
int getSocketOption(int socket_option_key,
ConsumerInterestCallback **socket_option_value);
int getSocketOption(int socket_option_key, IcnObserver **socket_option_value);
int getSocketOption(int socket_option_key,
- std::shared_ptr<utils::Verifier> &socket_option_value);
+ std::shared_ptr<auth::Verifier> &socket_option_value);
int getSocketOption(int socket_option_key, std::string &socket_option_value);
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h b/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h
index bcf103b..f4945ac 100644
--- a/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h
+++ b/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h
@@ -16,6 +16,7 @@
#pragma once
#include <hicn/base.h>
+
#include <chrono>
#include <cstdint>
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h b/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h
index f50e919..00cd440 100644
--- a/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h
+++ b/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h
@@ -32,6 +32,11 @@ typedef enum {
} TransportProtocolAlgorithms;
typedef enum {
+ BYTE_STREAM = 10,
+ RTC_PROD = 11,
+} ProductionProtocolAlgorithms;
+
+typedef enum {
INPUT_BUFFER_SIZE = 101,
OUTPUT_BUFFER_SIZE = 102,
NETWORK_NAME = 103,
@@ -40,7 +45,6 @@ typedef enum {
DATA_PACKET_SIZE = 106,
INTEREST_LIFETIME = 107,
CONTENT_OBJECT_EXPIRY_TIME = 108,
- KEY_CONTENT = 110,
MIN_WINDOW_SIZE = 111,
MAX_WINDOW_SIZE = 112,
CURRENT_WINDOW_SIZE = 113,
@@ -50,12 +54,10 @@ typedef enum {
RUNNING = 117,
APPLICATION_BUFFER = 118,
HASH_ALGORITHM = 119,
- CRYPTO_SUITE = 120,
SIGNER = 121,
VERIFIER = 122,
- CERTIFICATE = 123,
- VERIFY_SIGNATURE = 124,
STATS_INTERVAL = 125,
+ SUFFIX_STRATEGY = 126
} GeneralTransportOptions;
typedef enum {
@@ -98,6 +100,7 @@ typedef enum {
CONTENT_OBJECT_READY = 510,
CONTENT_OBJECT_OUTPUT = 511,
CONTENT_PRODUCED = 512,
+ CONTENT_OBJECT_TO_SIGN = 513
} ProducerCallbacksOptions;
typedef enum { OUTPUT_INTERFACE = 601 } DataLinkOptions;
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_producer.h b/libtransport/includes/hicn/transport/interfaces/socket_producer.h
index e269fb8..302b03f 100644
--- a/libtransport/includes/hicn/transport/interfaces/socket_producer.h
+++ b/libtransport/includes/hicn/transport/interfaces/socket_producer.h
@@ -21,7 +21,7 @@
#include <hicn/transport/interfaces/callbacks.h>
#include <hicn/transport/interfaces/socket_options_default_values.h>
#include <hicn/transport/interfaces/socket_options_keys.h>
-#include <hicn/transport/security/signer.h>
+#include <hicn/transport/auth/signer.h>
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
@@ -40,7 +40,10 @@ using namespace core;
class ProducerSocket {
public:
- explicit ProducerSocket(int protocol = 0);
+ explicit ProducerSocket(
+ int protocol = ProductionProtocolAlgorithms::BYTE_STREAM);
+
+ explicit ProducerSocket(int protocol, asio::io_service &io_service);
virtual ~ProducerSocket();
@@ -48,22 +51,21 @@ class ProducerSocket {
bool isRunning();
- uint32_t produce(Name content_name, const uint8_t *buffer, size_t buffer_size,
- bool is_last = true, uint32_t start_offset = 0) {
- return produce(content_name, utils::MemBuf::copyBuffer(buffer, buffer_size),
- is_last, start_offset);
- }
+ void registerPrefix(const Prefix &producer_namespace);
- uint32_t produce(Name content_name, std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last = true, uint32_t start_offset = 0);
+ uint32_t produceStream(const Name &content_name, const uint8_t *buffer,
+ size_t buffer_size, bool is_last = true,
+ uint32_t start_offset = 0);
- void produce(ContentObject &content_object);
+ uint32_t produceStream(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last = true, uint32_t start_offset = 0);
- void produce(const uint8_t *buffer, size_t buffer_size) {
- produce(utils::MemBuf::copyBuffer(buffer, buffer_size));
- }
+ uint32_t produceDatagram(const Name &content_name, const uint8_t *buffer,
+ size_t buffer_size);
- void produce(std::unique_ptr<utils::MemBuf> &&buffer);
+ uint32_t produceDatagram(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer);
void asyncProduce(const Name &suffix, const uint8_t *buf, size_t buffer_size,
bool is_last = true, uint32_t *start_offset = nullptr);
@@ -72,9 +74,7 @@ class ProducerSocket {
bool is_last, uint32_t offset,
uint32_t **last_segment = nullptr);
- void asyncProduce(ContentObject &content_object);
-
- void registerPrefix(const Prefix &producer_namespace);
+ void produce(ContentObject &content_object);
void serveForever();
@@ -104,14 +104,13 @@ class ProducerSocket {
ProducerContentCallback socket_option_value);
int setSocketOption(int socket_option_key,
- utils::CryptoHashType socket_option_value);
+ auth::CryptoHashType socket_option_value);
int setSocketOption(int socket_option_key,
- utils::CryptoSuite socket_option_value);
+ auth::CryptoSuite socket_option_value);
- int setSocketOption(
- int socket_option_key,
- const std::shared_ptr<utils::Signer> &socket_option_value);
+ int setSocketOption(int socket_option_key,
+ const std::shared_ptr<auth::Signer> &socket_option_value);
int setSocketOption(int socket_option_key,
const std::string &socket_option_value);
@@ -133,13 +132,13 @@ class ProducerSocket {
ProducerInterestCallback **socket_option_value);
int getSocketOption(int socket_option_key,
- utils::CryptoHashType &socket_option_value);
+ auth::CryptoHashType &socket_option_value);
int getSocketOption(int socket_option_key,
- utils::CryptoSuite &socket_option_value);
+ auth::CryptoSuite &socket_option_value);
int getSocketOption(int socket_option_key,
- std::shared_ptr<utils::Signer> &socket_option_value);
+ std::shared_ptr<auth::Signer> &socket_option_value);
int getSocketOption(int socket_option_key, std::string &socket_option_value);
diff --git a/libtransport/includes/hicn/transport/interfaces/statistics.h b/libtransport/includes/hicn/transport/interfaces/statistics.h
index 26831fb..92c58da 100644
--- a/libtransport/includes/hicn/transport/interfaces/statistics.h
+++ b/libtransport/includes/hicn/transport/interfaces/statistics.h
@@ -31,6 +31,8 @@ class IcnObserver {
virtual void notifyDownloadTime(double downloadTime) = 0;
};
+class ProductionStatistics {};
+
class TransportStatistics {
static constexpr double default_alpha = 0.7;
@@ -43,7 +45,15 @@ class TransportStatistics {
interest_tx_(0),
alpha_(alpha),
loss_ratio_(0.0),
- queuing_delay_(0.0) {}
+ queuing_delay_(0.0),
+ interest_FEC_tx_(0),
+ bytes_FEC_received_(0),
+ lost_data_(0),
+ recovered_data_(0),
+ status_(-1),
+ // avg_data_rtt_(0),
+ avg_pending_pkt_(0.0),
+ received_nacks_(0) {}
TRANSPORT_ALWAYS_INLINE void updateRetxCount(uint64_t retx) {
retx_count_ += retx;
@@ -74,6 +84,32 @@ class TransportStatistics {
queuing_delay_ = queuing_delay;
}
+ TRANSPORT_ALWAYS_INLINE void updateInterestFecTx(uint64_t int_tx) {
+ interest_FEC_tx_ += int_tx;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateBytesFecRecv(uint64_t bytes) {
+ bytes_FEC_received_ += bytes;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateLostData(uint64_t pkt) {
+ lost_data_ += pkt;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateRecoveredData(uint64_t bytes) {
+ recovered_data_ += bytes;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateCCState(int status) { status_ = status; }
+
+ TRANSPORT_ALWAYS_INLINE void updateAveragePendingPktCount(double pkt) {
+ avg_pending_pkt_ = (alpha_ * avg_pending_pkt_) + ((1. - alpha_) * pkt);
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateReceivedNacks(uint32_t nacks) {
+ received_nacks_ += nacks;
+ }
+
TRANSPORT_ALWAYS_INLINE uint64_t getRetxCount() const { return retx_count_; }
TRANSPORT_ALWAYS_INLINE uint64_t getBytesRecv() const {
@@ -96,6 +132,32 @@ class TransportStatistics {
return queuing_delay_;
}
+ TRANSPORT_ALWAYS_INLINE uint64_t getInterestFecTxCount() const {
+ return interest_FEC_tx_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getBytesFecRecv() const {
+ return bytes_FEC_received_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getLostData() const { return lost_data_; }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getBytesRecoveredData() const {
+ return recovered_data_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE int getCCStatus() const { return status_; }
+
+ TRANSPORT_ALWAYS_INLINE double getAveragePendingPktCount() const {
+ return avg_pending_pkt_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE uint32_t getReceivedNacks() const {
+ return received_nacks_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void setAlpha(double val) { alpha_ = val; }
+
TRANSPORT_ALWAYS_INLINE void reset() {
retx_count_ = 0;
bytes_received_ = 0;
@@ -103,6 +165,14 @@ class TransportStatistics {
avg_window_size_ = 0;
interest_tx_ = 0;
loss_ratio_ = 0;
+ interest_FEC_tx_ = 0;
+ bytes_FEC_received_ = 0;
+ lost_data_ = 0;
+ recovered_data_ = 0;
+ status_ = 0;
+ // avg_data_rtt_ = 0;
+ avg_pending_pkt_ = 0;
+ received_nacks_ = 0;
}
private:
@@ -114,6 +184,13 @@ class TransportStatistics {
double alpha_;
double loss_ratio_;
double queuing_delay_;
+ uint64_t interest_FEC_tx_;
+ uint64_t bytes_FEC_received_;
+ uint64_t lost_data_;
+ uint64_t recovered_data_;
+ int status_; // transport status (e.g. sync status, congestion etc.)
+ double avg_pending_pkt_;
+ uint32_t received_nacks_;
};
} // namespace interface
diff --git a/libtransport/includes/hicn/transport/portability/c_portability.h b/libtransport/includes/hicn/transport/portability/c_portability.h
index 71e976a..9fe9ef9 100644
--- a/libtransport/includes/hicn/transport/portability/c_portability.h
+++ b/libtransport/includes/hicn/transport/portability/c_portability.h
@@ -33,4 +33,4 @@
#define TRANSPORT_ALWAYS_INLINE inline __attribute__((__always_inline__))
#else
#define TRANSPORT_ALWAYS_INLINE inline
-#endif \ No newline at end of file
+#endif
diff --git a/libtransport/includes/hicn/transport/portability/platform.h b/libtransport/includes/hicn/transport/portability/platform.h
new file mode 100644
index 0000000..282d277
--- /dev/null
+++ b/libtransport/includes/hicn/transport/portability/platform.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+/*
+ * Extract the "MACINTOSH" flag from the compiler.
+ */
+#if defined(__APPLE__)
+#define UNIX
+#define MACINTOSH
+#endif
+
+/*
+ * Extract the "SUNOS" flag from the compiler.
+ */
+#if defined(sun)
+#define UNIX
+#define SUNOS
+#endif
+
+/*
+ * Extract the "LINUX" flag from compiler.
+ */
+#ifdef __linux__
+#define UNIX
+#define LINUX
+#endif
+
+/*
+ * Extract the "ANDROID" flag from compiler.
+ */
+#ifdef __ANDROID__
+#define UNIX
+#define LINUX
+#ifndef ANDROID
+#define ANDROID
+#endif
+#endif
+
+/*
+ * Extract the "BSD" flag from compiler.
+ */
+#if defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || \
+ defined(__OpenBSD__)
+#define OS_BSD
+#define UNIX
+#endif
+
+/*
+ * Extract the "MSDOS" flag from the compiler.
+ */
+#ifdef __MSDOS__
+#define MSDOS
+#undef UNIX
+#endif
+
+/*
+ * Extract the "WINDOWS" flag from the compiler.
+ */
+#if defined(_Windows) || defined(__WINDOWS__) || defined(__WIN32__) || \
+ defined(WIN32) || defined(__WINNT__) || defined(__NT__) || \
+ defined(_WIN32) || defined(_WIN64)
+#define WINDOWS
+#ifdef _MSC_VER
+#define MSV
+#if defined(DEBUG) || defined(DEBUGTRACE)
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#else
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+#endif
+#else
+#undef MSV
+#endif
+#undef UNIX
+#undef MSDOS
+#endif
+
+/*
+ * Remove the WINDOWS flag when using MACINTOSH.
+ */
+#ifdef MACINTOSH
+#undef WINDOWS
+#endif
+
+/*
+ * Assume UNIX if not Windows, Macintosh or MSDOS.
+ */
+#if !defined(WINDOWS) && !defined(MACINTOSH) && !defined(MSDOS)
+#define UNIX
+#endif
diff --git a/libtransport/includes/hicn/transport/portability/portability.h b/libtransport/includes/hicn/transport/portability/portability.h
index 1d97a34..539ce2d 100644
--- a/libtransport/includes/hicn/transport/portability/portability.h
+++ b/libtransport/includes/hicn/transport/portability/portability.h
@@ -22,8 +22,8 @@
#endif
#include <hicn/transport/portability/c_portability.h>
-
#include <string.h>
+
#include <cstddef>
namespace portability {
diff --git a/libtransport/includes/hicn/transport/portability/win_portability.h b/libtransport/includes/hicn/transport/portability/win_portability.h
index 65d9492..bfbe431 100644
--- a/libtransport/includes/hicn/transport/portability/win_portability.h
+++ b/libtransport/includes/hicn/transport/portability/win_portability.h
@@ -31,6 +31,7 @@
#include <winsock2.h>
#include <ws2ipdef.h>
#include <ws2tcpip.h>
+
#include <algorithm>
#define __ORDER_LITTLE_ENDIAN__ 0x41424344UL
diff --git a/libtransport/includes/hicn/transport/utils/CMakeLists.txt b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
index 11a9b0f..7094601 100644
--- a/libtransport/includes/hicn/transport/utils/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
@@ -31,6 +31,11 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/fixed_block_allocator.h
${CMAKE_CURRENT_SOURCE_DIR}/event_thread.h
${CMAKE_CURRENT_SOURCE_DIR}/string_utils.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/file.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/shared_ptr_utils.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/move_wrapper.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/noncopyable.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/singleton.h
)
if(NOT WIN32)
diff --git a/libtransport/includes/hicn/transport/utils/conversions.h b/libtransport/includes/hicn/transport/utils/conversions.h
index 24b5292..52d3e31 100644
--- a/libtransport/includes/hicn/transport/utils/conversions.h
+++ b/libtransport/includes/hicn/transport/utils/conversions.h
@@ -16,8 +16,8 @@
#pragma once
#include <hicn/transport/portability/portability.h>
-
#include <stdio.h>
+
#include <cstdint>
#include <string>
diff --git a/libtransport/includes/hicn/transport/utils/enum_iterator.h b/libtransport/includes/hicn/transport/utils/enum_iterator.h
new file mode 100644
index 0000000..5e108b0
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/enum_iterator.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <type_traits>
+
+template <typename C, C begin_val, C end_val>
+class Iterator {
+ typedef typename std::underlying_type<C>::type val_t;
+ int val;
+
+ public:
+ Iterator(const C& f) : val(static_cast<val_t>(f)) {}
+
+ Iterator() : val(static_cast<val_t>(begin_val)) {}
+
+ Iterator operator++() {
+ ++val;
+ return *this;
+ }
+
+ C operator*() { return static_cast<C>(val); }
+
+ Iterator begin() { return *this; } // default ctor is good
+
+ Iterator end() {
+ static const Iterator endIter = ++Iterator(end_val); // cache it
+ return endIter;
+ }
+
+ bool operator!=(const Iterator& i) { return val != i.val; }
+}; \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/event_thread.h b/libtransport/includes/hicn/transport/utils/event_thread.h
index 702c98f..bb6ab90 100644
--- a/libtransport/includes/hicn/transport/utils/event_thread.h
+++ b/libtransport/includes/hicn/transport/utils/event_thread.h
@@ -17,7 +17,11 @@
#include <hicn/transport/config.h>
#include <hicn/transport/errors/runtime_exception.h>
+#include <hicn/transport/utils/log.h>
+#ifndef ASIO_STANDALONE
+#define ASIO_STANDALONE
+#endif
#include <asio.hpp>
#include <memory>
#include <thread>
@@ -25,36 +29,58 @@
namespace utils {
class EventThread {
- private:
- // No copies
- EventThread(const EventThread&) = delete; // non construction-copyable
- EventThread& operator=(const EventThread&) = delete; // non copyable
-
public:
- explicit EventThread(asio::io_service& io_service)
+ EventThread(asio::io_service& io_service, bool detached = false)
: internal_io_service_(nullptr),
- io_service_(io_service),
+ io_service_(std::ref(io_service)),
work_(std::make_unique<asio::io_service::work>(io_service_)),
- thread_(nullptr) {
+ thread_(nullptr),
+ detached_(detached) {
run();
}
- explicit EventThread()
+ EventThread(bool detached = false)
: internal_io_service_(std::make_unique<asio::io_service>()),
- io_service_(*internal_io_service_),
+ io_service_(std::ref(*internal_io_service_)),
work_(std::make_unique<asio::io_service::work>(io_service_)),
- thread_(nullptr) {
+ thread_(nullptr),
+ detached_(detached) {
run();
}
+ EventThread(const EventThread&) = delete;
+ EventThread& operator=(const EventThread&) = delete;
+
+ EventThread(EventThread&& other)
+ : internal_io_service_(std::move(other.internal_io_service_)),
+ io_service_(std::move(other.io_service_)),
+ work_(std::move(other.work_)),
+ thread_(std::move(other.thread_)),
+ detached_(std::move(other.detached_)) {}
+
+ EventThread& operator=(EventThread&& other) {
+ internal_io_service_ = std::move(other.internal_io_service_);
+ io_service_ = std::move(other.io_service_);
+ work_ = std::move(other.work_);
+ thread_ = std::move(other.thread_);
+ detached_ = other.detached_;
+
+ return *this;
+ }
+
~EventThread() { stop(); }
void run() {
if (stopped()) {
- io_service_.reset();
+ io_service_.get().stopped();
}
- thread_ = std::make_unique<std::thread>([this]() { io_service_.run(); });
+ thread_ =
+ std::make_unique<std::thread>([this]() { io_service_.get().run(); });
+
+ if (detached_) {
+ thread_->detach();
+ }
}
std::thread::id getThreadId() const {
@@ -67,14 +93,12 @@ class EventThread {
template <typename Func>
void add(Func&& f) {
- // If the function f
- // TODO USe post in mac os, asio->post in xenial
- io_service_.post(std::forward<Func&&>(f));
+ io_service_.get().post(std::forward<Func&&>(f));
}
template <typename Func>
void tryRunHandlerNow(Func&& f) {
- io_service_.dispatch(std::forward<Func&&>(f));
+ io_service_.get().dispatch(std::forward<Func&&>(f));
}
void stop() {
@@ -87,15 +111,16 @@ class EventThread {
thread_.reset();
}
- bool stopped() { return io_service_.stopped(); }
+ bool stopped() { return io_service_.get().stopped(); }
asio::io_service& getIoService() { return io_service_; }
private:
std::unique_ptr<asio::io_service> internal_io_service_;
- asio::io_service& io_service_;
+ std::reference_wrapper<asio::io_service> io_service_;
std::unique_ptr<asio::io_service::work> work_;
std::unique_ptr<std::thread> thread_;
+ bool detached_;
};
} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/file.h b/libtransport/includes/hicn/transport/utils/file.h
new file mode 100644
index 0000000..4c73f33
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/file.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/stat.h>
+
+namespace utils {
+
+class File {
+ public:
+ static inline bool exists(const std::string& name) {
+ struct stat buffer;
+ return (stat(name.c_str(), &buffer) == 0);
+ }
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h
index 1ade151..b1df364 100644
--- a/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h
+++ b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h
@@ -5,104 +5,99 @@
#pragma once
#include <hicn/transport/portability/c_portability.h>
+#include <hicn/transport/utils/singleton.h>
#include <hicn/transport/utils/spinlock.h>
-
#include <stdint.h>
+
+#include <cassert>
#include <cstdlib>
#include <memory>
-#include <cassert>
namespace utils {
-template <std::size_t DEFAULT_SIZE = 512, std::size_t OBJECTS = 4096>
-class FixedBlockAllocator {
- FixedBlockAllocator(std::size_t size = DEFAULT_SIZE,
- std::size_t objects = OBJECTS)
- : block_size_(size < sizeof(void*) ? sizeof(long*) : size),
- object_size_(size),
- max_objects_(objects),
- p_head_(NULL),
- pool_index_(0),
- block_count_(0),
- blocks_in_use_(0),
- allocations_(0),
- deallocations_(0) {
- p_pool_ = (uint8_t*)new uint8_t[block_size_ * max_objects_];
- }
+template <std::size_t SIZE = 512, std::size_t OBJECTS = 4096>
+class FixedBlockAllocator
+ : public utils::Singleton<FixedBlockAllocator<SIZE, OBJECTS>> {
+ friend class utils::Singleton<FixedBlockAllocator<SIZE, OBJECTS>>;
public:
- static FixedBlockAllocator* getInstance() {
- if (!instance_) {
- instance_ = std::unique_ptr<FixedBlockAllocator>(
- new FixedBlockAllocator(DEFAULT_SIZE, OBJECTS));
+ ~FixedBlockAllocator() {
+ for (auto& p : p_pools_) {
+ delete[] p;
}
-
- return instance_.get();
}
- ~FixedBlockAllocator() { delete[] p_pool_; }
-
- TRANSPORT_ALWAYS_INLINE void* allocateBlock(size_t size = DEFAULT_SIZE) {
- assert(size <= DEFAULT_SIZE);
+ void* allocateBlock(size_t size = SIZE) {
+ assert(size <= SIZE);
uint32_t index;
+ SpinLock::Acquire locked(lock_);
void* p_block = pop();
if (!p_block) {
- if (pool_index_ < max_objects_) {
- {
- SpinLock::Acquire locked(lock_);
- index = pool_index_++;
- }
- p_block = (void*)(p_pool_ + (index * block_size_));
- } else {
- // TODO Consider increasing pool here instead of throwing an exception
- throw std::runtime_error("No more memory available from packet pool!");
+ if (TRANSPORT_EXPECT_FALSE(current_pool_index_ >= max_objects_)) {
+ // Allocate new memory block
+ TRANSPORT_LOGV("Allocating new block of %zu size", SIZE * OBJECTS);
+ p_pools_.emplace_front(
+ new typename std::aligned_storage<SIZE>::type[max_objects_]);
+ // reset current_pool_index_
+ current_pool_index_ = 0;
}
- }
- blocks_in_use_++;
- allocations_++;
+ auto& latest = p_pools_.front();
+ index = current_pool_index_++;
+ blocks_in_use_++;
+ allocations_++;
+ p_block = (void*)&latest[index];
+ }
return p_block;
}
- TRANSPORT_ALWAYS_INLINE void deallocateBlock(void* pBlock) {
+ void deallocateBlock(void* pBlock) {
+ SpinLock::Acquire locked(lock_);
push(pBlock);
- {
- SpinLock::Acquire locked(lock_);
- blocks_in_use_--;
- deallocations_++;
- }
+ blocks_in_use_--;
+ deallocations_++;
}
- TRANSPORT_ALWAYS_INLINE std::size_t blockSize() { return block_size_; }
+ public:
+ std::size_t blockSize() { return block_size_; }
- TRANSPORT_ALWAYS_INLINE uint32_t blockCount() { return block_count_; }
+ uint32_t blockCount() { return block_count_; }
- TRANSPORT_ALWAYS_INLINE uint32_t blocksInUse() { return blocks_in_use_; }
+ uint32_t blocksInUse() { return blocks_in_use_; }
- TRANSPORT_ALWAYS_INLINE uint32_t allocations() { return allocations_; }
+ uint32_t allocations() { return allocations_; }
- TRANSPORT_ALWAYS_INLINE uint32_t deallocations() { return deallocations_; }
+ uint32_t deallocations() { return deallocations_; }
private:
- TRANSPORT_ALWAYS_INLINE void push(void* p_memory) {
+ FixedBlockAllocator()
+ : block_size_(SIZE),
+ object_size_(SIZE),
+ max_objects_(OBJECTS),
+ p_head_(NULL),
+ current_pool_index_(0),
+ block_count_(0),
+ blocks_in_use_(0),
+ allocations_(0),
+ deallocations_(0) {
+ static_assert(SIZE >= sizeof(long*), "SIZE must be at least 8 bytes");
+ p_pools_.emplace_front(
+ new typename std::aligned_storage<SIZE>::type[max_objects_]);
+ }
+
+ void push(void* p_memory) {
Block* p_block = (Block*)p_memory;
- {
- SpinLock::Acquire locked(lock_);
- p_block->p_next = p_head_;
- p_head_ = p_block;
- }
+ p_block->p_next = p_head_;
+ p_head_ = p_block;
}
- TRANSPORT_ALWAYS_INLINE void* pop() {
+ void* pop() {
Block* p_block = nullptr;
- {
- SpinLock::Acquire locked(lock_);
- if (p_head_) {
- p_block = p_head_;
- p_head_ = p_head_->p_next;
- }
+ if (p_head_) {
+ p_block = p_head_;
+ p_head_ = p_head_->p_next;
}
return (void*)p_block;
@@ -119,8 +114,8 @@ class FixedBlockAllocator {
const std::size_t max_objects_;
Block* p_head_;
- uint8_t* p_pool_;
- uint32_t pool_index_;
+ uint32_t current_pool_index_;
+ std::list<typename std::aligned_storage<SIZE>::type*> p_pools_;
uint32_t block_count_;
uint32_t blocks_in_use_;
uint32_t allocations_;
@@ -133,4 +128,88 @@ template <std::size_t A, std::size_t B>
std::unique_ptr<FixedBlockAllocator<A, B>>
FixedBlockAllocator<A, B>::instance_ = nullptr;
+/**
+ * STL Allocator trait to be used with allocate_shared.
+ */
+template <typename T, typename Pool>
+class STLAllocator {
+ /**
+ * If STLAllocator is rebound to another type (!= T) using copy constructor,
+ * we may need to access private members of the source allocator to copy
+ * memory and pool.
+ */
+ template <typename U, typename P>
+ friend class STLAllocator;
+
+ public:
+ using size_type = std::size_t;
+ using difference_type = ptrdiff_t;
+ using pointer = T*;
+ using const_pointer = const T*;
+ using reference = T&;
+ using const_reference = const T&;
+ using value_type = T;
+
+ STLAllocator(pointer memory, Pool* memory_pool)
+ : memory_(memory), pool_(memory_pool) {
+ TRANSPORT_LOGV("Creating allocator. This: %p, memory: %p, memory_pool: %p",
+ this, memory, memory_pool);
+ }
+
+ ~STLAllocator() {}
+
+ template <typename U>
+ STLAllocator(const STLAllocator<U, Pool>& other) {
+ memory_ = other.memory_;
+ pool_ = other.pool_;
+ }
+
+ template <typename U>
+ struct rebind {
+ typedef STLAllocator<U, Pool> other;
+ };
+
+ pointer address(reference x) const { return &x; }
+ const_pointer address(const_reference x) const { return &x; }
+
+ pointer allocate(size_type n, pointer hint = 0) {
+ TRANSPORT_LOGV(
+ "Allocating memory (%zu). This: %p, memory: %p, memory_pool: %p", n,
+ this, memory_, pool_);
+ return static_cast<pointer>(memory_);
+ }
+
+ void deallocate(pointer p, size_type n) {
+ TRANSPORT_LOGV("Deallocating memory. This: %p, memory: %p, memory_pool: %p",
+ this, memory_, pool_);
+ pool_->deallocateBlock(memory_);
+ }
+
+ template <typename... Args>
+ void construct(pointer p, Args&&... args) {
+ new (static_cast<pointer>(p)) T(std::forward<Args>(args)...);
+ }
+
+ void destroy(pointer p) {
+ TRANSPORT_LOGV("Destroying object. This: %p, memory: %p, memory_pool: %p",
+ this, memory_, pool_);
+ p->~T();
+ }
+
+ private:
+ void* memory_;
+ Pool* pool_;
+};
+
+template <typename T, typename U, typename V>
+inline bool operator==(const STLAllocator<T, V>&, const STLAllocator<U, V>&) {
+ return true;
+}
+
+template <typename T, typename U, typename V>
+inline bool operator!=(const STLAllocator<T, V>& a,
+ const STLAllocator<U, V>& b) {
+ return !(a == b);
+}
+
} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/linux.h b/libtransport/includes/hicn/transport/utils/linux.h
index 5820528..105196f 100644
--- a/libtransport/includes/hicn/transport/utils/linux.h
+++ b/libtransport/includes/hicn/transport/utils/linux.h
@@ -17,14 +17,14 @@
#ifdef __linux__
+#include <arpa/inet.h>
#include <hicn/transport/portability/portability.h>
#include <hicn/transport/utils/log.h>
-
-#include <arpa/inet.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <stdio.h>
#include <sys/socket.h>
+
#include <string>
#define LINK_LOCAL_PREFIX 0xfe80
diff --git a/libtransport/includes/hicn/transport/utils/membuf.h b/libtransport/includes/hicn/transport/utils/membuf.h
index 9fc37dd..0db87e9 100644
--- a/libtransport/includes/hicn/transport/utils/membuf.h
+++ b/libtransport/includes/hicn/transport/utils/membuf.h
@@ -23,6 +23,7 @@
#include <hicn/transport/portability/portability.h>
#include <hicn/transport/utils/branch_prediction.h>
+#include <stdlib.h>
#include <atomic>
#include <cassert>
@@ -35,8 +36,6 @@
#include <type_traits>
#include <vector>
-#include <stdlib.h>
-
#ifndef _WIN32
TRANSPORT_GNU_DISABLE_WARNING("-Wshadow")
#endif
@@ -50,6 +49,8 @@ class MemBuf {
enum TakeOwnershipOp { TAKE_OWNERSHIP };
enum CopyBufferOp { COPY_BUFFER };
+ using Ptr = std::shared_ptr<MemBuf>;
+
typedef void (*FreeFunction)(void* buf, void* userData);
static std::unique_ptr<MemBuf> create(std::size_t capacity);
@@ -106,13 +107,14 @@ class MemBuf {
FreeFunction freeFn = nullptr, void* userData = nullptr,
bool freeOnError = true);
- static std::unique_ptr<MemBuf> wrapBuffer(const void* buf,
+ static std::unique_ptr<MemBuf> wrapBuffer(const void* buf, std::size_t length,
std::size_t capacity);
- static MemBuf wrapBufferAsValue(const void* buf,
+ static MemBuf wrapBufferAsValue(const void* buf, std::size_t length,
std::size_t capacity) noexcept;
- MemBuf(WrapBufferOp op, const void* buf, std::size_t capacity) noexcept;
+ MemBuf(WrapBufferOp op, const void* buf, std::size_t length,
+ std::size_t capacity) noexcept;
/**
* Convenience function to create a new MemBuf object that copies data from a
@@ -147,6 +149,8 @@ class MemBuf {
std::size_t length() const { return length_; }
+ void setLength(std::size_t length) { length_ = length; }
+
std::size_t headroom() const { return std::size_t(data_ - buffer()); }
std::size_t tailroom() const { return std::size_t(bufferEnd() - tail()); }
@@ -689,6 +693,18 @@ class MemBuf {
void* userData = nullptr,
bool freeOnError = true);
+ /**
+ * Ensure the current MemBuf can hold at least capacity bytes and its
+ * memory is contiguous
+ */
+ bool ensureCapacity(std::size_t capacity);
+
+ /**
+ * Ensure packet buffer can hold at least 1500 bytes in contiguous memory and
+ * fill unused memory with placeholder
+ */
+ bool ensureCapacityAndFillUnused(std::size_t capacity, uint8_t placeholder);
+
/*
* Overridden operator new and delete.
* These perform specialized memory management to help support
@@ -700,6 +716,12 @@ class MemBuf {
void operator delete(void* ptr);
void operator delete(void* ptr, void* placement);
+ /**
+ * Override operator == and !=
+ */
+ bool operator ==(const MemBuf &other);
+ bool operator !=(const MemBuf &other);
+
// /**
// * Iteration support: a chain of MemBufs may be iterated through using
// * STL-style iterators over const ByteRanges. Iterators are only
diff --git a/libtransport/includes/hicn/transport/utils/move_wrapper.h b/libtransport/includes/hicn/transport/utils/move_wrapper.h
new file mode 100644
index 0000000..3aba345
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/move_wrapper.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright 2017 Facebook, Inc.
+ *
+ * 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 <type_traits>
+
+namespace utils {
+
+template <typename F>
+struct MoveWrapper : F {
+ MoveWrapper(F&& f) : F(std::move(f)) {}
+
+ MoveWrapper(MoveWrapper&&) = default;
+ MoveWrapper& operator=(MoveWrapper&&) = default;
+
+ MoveWrapper(const MoveWrapper&);
+ MoveWrapper& operator=(const MoveWrapper&);
+};
+
+template <typename T>
+auto moveHandler(T&& t) -> MoveWrapper<typename std::decay<T>::type> {
+ return std::move(t);
+}
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/noncopyable.h b/libtransport/includes/hicn/transport/utils/noncopyable.h
new file mode 100644
index 0000000..83923e6
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/noncopyable.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace utils {
+
+class NonCopyable {
+ protected:
+ NonCopyable() = default;
+ ~NonCopyable() = default;
+
+ NonCopyable(const NonCopyable&) = delete;
+ NonCopyable& operator=(const NonCopyable&) = delete;
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/object_pool.h b/libtransport/includes/hicn/transport/utils/object_pool.h
index f78bd2a..a5e8b2e 100644
--- a/libtransport/includes/hicn/transport/utils/object_pool.h
+++ b/libtransport/includes/hicn/transport/utils/object_pool.h
@@ -17,6 +17,7 @@
// TODO
#include <hicn/transport/utils/branch_prediction.h>
+#include <hicn/transport/utils/log.h>
#include <hicn/transport/utils/spinlock.h>
#include <deque>
@@ -33,6 +34,7 @@ class ObjectPool {
void operator()(T *t) {
if (pool_) {
+ TRANSPORT_LOGV("Back in pool");
pool_->add(t);
} else {
delete t;
@@ -44,10 +46,13 @@ class ObjectPool {
};
public:
- using Ptr = std::unique_ptr<T, ObjectDeleter>;
+ using Ptr = std::shared_ptr<T>;
ObjectPool() : destructor_(false) {}
+ // No copies
+ ObjectPool(const ObjectPool &other) = delete;
+
~ObjectPool() {
destructor_ = true;
for (auto &ptr : object_pool_) {
@@ -55,12 +60,17 @@ class ObjectPool {
}
}
+ bool empty() {
+ utils::SpinLock::Acquire locked(object_pool_lock_);
+ return object_pool_.empty();
+ }
+
std::pair<bool, Ptr> get() {
+ utils::SpinLock::Acquire locked(object_pool_lock_);
if (object_pool_.empty()) {
- return std::make_pair<bool, Ptr>(false, makePtr(nullptr));
+ return std::make_pair<bool, Ptr>(false, nullptr);
}
- utils::SpinLock::Acquire locked(object_pool_lock_);
auto ret = std::move(object_pool_.front());
object_pool_.pop_front();
return std::make_pair<bool, Ptr>(true, std::move(ret));
@@ -70,7 +80,7 @@ class ObjectPool {
utils::SpinLock::Acquire locked(object_pool_lock_);
if (TRANSPORT_EXPECT_TRUE(!destructor_)) {
- object_pool_.emplace_back(makePtr(object));
+ object_pool_.emplace_front(makePtr(object));
} else {
delete object;
}
@@ -79,12 +89,9 @@ class ObjectPool {
Ptr makePtr(T *object) { return Ptr(object, ObjectDeleter(this)); }
private:
- // No copies
- ObjectPool(const ObjectPool &other) = delete;
-
utils::SpinLock object_pool_lock_;
std::deque<Ptr> object_pool_;
- bool destructor_;
+ std::atomic<bool> destructor_;
};
-} // namespace utils \ No newline at end of file
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h b/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h
new file mode 100644
index 0000000..3387997
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ */
+
+#pragma once
+
+#include <memory>
+
+namespace utils {
+
+template <typename Base>
+inline std::shared_ptr<Base> shared_from_base(
+ std::enable_shared_from_this<Base>* base) {
+ return base->shared_from_this();
+}
+
+template <typename Base>
+inline std::shared_ptr<const Base> shared_from_base(
+ std::enable_shared_from_this<Base> const* base) {
+ return base->shared_from_this();
+}
+
+template <typename That>
+inline std::shared_ptr<That> shared_from(That* that) {
+ return std::static_pointer_cast<That>(shared_from_base(that));
+}
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/singleton.h b/libtransport/includes/hicn/transport/utils/singleton.h
new file mode 100644
index 0000000..7fd8b91
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/singleton.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/utils/noncopyable.h>
+
+namespace utils {
+
+template <typename T>
+class Singleton {
+ public:
+ static T& getInstance() {
+ static T instance;
+ return instance;
+ }
+
+ protected:
+ Singleton() {}
+ ~Singleton() {}
+
+ public:
+ Singleton(Singleton const&) = delete;
+ Singleton& operator=(Singleton const&) = delete;
+};
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/string_utils.h b/libtransport/includes/hicn/transport/utils/string_utils.h
index bfda816..313c28c 100644
--- a/libtransport/includes/hicn/transport/utils/string_utils.h
+++ b/libtransport/includes/hicn/transport/utils/string_utils.h
@@ -72,4 +72,4 @@ static inline std::string trim_copy(std::string s) {
return s;
}
-} \ No newline at end of file
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/src/CMakeLists.txt b/libtransport/src/CMakeLists.txt
index 33497e0..0fa9bbe 100644
--- a/libtransport/src/CMakeLists.txt
+++ b/libtransport/src/CMakeLists.txt
@@ -20,7 +20,7 @@ set(ASIO_STANDALONE 1)
add_subdirectory(core)
add_subdirectory(interfaces)
add_subdirectory(protocols)
-add_subdirectory(security)
+add_subdirectory(auth)
add_subdirectory(implementation)
add_subdirectory(utils)
add_subdirectory(http)
@@ -34,7 +34,16 @@ install(
COMPONENT lib${LIBTRANSPORT}-dev
)
-set (COMPILER_DEFINITIONS "-DTRANSPORT_LOG_DEF_LEVEL=TRANSPORT_LOG_${TRANSPORT_LOG_LEVEL}")
+install(
+ FILES "transport.config"
+ DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/hicn
+ COMPONENT lib${LIBTRANSPORT}
+)
+
+list(APPEND COMPILER_DEFINITIONS
+ "-DTRANSPORT_LOG_DEF_LEVEL=TRANSPORT_LOG_${TRANSPORT_LOG_LEVEL}"
+ "-DASIO_STANDALONE"
+)
list(INSERT LIBTRANSPORT_INTERNAL_INCLUDE_DIRS 0
${CMAKE_CURRENT_SOURCE_DIR}/
@@ -55,8 +64,10 @@ else ()
set(CMAKE_SHARED_LINKER_FLAGS "/NODEFAULTLIB:\"MSVCRTD\"" )
endif ()
endif ()
-if (${CMAKE_SYSTEM_NAME} STREQUAL "Android")
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Android")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -isystem -lm")
+ add_subdirectory(io_modules)
endif()
if (DISABLE_SHARED_LIBRARIES)
@@ -68,8 +79,9 @@ if (DISABLE_SHARED_LIBRARIES)
DEPENDS ${DEPENDENCIES}
COMPONENT lib${LIBTRANSPORT}
INCLUDE_DIRS ${LIBTRANSPORT_INCLUDE_DIRS} ${LIBTRANSPORT_INTERNAL_INCLUDE_DIRS}
- INSTALL_ROOT_DIR hicn/transport
+ HEADER_ROOT_DIR hicn/transport
DEFINITIONS ${COMPILER_DEFINITIONS}
+ VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}
)
else ()
build_library(${LIBTRANSPORT}
@@ -80,11 +92,17 @@ else ()
DEPENDS ${DEPENDENCIES}
COMPONENT lib${LIBTRANSPORT}
INCLUDE_DIRS ${LIBTRANSPORT_INCLUDE_DIRS} ${LIBTRANSPORT_INTERNAL_INCLUDE_DIRS}
- INSTALL_ROOT_DIR hicn/transport
+ HEADER_ROOT_DIR hicn/transport
DEFINITIONS ${COMPILER_DEFINITIONS}
+ VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}
)
endif ()
+# io modules
+if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Android")
+ add_subdirectory(io_modules)
+endif()
+
if (${BUILD_TESTS})
add_subdirectory(test)
endif()
diff --git a/libtransport/src/auth/CMakeLists.txt b/libtransport/src/auth/CMakeLists.txt
new file mode 100644
index 0000000..0e7b583
--- /dev/null
+++ b/libtransport/src/auth/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (c) 2017-2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/signer.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/verifier.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/identity.cc
+)
+
+set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
diff --git a/libtransport/src/auth/identity.cc b/libtransport/src/auth/identity.cc
new file mode 100644
index 0000000..bd787b9
--- /dev/null
+++ b/libtransport/src/auth/identity.cc
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/auth/identity.h>
+
+using namespace std;
+
+namespace transport {
+namespace auth {
+
+Identity::Identity(const string &keystore_path, const string &keystore_pwd,
+ CryptoSuite suite, unsigned int signature_len,
+ unsigned int validity_days, const string &subject_name)
+ : identity_(nullptr), signer_(nullptr) {
+ parcSecurity_Init();
+
+ bool success = parcPkcs12KeyStore_CreateFile(
+ keystore_path.c_str(), keystore_pwd.c_str(), subject_name.c_str(),
+ parcCryptoSuite_GetSigningAlgorithm(static_cast<PARCCryptoSuite>(suite)),
+ signature_len, validity_days);
+
+ parcAssertTrue(
+ success,
+ "parcPkcs12KeyStore_CreateFile('%s', '%s', '%s', %d, %d, %d) failed.",
+ keystore_path.c_str(), keystore_pwd.c_str(), subject_name.c_str(),
+ static_cast<int>(suite), static_cast<int>(signature_len), validity_days);
+
+ PARCIdentityFile *identity_file =
+ parcIdentityFile_Create(keystore_path.c_str(), keystore_pwd.c_str());
+
+ identity_ =
+ parcIdentity_Create(identity_file, PARCIdentityFileAsPARCIdentity);
+
+ PARCSigner *signer = parcIdentity_CreateSigner(
+ identity_,
+ parcCryptoSuite_GetCryptoHash(static_cast<PARCCryptoSuite>(suite)));
+
+ signer_ = make_shared<AsymmetricSigner>(signer);
+
+ parcSigner_Release(&signer);
+ parcIdentityFile_Release(&identity_file);
+}
+
+Identity::Identity(string &keystore_path, string &keystore_pwd,
+ CryptoHashType hash_type)
+ : identity_(nullptr), signer_(nullptr) {
+ parcSecurity_Init();
+
+ PARCIdentityFile *identity_file =
+ parcIdentityFile_Create(keystore_path.c_str(), keystore_pwd.c_str());
+
+ identity_ =
+ parcIdentity_Create(identity_file, PARCIdentityFileAsPARCIdentity);
+
+ PARCSigner *signer = parcIdentity_CreateSigner(
+ identity_, static_cast<PARCCryptoHashType>(hash_type));
+
+ signer_ = make_shared<AsymmetricSigner>(signer);
+
+ parcSigner_Release(&signer);
+ parcIdentityFile_Release(&identity_file);
+}
+
+Identity::Identity(const Identity &other)
+ : identity_(nullptr), signer_(other.signer_) {
+ parcSecurity_Init();
+ identity_ = parcIdentity_Acquire(other.identity_);
+}
+
+Identity::Identity(Identity &&other)
+ : identity_(nullptr), signer_(move(other.signer_)) {
+ parcSecurity_Init();
+ identity_ = parcIdentity_Acquire(other.identity_);
+ parcIdentity_Release(&other.identity_);
+}
+
+Identity::~Identity() {
+ if (identity_) parcIdentity_Release(&identity_);
+ parcSecurity_Fini();
+}
+
+shared_ptr<AsymmetricSigner> Identity::getSigner() const { return signer_; }
+
+string Identity::getFilename() const {
+ return string(parcIdentity_GetFileName(identity_));
+}
+
+string Identity::getPassword() const {
+ return string(parcIdentity_GetPassWord(identity_));
+}
+
+Identity Identity::generateIdentity(const string &subject_name) {
+ string keystore_name = "keystore";
+ string keystore_password = "password";
+ size_t key_length = 1024;
+ unsigned int validity_days = 30;
+ CryptoSuite suite = CryptoSuite::RSA_SHA256;
+
+ return Identity(keystore_name, keystore_password, suite,
+ (unsigned int)key_length, validity_days, subject_name);
+}
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/src/auth/signer.cc b/libtransport/src/auth/signer.cc
new file mode 100644
index 0000000..281b9c5
--- /dev/null
+++ b/libtransport/src/auth/signer.cc
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2017-2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/auth/signer.h>
+
+extern "C" {
+#ifndef _WIN32
+TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat")
+#endif
+#include <hicn/hicn.h>
+}
+
+#include <chrono>
+
+#define ALLOW_UNALIGNED_READS 1
+
+using namespace std;
+
+namespace transport {
+namespace auth {
+
+Signer::Signer() : signer_(nullptr), key_id_(nullptr) { parcSecurity_Init(); }
+
+Signer::Signer(PARCSigner *signer) : Signer() { setSigner(signer); }
+
+Signer::~Signer() {
+ if (signer_) parcSigner_Release(&signer_);
+ if (key_id_) parcKeyId_Release(&key_id_);
+ parcSecurity_Fini();
+}
+
+void Signer::signPacket(PacketPtr packet) {
+ parcAssertNotNull(signer_, "Expected non-null signer");
+
+ const utils::MemBuf &header_chain = *packet;
+ core::Packet::Format format = packet->getFormat();
+ auto suite = getCryptoSuite();
+ size_t signature_len = getSignatureSize();
+
+ if (!packet->authenticationHeader()) {
+ throw errors::MalformedAHPacketException();
+ }
+
+ packet->setSignatureSize(signature_len);
+
+ // Copy IP+TCP / ICMP header before zeroing them
+ hicn_header_t header_copy;
+ hicn_packet_copy_header(format, packet->packet_start_, &header_copy, false);
+ packet->resetForHash();
+
+ // Fill in the HICN_AH header
+ auto now = chrono::duration_cast<chrono::milliseconds>(
+ chrono::system_clock::now().time_since_epoch())
+ .count();
+ packet->setSignatureTimestamp(now);
+ packet->setValidationAlgorithm(suite);
+
+ // Set the key ID
+ KeyId key_id;
+ key_id.first = static_cast<uint8_t *>(
+ parcBuffer_Overlay((PARCBuffer *)parcKeyId_GetKeyId(key_id_), 0));
+ packet->setKeyId(key_id);
+
+ // Calculate hash
+ CryptoHasher hasher(parcSigner_GetCryptoHasher(signer_));
+ const utils::MemBuf *current = &header_chain;
+
+ hasher.init();
+
+ do {
+ hasher.updateBytes(current->data(), current->length());
+ current = current->next();
+ } while (current != &header_chain);
+
+ CryptoHash hash = hasher.finalize();
+
+ // Compute signature
+ PARCSignature *signature = parcSigner_SignDigestNoAlloc(
+ signer_, hash.hash_, packet->getSignature(), signature_len);
+ PARCBuffer *buffer = parcSignature_GetSignature(signature);
+ size_t bytes_len = parcBuffer_Remaining(buffer);
+
+ if (bytes_len > signature_len) {
+ throw errors::MalformedAHPacketException();
+ }
+
+ // Put signature in AH header
+ hicn_packet_copy_header(format, &header_copy, packet->packet_start_, false);
+
+ // Release allocated objects
+ parcSignature_Release(&signature);
+}
+
+void Signer::setSigner(PARCSigner *signer) {
+ parcAssertNotNull(signer, "Expected non-null signer");
+
+ if (signer_) parcSigner_Release(&signer_);
+ if (key_id_) parcKeyId_Release(&key_id_);
+
+ signer_ = parcSigner_Acquire(signer);
+ key_id_ = parcSigner_CreateKeyId(signer_);
+}
+
+size_t Signer::getSignatureSize() const {
+ parcAssertNotNull(signer_, "Expected non-null signer");
+ return parcSigner_GetSignatureSize(signer_);
+}
+
+CryptoSuite Signer::getCryptoSuite() const {
+ parcAssertNotNull(signer_, "Expected non-null signer");
+ return static_cast<CryptoSuite>(parcSigner_GetCryptoSuite(signer_));
+}
+
+CryptoHashType Signer::getCryptoHashType() const {
+ parcAssertNotNull(signer_, "Expected non-null signer");
+ return static_cast<CryptoHashType>(parcSigner_GetCryptoHashType(signer_));
+}
+
+PARCSigner *Signer::getParcSigner() const { return signer_; }
+
+PARCKeyStore *Signer::getParcKeyStore() const {
+ parcAssertNotNull(signer_, "Expected non-null signer");
+ return parcSigner_GetKeyStore(signer_);
+}
+
+AsymmetricSigner::AsymmetricSigner(CryptoSuite suite, PARCKeyStore *key_store) {
+ parcAssertNotNull(key_store, "Expected non-null key_store");
+
+ auto crypto_suite = static_cast<PARCCryptoSuite>(suite);
+
+ switch (suite) {
+ case CryptoSuite::DSA_SHA256:
+ case CryptoSuite::RSA_SHA256:
+ case CryptoSuite::RSA_SHA512:
+ case CryptoSuite::ECDSA_256K1:
+ break;
+ default:
+ throw errors::RuntimeException(
+ "Invalid crypto suite for asymmetric signer");
+ }
+
+ setSigner(
+ parcSigner_Create(parcPublicKeySigner_Create(key_store, crypto_suite),
+ PARCPublicKeySignerAsSigner));
+}
+
+SymmetricSigner::SymmetricSigner(CryptoSuite suite, PARCKeyStore *key_store) {
+ parcAssertNotNull(key_store, "Expected non-null key_store");
+
+ auto crypto_suite = static_cast<PARCCryptoSuite>(suite);
+
+ switch (suite) {
+ case CryptoSuite::HMAC_SHA256:
+ case CryptoSuite::HMAC_SHA512:
+ break;
+ default:
+ throw errors::RuntimeException(
+ "Invalid crypto suite for symmetric signer");
+ }
+
+ setSigner(parcSigner_Create(parcSymmetricKeySigner_Create(
+ (PARCSymmetricKeyStore *)key_store,
+ parcCryptoSuite_GetCryptoHash(crypto_suite)),
+ PARCSymmetricKeySignerAsSigner));
+}
+
+SymmetricSigner::SymmetricSigner(CryptoSuite suite, const string &passphrase) {
+ auto crypto_suite = static_cast<PARCCryptoSuite>(suite);
+
+ switch (suite) {
+ case CryptoSuite::HMAC_SHA256:
+ case CryptoSuite::HMAC_SHA512:
+ break;
+ default:
+ throw errors::RuntimeException(
+ "Invalid crypto suite for symmetric signer");
+ }
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_PutString(composer, passphrase.c_str());
+ PARCBuffer *key_buf = parcBufferComposer_ProduceBuffer(composer);
+ parcBufferComposer_Release(&composer);
+
+ PARCSymmetricKeyStore *key_store = parcSymmetricKeyStore_Create(key_buf);
+ PARCSymmetricKeySigner *key_signer = parcSymmetricKeySigner_Create(
+ key_store, parcCryptoSuite_GetCryptoHash(crypto_suite));
+
+ setSigner(parcSigner_Create(key_signer, PARCSymmetricKeySignerAsSigner));
+
+ parcSymmetricKeySigner_Release(&key_signer);
+ parcSymmetricKeyStore_Release(&key_store);
+ parcBuffer_Release(&key_buf);
+}
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/src/auth/verifier.cc b/libtransport/src/auth/verifier.cc
new file mode 100644
index 0000000..c6648a7
--- /dev/null
+++ b/libtransport/src/auth/verifier.cc
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2017-2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/auth/verifier.h>
+#include <protocols/errors.h>
+
+extern "C" {
+#ifndef _WIN32
+TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat")
+#endif
+#include <hicn/hicn.h>
+}
+
+#include <sys/stat.h>
+
+using namespace std;
+
+namespace transport {
+namespace auth {
+
+const std::vector<VerificationPolicy> Verifier::DEFAULT_FAILED_POLICIES = {
+ VerificationPolicy::DROP,
+ VerificationPolicy::ABORT,
+};
+
+Verifier::Verifier()
+ : hasher_(nullptr),
+ verifier_(nullptr),
+ verification_failed_cb_(interface::VOID_HANDLER),
+ failed_policies_(DEFAULT_FAILED_POLICIES) {
+ parcSecurity_Init();
+ PARCInMemoryVerifier *in_memory_verifier = parcInMemoryVerifier_Create();
+ verifier_ =
+ parcVerifier_Create(in_memory_verifier, PARCInMemoryVerifierAsVerifier);
+ parcInMemoryVerifier_Release(&in_memory_verifier);
+}
+
+Verifier::~Verifier() {
+ if (hasher_) parcCryptoHasher_Release(&hasher_);
+ if (verifier_) parcVerifier_Release(&verifier_);
+ parcSecurity_Fini();
+}
+
+bool Verifier::verifyPacket(PacketPtr packet) {
+ bool valid_packet = false;
+ core::Packet::Format format = packet->getFormat();
+
+ if (!packet->authenticationHeader()) {
+ throw errors::MalformedAHPacketException();
+ }
+
+ // Get crypto suite and hash type
+ auto suite = static_cast<PARCCryptoSuite>(packet->getValidationAlgorithm());
+ PARCCryptoHashType hash_type = parcCryptoSuite_GetCryptoHash(suite);
+
+ // Copy IP+TCP / ICMP header before zeroing them
+ hicn_header_t header_copy;
+ hicn_packet_copy_header(format, packet->packet_start_, &header_copy, false);
+
+ // Fetch packet signature
+ uint8_t *packet_signature = packet->getSignature();
+ size_t signature_len = Verifier::getSignatureSize(packet);
+ vector<uint8_t> signature_raw(packet_signature,
+ packet_signature + signature_len);
+
+ // Create a signature buffer from the raw packet signature
+ PARCBuffer *bits =
+ parcBuffer_Wrap(signature_raw.data(), signature_len, 0, signature_len);
+ parcBuffer_Rewind(bits);
+
+ // If the signature algo is ECDSA, the signature might be shorter than the
+ // signature field
+ PARCSigningAlgorithm algo = parcCryptoSuite_GetSigningAlgorithm(suite);
+ if (algo == PARCSigningAlgorithm_ECDSA) {
+ while (parcBuffer_HasRemaining(bits) && parcBuffer_GetUint8(bits) == 0)
+ ;
+ parcBuffer_SetPosition(bits, parcBuffer_Position(bits) - 1);
+ }
+
+ if (!parcBuffer_HasRemaining(bits)) {
+ parcBuffer_Release(&bits);
+ return false;
+ }
+
+ // Create a signature object from the signature buffer
+ PARCSignature *signature = parcSignature_Create(
+ parcCryptoSuite_GetSigningAlgorithm(suite), hash_type, bits);
+
+ // Fetch the key to verify the signature
+ KeyId key_buffer = packet->getKeyId();
+ PARCBuffer *buffer = parcBuffer_Wrap(key_buffer.first, key_buffer.second, 0,
+ key_buffer.second);
+ PARCKeyId *key_id = parcKeyId_Create(buffer);
+
+ // Reset fields that are not used to compute signature
+ packet->resetForHash();
+
+ // Compute the packet hash
+ if (!hasher_)
+ setHasher(parcVerifier_GetCryptoHasher(verifier_, key_id, hash_type));
+ CryptoHash local_hash = computeHash(packet);
+
+ // Compare the packet signature to the locally computed one
+ valid_packet = parcVerifier_VerifyDigestSignature(
+ verifier_, key_id, local_hash.hash_, suite, signature);
+
+ // Restore the fields that were reset
+ hicn_packet_copy_header(format, &header_copy, packet->packet_start_, false);
+
+ // Release allocated objects
+ parcBuffer_Release(&buffer);
+ parcKeyId_Release(&key_id);
+ parcSignature_Release(&signature);
+ parcBuffer_Release(&bits);
+
+ return valid_packet;
+}
+
+vector<VerificationPolicy> Verifier::verifyPackets(
+ const vector<PacketPtr> &packets) {
+ vector<VerificationPolicy> policies(packets.size(), VerificationPolicy::DROP);
+
+ for (unsigned int i = 0; i < packets.size(); ++i) {
+ if (verifyPacket(packets[i])) {
+ policies[i] = VerificationPolicy::ACCEPT;
+ }
+
+ callVerificationFailedCallback(packets[i], policies[i]);
+ }
+
+ return policies;
+}
+
+vector<VerificationPolicy> Verifier::verifyPackets(
+ const vector<PacketPtr> &packets,
+ const unordered_map<Suffix, HashEntry> &suffix_map) {
+ vector<VerificationPolicy> policies(packets.size(),
+ VerificationPolicy::UNKNOWN);
+
+ for (unsigned int i = 0; i < packets.size(); ++i) {
+ uint32_t suffix = packets[i]->getName().getSuffix();
+ auto manifest_hash = suffix_map.find(suffix);
+
+ if (manifest_hash != suffix_map.end()) {
+ CryptoHashType hash_type = manifest_hash->second.first;
+ CryptoHash packet_hash = packets[i]->computeDigest(hash_type);
+
+ if (!CryptoHash::compareBinaryDigest(
+ packet_hash.getDigest<uint8_t>().data(),
+ manifest_hash->second.second.data(), hash_type)) {
+ policies[i] = VerificationPolicy::ABORT;
+ } else {
+ policies[i] = VerificationPolicy::ACCEPT;
+ }
+ }
+
+ callVerificationFailedCallback(packets[i], policies[i]);
+ }
+
+ return policies;
+}
+
+void Verifier::addKey(PARCKey *key) { parcVerifier_AddKey(verifier_, key); }
+
+void Verifier::setHasher(PARCCryptoHasher *hasher) {
+ parcAssertNotNull(hasher, "Expected non-null hasher");
+ if (hasher_) parcCryptoHasher_Release(&hasher_);
+ hasher_ = parcCryptoHasher_Acquire(hasher);
+}
+
+void Verifier::setVerificationFailedCallback(
+ VerificationFailedCallback verfication_failed_cb,
+ const vector<VerificationPolicy> &failed_policies) {
+ verification_failed_cb_ = verfication_failed_cb;
+ failed_policies_ = failed_policies;
+}
+
+void Verifier::getVerificationFailedCallback(
+ VerificationFailedCallback **verfication_failed_cb) {
+ *verfication_failed_cb = &verification_failed_cb_;
+}
+
+size_t Verifier::getSignatureSize(const PacketPtr packet) {
+ return packet->getSignatureSize();
+}
+
+CryptoHash Verifier::computeHash(PacketPtr packet) {
+ parcAssertNotNull(hasher_, "Expected non-null hasher");
+
+ CryptoHasher crypto_hasher(hasher_);
+ const utils::MemBuf &header_chain = *packet;
+ const utils::MemBuf *current = &header_chain;
+
+ crypto_hasher.init();
+
+ do {
+ crypto_hasher.updateBytes(current->data(), current->length());
+ current = current->next();
+ } while (current != &header_chain);
+
+ return crypto_hasher.finalize();
+}
+
+void Verifier::callVerificationFailedCallback(PacketPtr packet,
+ VerificationPolicy &policy) {
+ if (verification_failed_cb_ == interface::VOID_HANDLER) {
+ return;
+ }
+
+ if (find(failed_policies_.begin(), failed_policies_.end(), policy) !=
+ failed_policies_.end()) {
+ policy = verification_failed_cb_(
+ static_cast<const core::ContentObject &>(*packet),
+ make_error_code(
+ protocol::protocol_error::signature_verification_failed));
+ }
+}
+
+bool VoidVerifier::verifyPacket(PacketPtr packet) { return true; }
+
+vector<VerificationPolicy> VoidVerifier::verifyPackets(
+ const vector<PacketPtr> &packets) {
+ return vector<VerificationPolicy>(packets.size(), VerificationPolicy::ACCEPT);
+}
+
+vector<VerificationPolicy> VoidVerifier::verifyPackets(
+ const vector<PacketPtr> &packets,
+ const unordered_map<Suffix, HashEntry> &suffix_map) {
+ return vector<VerificationPolicy>(packets.size(), VerificationPolicy::ACCEPT);
+}
+
+AsymmetricVerifier::AsymmetricVerifier(PARCKey *pub_key) { addKey(pub_key); }
+
+AsymmetricVerifier::AsymmetricVerifier(const string &cert_path) {
+ setCertificate(cert_path);
+}
+
+void AsymmetricVerifier::setCertificate(const string &cert_path) {
+ PARCCertificateFactory *factory = parcCertificateFactory_Create(
+ PARCCertificateType_X509, PARCContainerEncoding_PEM);
+
+ struct stat buffer;
+ if (stat(cert_path.c_str(), &buffer) != 0) {
+ throw errors::RuntimeException("Certificate does not exist");
+ }
+
+ PARCCertificate *certificate =
+ parcCertificateFactory_CreateCertificateFromFile(factory,
+ cert_path.c_str(), NULL);
+ PARCKey *key = parcCertificate_GetPublicKey(certificate);
+
+ addKey(key);
+
+ parcKey_Release(&key);
+ parcCertificateFactory_Release(&factory);
+}
+
+SymmetricVerifier::SymmetricVerifier(const string &passphrase)
+ : passphrase_(nullptr), signer_(nullptr) {
+ setPassphrase(passphrase);
+}
+
+SymmetricVerifier::~SymmetricVerifier() {
+ if (passphrase_) parcBuffer_Release(&passphrase_);
+ if (signer_) parcSigner_Release(&signer_);
+}
+
+void SymmetricVerifier::setPassphrase(const string &passphrase) {
+ if (passphrase_) parcBuffer_Release(&passphrase_);
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_PutString(composer, passphrase.c_str());
+ passphrase_ = parcBufferComposer_ProduceBuffer(composer);
+ parcBufferComposer_Release(&composer);
+}
+
+void SymmetricVerifier::setSigner(const PARCCryptoSuite &suite) {
+ parcAssertNotNull(passphrase_, "Expected non-null passphrase");
+
+ if (signer_) parcSigner_Release(&signer_);
+
+ PARCSymmetricKeyStore *key_store = parcSymmetricKeyStore_Create(passphrase_);
+ PARCSymmetricKeySigner *key_signer = parcSymmetricKeySigner_Create(
+ key_store, parcCryptoSuite_GetCryptoHash(suite));
+ signer_ = parcSigner_Create(key_signer, PARCSymmetricKeySignerAsSigner);
+
+ PARCKeyId *key_id = parcSigner_CreateKeyId(signer_);
+ PARCKey *key = parcKey_CreateFromSymmetricKey(
+ key_id, parcSigner_GetSigningAlgorithm(signer_), passphrase_);
+
+ addKey(key);
+ setHasher(parcSigner_GetCryptoHasher(signer_));
+
+ parcSymmetricKeyStore_Release(&key_store);
+ parcSymmetricKeySigner_Release(&key_signer);
+ parcKeyId_Release(&key_id);
+ parcKey_Release(&key);
+}
+
+vector<VerificationPolicy> SymmetricVerifier::verifyPackets(
+ const vector<PacketPtr> &packets) {
+ vector<VerificationPolicy> policies(packets.size(), VerificationPolicy::DROP);
+
+ for (unsigned int i = 0; i < packets.size(); ++i) {
+ auto suite =
+ static_cast<PARCCryptoSuite>(packets[i]->getValidationAlgorithm());
+
+ if (!signer_ || suite != parcSigner_GetCryptoSuite(signer_)) {
+ setSigner(suite);
+ }
+
+ if (verifyPacket(packets[i])) {
+ policies[i] = VerificationPolicy::ACCEPT;
+ }
+
+ callVerificationFailedCallback(packets[i], policies[i]);
+ }
+
+ return policies;
+}
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/src/config.h.in b/libtransport/src/config.h.in
index 4e9a0f2..ef47aff 100644
--- a/libtransport/src/config.h.in
+++ b/libtransport/src/config.h.in
@@ -25,10 +25,6 @@
#cmakedefine ASIO_STANDALONE
#endif
-#ifndef SECURE_HICNTRANSPORT
-#cmakedefine SECURE_HICNTRANSPORT
-#endif
-
#define RAAQM_CONFIG_PATH "@raaqm_config_path@"
#cmakedefine __vpp__
diff --git a/libtransport/src/core/CMakeLists.txt b/libtransport/src/core/CMakeLists.txt
index 5c8ab92..4e3ac10 100644
--- a/libtransport/src/core/CMakeLists.txt
+++ b/libtransport/src/core/CMakeLists.txt
@@ -21,55 +21,27 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/manifest_format.h
${CMAKE_CURRENT_SOURCE_DIR}/pending_interest.h
${CMAKE_CURRENT_SOURCE_DIR}/portal.h
- ${CMAKE_CURRENT_SOURCE_DIR}/connector.h
- ${CMAKE_CURRENT_SOURCE_DIR}/tcp_socket_connector.h
- ${CMAKE_CURRENT_SOURCE_DIR}/udp_socket_connector.h
- ${CMAKE_CURRENT_SOURCE_DIR}/forwarder_interface.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn_forwarder_interface.h
- ${CMAKE_CURRENT_SOURCE_DIR}/vpp_forwarder_interface.h
- ${CMAKE_CURRENT_SOURCE_DIR}/memif_connector.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/errors.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/global_configuration.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/local_connector.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/rs.h
)
list(APPEND SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/content_object.cc
${CMAKE_CURRENT_SOURCE_DIR}/interest.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/errors.cc
${CMAKE_CURRENT_SOURCE_DIR}/packet.cc
${CMAKE_CURRENT_SOURCE_DIR}/name.cc
${CMAKE_CURRENT_SOURCE_DIR}/prefix.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/tcp_socket_connector.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/udp_socket_connector.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn_forwarder_interface.cc
${CMAKE_CURRENT_SOURCE_DIR}/manifest_format_fixed.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/connector.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/portal.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/global_configuration.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/io_module.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/local_connector.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/fec.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/rs.cc
)
-if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
- if (BUILD_WITH_VPP OR BUILD_HICNPLUGIN)
- list(APPEND HEADER_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/vpp_forwarder_interface.h
- ${CMAKE_CURRENT_SOURCE_DIR}/memif_connector.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn_vapi.h
- ${CMAKE_CURRENT_SOURCE_DIR}/memif_vapi.h
- )
-
- list(APPEND SOURCE_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/vpp_forwarder_interface.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/memif_connector.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn_vapi.c
- ${CMAKE_CURRENT_SOURCE_DIR}/memif_vapi.c
- )
- endif()
-
- list(APPEND HEADER_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/raw_socket_connector.h
- ${CMAKE_CURRENT_SOURCE_DIR}/raw_socket_interface.h
- )
-
- list(APPEND SOURCE_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/raw_socket_connector.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/raw_socket_interface.cc
- )
-endif()
-
set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/src/core/content_object.cc b/libtransport/src/core/content_object.cc
index f5cccf4..0c68ef5 100644
--- a/libtransport/src/core/content_object.cc
+++ b/libtransport/src/core/content_object.cc
@@ -32,8 +32,9 @@ namespace transport {
namespace core {
-ContentObject::ContentObject(const Name &name, Packet::Format format)
- : Packet(format) {
+ContentObject::ContentObject(const Name &name, Packet::Format format,
+ std::size_t additional_header_size)
+ : Packet(format, additional_header_size) {
if (TRANSPORT_EXPECT_FALSE(
hicn_data_set_name(format, packet_start_, &name.name_) < 0)) {
throw errors::RuntimeException("Error filling the packet name.");
@@ -47,41 +48,32 @@ ContentObject::ContentObject(const Name &name, Packet::Format format)
}
#ifdef __ANDROID__
-ContentObject::ContentObject(hicn_format_t format)
- : ContentObject(Name("0::0|0"), format) {}
+ContentObject::ContentObject(hicn_format_t format,
+ std::size_t additional_header_size)
+ : ContentObject(Name("0::0|0"), format, additional_header_size) {}
#else
-ContentObject::ContentObject(hicn_format_t format)
- : ContentObject(Packet::base_name, format) {}
+ContentObject::ContentObject(hicn_format_t format,
+ std::size_t additional_header_size)
+ : ContentObject(Packet::base_name, format, additional_header_size) {}
#endif
ContentObject::ContentObject(const Name &name, hicn_format_t format,
+ std::size_t additional_header_size,
const uint8_t *payload, std::size_t size)
- : ContentObject(name, format) {
+ : ContentObject(name, format, additional_header_size) {
appendPayload(payload, size);
}
-ContentObject::ContentObject(const uint8_t *buffer, std::size_t size)
- : Packet(buffer, size) {
- if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
- 0) {
- throw errors::RuntimeException("Error getting name from content object.");
- }
+ContentObject::ContentObject(ContentObject &&other) : Packet(std::move(other)) {
+ name_ = std::move(other.name_);
}
-ContentObject::ContentObject(MemBufPtr &&buffer) : Packet(std::move(buffer)) {
- if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
- 0) {
- throw errors::RuntimeException("Error getting name from content object.");
- }
+ContentObject::ContentObject(const ContentObject &other) : Packet(other) {
+ name_ = other.name_;
}
-ContentObject::ContentObject(ContentObject &&other) : Packet(std::move(other)) {
- name_ = std::move(other.name_);
-
- if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
- 0) {
- throw errors::MalformedPacketException();
- }
+ContentObject &ContentObject::operator=(const ContentObject &other) {
+ return (ContentObject &)Packet::operator=(other);
}
ContentObject::~ContentObject() {}
@@ -132,10 +124,11 @@ uint32_t ContentObject::getPathLabel() const {
"Error retrieving the path label from content object");
}
- return path_label;
+ return ntohl(path_label);
}
ContentObject &ContentObject::setPathLabel(uint32_t path_label) {
+ path_label = htonl(path_label);
if (hicn_data_set_path_label((hicn_header_t *)packet_start_, path_label) <
0) {
throw errors::RuntimeException(
diff --git a/libtransport/src/core/errors.cc b/libtransport/src/core/errors.cc
new file mode 100644
index 0000000..82647a6
--- /dev/null
+++ b/libtransport/src/core/errors.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core/errors.h>
+
+namespace transport {
+namespace core {
+
+const std::error_category& core_category() {
+ static core_category_impl instance;
+
+ return instance;
+}
+
+const char* core_category_impl::name() const throw() {
+ return "transport::protocol::error";
+}
+
+std::string core_category_impl::message(int ev) const {
+ switch (static_cast<core_error>(ev)) {
+ case core_error::success: {
+ return "Success";
+ }
+ case core_error::configuration_parse_failed: {
+ return "Error parsing configuration.";
+ }
+ case core_error::configuration_not_applied: {
+ return "Configuration was not applied due to wrong parameters.";
+ }
+ default: {
+ return "Unknown core error";
+ }
+ }
+}
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/core/errors.h b/libtransport/src/core/errors.h
new file mode 100644
index 0000000..a46f1db
--- /dev/null
+++ b/libtransport/src/core/errors.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <system_error>
+
+namespace transport {
+namespace core {
+
+/**
+ * @brief Get the default server error category.
+ * @return The default server error category instance.
+ *
+ * @warning The first call to this function is thread-safe only starting with
+ * C++11.
+ */
+const std::error_category& core_category();
+
+/**
+ * The list of errors.
+ */
+enum class core_error {
+ success = 0,
+ configuration_parse_failed,
+ configuration_not_applied
+};
+
+/**
+ * @brief Create an error_code instance for the given error.
+ * @param error The error.
+ * @return The error_code instance.
+ */
+inline std::error_code make_error_code(core_error error) {
+ return std::error_code(static_cast<int>(error), core_category());
+}
+
+/**
+ * @brief Create an error_condition instance for the given error.
+ * @param error The error.
+ * @return The error_condition instance.
+ */
+inline std::error_condition make_error_condition(core_error error) {
+ return std::error_condition(static_cast<int>(error), core_category());
+}
+
+/**
+ * @brief A server error category.
+ */
+class core_category_impl : public std::error_category {
+ public:
+ /**
+ * @brief Get the name of the category.
+ * @return The name of the category.
+ */
+ virtual const char* name() const throw();
+
+ /**
+ * @brief Get the error message for a given error.
+ * @param ev The error numeric value.
+ * @return The message associated to the error.
+ */
+ virtual std::string message(int ev) const;
+};
+} // namespace core
+} // namespace transport
+
+namespace std {
+// namespace system {
+template <>
+struct is_error_code_enum<::transport::core::core_error>
+ : public std::true_type {};
+// } // namespace system
+} // namespace std \ No newline at end of file
diff --git a/libtransport/src/core/facade.h b/libtransport/src/core/facade.h
index 04f643f..1990812 100644
--- a/libtransport/src/core/facade.h
+++ b/libtransport/src/core/facade.h
@@ -15,36 +15,14 @@
#pragma once
-#include <core/forwarder_interface.h>
-#include <core/hicn_forwarder_interface.h>
#include <core/manifest_format_fixed.h>
#include <core/manifest_inline.h>
#include <core/portal.h>
-#ifdef __linux__
-#ifndef __ANDROID__
-#include <core/raw_socket_interface.h>
-#ifdef __vpp__
-#include <core/vpp_forwarder_interface.h>
-#endif
-#endif
-#endif
-
namespace transport {
namespace core {
-using HicnForwarderPortal = Portal<HicnForwarderInterface>;
-
-#ifdef __linux__
-#ifndef __ANDROID__
-using RawSocketPortal = Portal<RawSocketInterface>;
-#endif
-#ifdef __vpp__
-using VPPForwarderPortal = Portal<VPPForwarderInterface>;
-#endif
-#endif
-
using ContentObjectManifest = core::ManifestInline<ContentObject, Fixed>;
using InterestManifest = core::ManifestInline<Interest, Fixed>;
diff --git a/libtransport/src/core/fec.cc b/libtransport/src/core/fec.cc
new file mode 100644
index 0000000..134198b
--- /dev/null
+++ b/libtransport/src/core/fec.cc
@@ -0,0 +1,878 @@
+/*
+ * fec.c -- forward error correction based on Vandermonde matrices
+ * 980624
+ * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)
+ *
+ * Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
+ * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
+ * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+/*
+ * The following parameter defines how many bits are used for
+ * field elements. The code supports any value from 2 to 16
+ * but fastest operation is achieved with 8 bit elements
+ * This is the only parameter you may want to change.
+ */
+#ifndef GF_BITS
+#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <hicn/transport/portability/platform.h>
+#include "fec.h"
+
+/**
+ * XXX This disable a warning raising only in some platforms.
+ * TODO Check if this warning is a mistake or it is a real bug:
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83404
+ * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=88059
+ */
+#ifndef __clang__
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+#endif
+
+/*
+ * compatibility stuff
+ */
+#ifdef MSDOS /* but also for others, e.g. sun... */
+#define NEED_BCOPY
+#define bcmp(a,b,n) memcmp(a,b,n)
+#endif
+
+#ifdef ANDROID
+#define bcmp(a,b,n) memcmp(a,b,n)
+#endif
+
+#ifdef NEED_BCOPY
+#define bcopy(s, d, siz) memcpy((d), (s), (siz))
+#define bzero(d, siz) memset((d), '\0', (siz))
+#endif
+
+/*
+ * stuff used for testing purposes only
+ */
+
+#ifdef TEST
+#define DEB(x)
+#define DDB(x) x
+#define DEBUG 0 /* minimal debugging */
+#ifdef MSDOS
+#include <time.h>
+struct timeval {
+ unsigned long ticks;
+};
+#define gettimeofday(x, dummy) { (x)->ticks = clock() ; }
+#define DIFF_T(a,b) (1+ 1000000*(a.ticks - b.ticks) / CLOCKS_PER_SEC )
+typedef unsigned long u_long ;
+typedef unsigned short u_short ;
+#else /* typically, unix systems */
+#include <sys/time.h>
+#define DIFF_T(a,b) \
+ (1+ 1000000*(a.tv_sec - b.tv_sec) + (a.tv_usec - b.tv_usec) )
+#endif
+
+#define TICK(t) \
+ {struct timeval x ; \
+ gettimeofday(&x, NULL) ; \
+ t = x.tv_usec + 1000000* (x.tv_sec & 0xff ) ; \
+ }
+#define TOCK(t) \
+ { u_long t1 ; TICK(t1) ; \
+ if (t1 < t) t = 256000000 + t1 - t ; \
+ else t = t1 - t ; \
+ if (t == 0) t = 1 ;}
+
+u_long ticks[10]; /* vars for timekeeping */
+#else
+#define DEB(x)
+#define DDB(x)
+#define TICK(x)
+#define TOCK(x)
+#endif /* TEST */
+
+/*
+ * You should not need to change anything beyond this point.
+ * The first part of the file implements linear algebra in GF.
+ *
+ * gf is the type used to store an element of the Galois Field.
+ * Must constain at least GF_BITS bits.
+ *
+ * Note: unsigned char will work up to GF(256) but int seems to run
+ * faster on the Pentium. We use int whenever have to deal with an
+ * index, since they are generally faster.
+ */
+#if (GF_BITS < 2 && GF_BITS >16)
+#error "GF_BITS must be 2 .. 16"
+#endif
+
+
+#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */
+
+/*
+ * Primitive polynomials - see Lin & Costello, Appendix A,
+ * and Lee & Messerschmitt, p. 453.
+ */
+static const char *allPp[] = { /* GF_BITS polynomial */
+ NULL, /* 0 no code */
+ NULL, /* 1 no code */
+ "111", /* 2 1+x+x^2 */
+ "1101", /* 3 1+x+x^3 */
+ "11001", /* 4 1+x+x^4 */
+ "101001", /* 5 1+x^2+x^5 */
+ "1100001", /* 6 1+x+x^6 */
+ "10010001", /* 7 1 + x^3 + x^7 */
+ "101110001", /* 8 1+x^2+x^3+x^4+x^8 */
+ "1000100001", /* 9 1+x^4+x^9 */
+ "10010000001", /* 10 1+x^3+x^10 */
+ "101000000001", /* 11 1+x^2+x^11 */
+ "1100101000001", /* 12 1+x+x^4+x^6+x^12 */
+ "11011000000001", /* 13 1+x+x^3+x^4+x^13 */
+ "110000100010001", /* 14 1+x+x^6+x^10+x^14 */
+ "1100000000000001", /* 15 1+x+x^15 */
+ "11010000000010001" /* 16 1+x+x^3+x^12+x^16 */
+};
+
+
+/*
+ * To speed up computations, we have tables for logarithm, exponent
+ * and inverse of a number. If GF_BITS <= 8, we use a table for
+ * multiplication as well (it takes 64K, no big deal even on a PDA,
+ * especially because it can be pre-initialized an put into a ROM!),
+ * otherwhise we use a table of logarithms.
+ * In any case the macro gf_mul(x,y) takes care of multiplications.
+ */
+
+static gf gf_exp[2*GF_SIZE]; /* index->poly form conversion table */
+static int gf_log[GF_SIZE + 1]; /* Poly->index form conversion table */
+static gf inverse[GF_SIZE+1]; /* inverse of field elem. */
+ /* inv[\alpha**i]=\alpha**(GF_SIZE-i-1) */
+
+/*
+ * modnn(x) computes x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1,
+ * without a slow divide.
+ */
+static inline gf
+modnn(int x)
+{
+ while (x >= GF_SIZE) {
+ x -= GF_SIZE;
+ x = (x >> GF_BITS) + (x & GF_SIZE);
+ }
+ return x;
+}
+
+#define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;}
+
+/*
+ * gf_mul(x,y) multiplies two numbers. If GF_BITS<=8, it is much
+ * faster to use a multiplication table.
+ *
+ * USE_GF_MULC, GF_MULC0(c) and GF_ADDMULC(x) can be used when multiplying
+ * many numbers by the same constant. In this case the first
+ * call sets the constant, and others perform the multiplications.
+ * A value related to the multiplication is held in a local variable
+ * declared with USE_GF_MULC . See usage in addmul1().
+ */
+#if (GF_BITS <= 8)
+static gf gf_mul_table[GF_SIZE + 1][GF_SIZE + 1];
+
+#define gf_mul(x,y) gf_mul_table[x][y]
+
+#define USE_GF_MULC gf * __gf_mulc_
+#define GF_MULC0(c) __gf_mulc_ = gf_mul_table[c]
+#define GF_ADDMULC(dst, x) dst ^= __gf_mulc_[x]
+
+static void
+init_mul_table()
+{
+ int i, j;
+ for (i=0; i< GF_SIZE+1; i++)
+ for (j=0; j< GF_SIZE+1; j++)
+ gf_mul_table[i][j] = gf_exp[modnn(gf_log[i] + gf_log[j]) ] ;
+
+ for (j=0; j< GF_SIZE+1; j++)
+ gf_mul_table[0][j] = gf_mul_table[j][0] = 0;
+}
+#else /* GF_BITS > 8 */
+static inline gf
+gf_mul(x,y)
+{
+ if ( (x) == 0 || (y)==0 ) return 0;
+
+ return gf_exp[gf_log[x] + gf_log[y] ] ;
+}
+#define init_mul_table()
+
+#define USE_GF_MULC register gf * __gf_mulc_
+#define GF_MULC0(c) __gf_mulc_ = &gf_exp[ gf_log[c] ]
+#define GF_ADDMULC(dst, x) { if (x) dst ^= __gf_mulc_[ gf_log[x] ] ; }
+#endif
+
+/*
+ * Generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m]
+ * Lookup tables:
+ * index->polynomial form gf_exp[] contains j= \alpha^i;
+ * polynomial form -> index form gf_log[ j = \alpha^i ] = i
+ * \alpha=x is the primitive element of GF(2^m)
+ *
+ * For efficiency, gf_exp[] has size 2*GF_SIZE, so that a simple
+ * multiplication of two numbers can be resolved without calling modnn
+ */
+
+/*
+ * i use malloc so many times, it is easier to put checks all in
+ * one place.
+ */
+static void *
+my_malloc(int sz, const char *err_string)
+{
+ void *p = malloc( sz );
+ if (p == NULL) {
+ fprintf(stderr, "-- malloc failure allocating %s\n", err_string);
+ exit(1) ;
+ }
+ return p ;
+}
+
+#define NEW_GF_MATRIX(rows, cols) \
+ (gf *)my_malloc(rows * cols * sizeof(gf), " ## __LINE__ ## " )
+
+/*
+ * initialize the data structures used for computations in GF.
+ */
+static void
+generate_gf(void)
+{
+ int i;
+ gf mask;
+ const char *Pp = allPp[GF_BITS] ;
+
+ mask = 1; /* x ** 0 = 1 */
+ gf_exp[GF_BITS] = 0; /* will be updated at the end of the 1st loop */
+ /*
+ * first, generate the (polynomial representation of) powers of \alpha,
+ * which are stored in gf_exp[i] = \alpha ** i .
+ * At the same time build gf_log[gf_exp[i]] = i .
+ * The first GF_BITS powers are simply bits shifted to the left.
+ */
+ for (i = 0; i < GF_BITS; i++, mask <<= 1 ) {
+ gf_exp[i] = mask;
+ gf_log[gf_exp[i]] = i;
+ /*
+ * If Pp[i] == 1 then \alpha ** i occurs in poly-repr
+ * gf_exp[GF_BITS] = \alpha ** GF_BITS
+ */
+ if ( Pp[i] == '1' )
+ gf_exp[GF_BITS] ^= mask;
+ }
+ /*
+ * now gf_exp[GF_BITS] = \alpha ** GF_BITS is complete, so can als
+ * compute its inverse.
+ */
+ gf_log[gf_exp[GF_BITS]] = GF_BITS;
+ /*
+ * Poly-repr of \alpha ** (i+1) is given by poly-repr of
+ * \alpha ** i shifted left one-bit and accounting for any
+ * \alpha ** GF_BITS term that may occur when poly-repr of
+ * \alpha ** i is shifted.
+ */
+ mask = 1 << (GF_BITS - 1 ) ;
+ for (i = GF_BITS + 1; i < GF_SIZE; i++) {
+ if (gf_exp[i - 1] >= mask)
+ gf_exp[i] = gf_exp[GF_BITS] ^ ((gf_exp[i - 1] ^ mask) << 1);
+ else
+ gf_exp[i] = gf_exp[i - 1] << 1;
+ gf_log[gf_exp[i]] = i;
+ }
+ /*
+ * log(0) is not defined, so use a special value
+ */
+ gf_log[0] = GF_SIZE ;
+ /* set the extended gf_exp values for fast multiply */
+ for (i = 0 ; i < GF_SIZE ; i++)
+ gf_exp[i + GF_SIZE] = gf_exp[i] ;
+
+ /*
+ * again special cases. 0 has no inverse. This used to
+ * be initialized to GF_SIZE, but it should make no difference
+ * since noone is supposed to read from here.
+ */
+ inverse[0] = 0 ;
+ inverse[1] = 1;
+ for (i=2; i<=GF_SIZE; i++)
+ inverse[i] = gf_exp[GF_SIZE-gf_log[i]];
+}
+
+/*
+ * Various linear algebra operations that i use often.
+ */
+
+/*
+ * addmul() computes dst[] = dst[] + c * src[]
+ * This is used often, so better optimize it! Currently the loop is
+ * unrolled 16 times, a good value for 486 and pentium-class machines.
+ * The case c=0 is also optimized, whereas c=1 is not. These
+ * calls are unfrequent in my typical apps so I did not bother.
+ *
+ * Note that gcc on
+ */
+#define addmul(dst, src, c, sz) \
+ if (c != 0) addmul1(dst, src, c, sz)
+
+#define UNROLL 16 /* 1, 4, 8, 16 */
+static void
+addmul1(gf *dst1, gf *src1, gf c, int sz)
+{
+ USE_GF_MULC ;
+ gf *dst = dst1, *src = src1 ;
+ gf *lim = &dst[sz - UNROLL + 1] ;
+
+ GF_MULC0(c) ;
+
+#if (UNROLL > 1) /* unrolling by 8/16 is quite effective on the pentium */
+ for (; dst < lim ; dst += UNROLL, src += UNROLL ) {
+ GF_ADDMULC( dst[0] , src[0] );
+ GF_ADDMULC( dst[1] , src[1] );
+ GF_ADDMULC( dst[2] , src[2] );
+ GF_ADDMULC( dst[3] , src[3] );
+#if (UNROLL > 4)
+ GF_ADDMULC( dst[4] , src[4] );
+ GF_ADDMULC( dst[5] , src[5] );
+ GF_ADDMULC( dst[6] , src[6] );
+ GF_ADDMULC( dst[7] , src[7] );
+#endif
+#if (UNROLL > 8)
+ GF_ADDMULC( dst[8] , src[8] );
+ GF_ADDMULC( dst[9] , src[9] );
+ GF_ADDMULC( dst[10] , src[10] );
+ GF_ADDMULC( dst[11] , src[11] );
+ GF_ADDMULC( dst[12] , src[12] );
+ GF_ADDMULC( dst[13] , src[13] );
+ GF_ADDMULC( dst[14] , src[14] );
+ GF_ADDMULC( dst[15] , src[15] );
+#endif
+ }
+#endif
+ lim += UNROLL - 1 ;
+ for (; dst < lim; dst++, src++ ) /* final components */
+ GF_ADDMULC( *dst , *src );
+}
+
+/*
+ * computes C = AB where A is n*k, B is k*m, C is n*m
+ */
+static void
+matmul(gf *a, gf *b, gf *c, int n, int k, int m)
+{
+ int row, col, i ;
+
+ for (row = 0; row < n ; row++) {
+ for (col = 0; col < m ; col++) {
+ gf *pa = &a[ row * k ];
+ gf *pb = &b[ col ];
+ gf acc = 0 ;
+ for (i = 0; i < k ; i++, pa++, pb += m )
+ acc ^= gf_mul( *pa, *pb ) ;
+ c[ row * m + col ] = acc ;
+ }
+ }
+}
+
+#ifdef DEBUGG
+/*
+ * returns 1 if the square matrix is identiy
+ * (only for test)
+ */
+static int
+is_identity(gf *m, int k)
+{
+ int row, col ;
+ for (row=0; row<k; row++)
+ for (col=0; col<k; col++)
+ if ( (row==col && *m != 1) ||
+ (row!=col && *m != 0) )
+ return 0 ;
+ else
+ m++ ;
+ return 1 ;
+}
+#endif /* debug */
+
+/*
+ * invert_mat() takes a matrix and produces its inverse
+ * k is the size of the matrix.
+ * (Gauss-Jordan, adapted from Numerical Recipes in C)
+ * Return non-zero if singular.
+ */
+DEB( int pivloops=0; int pivswaps=0 ; /* diagnostic */)
+static int
+invert_mat(gf *src, int k)
+{
+ gf c, *p ;
+ int irow, icol, row, col, i, ix ;
+
+ int error = 1 ;
+ int *indxc = (int*)my_malloc(k*sizeof(int), "indxc");
+ int *indxr = (int*)my_malloc(k*sizeof(int), "indxr");
+ int *ipiv = (int*)my_malloc(k*sizeof(int), "ipiv");
+ gf *id_row = NEW_GF_MATRIX(1, k);
+ gf *temp_row = NEW_GF_MATRIX(1, k);
+
+ bzero(id_row, k*sizeof(gf));
+ DEB( pivloops=0; pivswaps=0 ; /* diagnostic */ )
+ /*
+ * ipiv marks elements already used as pivots.
+ */
+ for (i = 0; i < k ; i++)
+ ipiv[i] = 0 ;
+
+ for (col = 0; col < k ; col++) {
+ gf *pivot_row ;
+ /*
+ * Zeroing column 'col', look for a non-zero element.
+ * First try on the diagonal, if it fails, look elsewhere.
+ */
+ irow = icol = -1 ;
+ if (ipiv[col] != 1 && src[col*k + col] != 0) {
+ irow = col ;
+ icol = col ;
+ goto found_piv ;
+ }
+ for (row = 0 ; row < k ; row++) {
+ if (ipiv[row] != 1) {
+ for (ix = 0 ; ix < k ; ix++) {
+ DEB( pivloops++ ; )
+ if (ipiv[ix] == 0) {
+ if (src[row*k + ix] != 0) {
+ irow = row ;
+ icol = ix ;
+ goto found_piv ;
+ }
+ } else if (ipiv[ix] > 1) {
+ fprintf(stderr, "singular matrix\n");
+ goto fail ;
+ }
+ }
+ }
+ }
+ if (icol == -1) {
+ fprintf(stderr, "XXX pivot not found!\n");
+ goto fail ;
+ }
+found_piv:
+ ++(ipiv[icol]) ;
+ /*
+ * swap rows irow and icol, so afterwards the diagonal
+ * element will be correct. Rarely done, not worth
+ * optimizing.
+ */
+ if (irow != icol) {
+ for (ix = 0 ; ix < k ; ix++ ) {
+ SWAP( src[irow*k + ix], src[icol*k + ix], gf) ;
+ }
+ }
+ indxr[col] = irow ;
+ indxc[col] = icol ;
+ pivot_row = &src[icol*k] ;
+ c = pivot_row[icol] ;
+ if (c == 0) {
+ fprintf(stderr, "singular matrix 2\n");
+ goto fail ;
+ }
+ if (c != 1 ) { /* otherwhise this is a NOP */
+ /*
+ * this is done often , but optimizing is not so
+ * fruitful, at least in the obvious ways (unrolling)
+ */
+ DEB( pivswaps++ ; )
+ c = inverse[ c ] ;
+ pivot_row[icol] = 1 ;
+ for (ix = 0 ; ix < k ; ix++ )
+ pivot_row[ix] = gf_mul(c, pivot_row[ix] );
+ }
+ /*
+ * from all rows, remove multiples of the selected row
+ * to zero the relevant entry (in fact, the entry is not zero
+ * because we know it must be zero).
+ * (Here, if we know that the pivot_row is the identity,
+ * we can optimize the addmul).
+ */
+ id_row[icol] = 1;
+ if (bcmp(pivot_row, id_row, k*sizeof(gf)) != 0) {
+ for (p = src, ix = 0 ; ix < k ; ix++, p += k ) {
+ if (ix != icol) {
+ c = p[icol] ;
+ p[icol] = 0 ;
+ addmul(p, pivot_row, c, k );
+ }
+ }
+ }
+ id_row[icol] = 0;
+ } /* done all columns */
+ for (col = k-1 ; col >= 0 ; col-- ) {
+ if (indxr[col] <0 || indxr[col] >= k)
+ fprintf(stderr, "AARGH, indxr[col] %d\n", indxr[col]);
+ else if (indxc[col] <0 || indxc[col] >= k)
+ fprintf(stderr, "AARGH, indxc[col] %d\n", indxc[col]);
+ else
+ if (indxr[col] != indxc[col] ) {
+ for (row = 0 ; row < k ; row++ ) {
+ SWAP( src[row*k + indxr[col]], src[row*k + indxc[col]], gf) ;
+ }
+ }
+ }
+ error = 0 ;
+fail:
+ free(indxc);
+ free(indxr);
+ free(ipiv);
+ free(id_row);
+ free(temp_row);
+ return error ;
+}
+
+/*
+ * fast code for inverting a vandermonde matrix.
+ * XXX NOTE: It assumes that the matrix
+ * is not singular and _IS_ a vandermonde matrix. Only uses
+ * the second column of the matrix, containing the p_i's.
+ *
+ * Algorithm borrowed from "Numerical recipes in C" -- sec.2.8, but
+ * largely revised for my purposes.
+ * p = coefficients of the matrix (p_i)
+ * q = values of the polynomial (known)
+ */
+
+int
+invert_vdm(gf *src, int k)
+{
+ int i, j, row, col ;
+ gf *b, *c, *p;
+ gf t, xx ;
+
+ if (k == 1) /* degenerate case, matrix must be p^0 = 1 */
+ return 0 ;
+ /*
+ * c holds the coefficient of P(x) = Prod (x - p_i), i=0..k-1
+ * b holds the coefficient for the matrix inversion
+ */
+ c = NEW_GF_MATRIX(1, k);
+ b = NEW_GF_MATRIX(1, k);
+
+ p = NEW_GF_MATRIX(1, k);
+
+ for ( j=1, i = 0 ; i < k ; i++, j+=k ) {
+ c[i] = 0 ;
+ p[i] = src[j] ; /* p[i] */
+ }
+ /*
+ * construct coeffs. recursively. We know c[k] = 1 (implicit)
+ * and start P_0 = x - p_0, then at each stage multiply by
+ * x - p_i generating P_i = x P_{i-1} - p_i P_{i-1}
+ * After k steps we are done.
+ */
+ c[k-1] = p[0] ; /* really -p(0), but x = -x in GF(2^m) */
+ for (i = 1 ; i < k ; i++ ) {
+ gf p_i = p[i] ; /* see above comment */
+ for (j = k-1 - ( i - 1 ) ; j < k-1 ; j++ )
+ c[j] ^= gf_mul( p_i, c[j+1] ) ;
+ c[k-1] ^= p_i ;
+ }
+
+ for (row = 0 ; row < k ; row++ ) {
+ /*
+ * synthetic division etc.
+ */
+ xx = p[row] ;
+ t = 1 ;
+ b[k-1] = 1 ; /* this is in fact c[k] */
+ for (i = k-2 ; i >= 0 ; i-- ) {
+ b[i] = c[i+1] ^ gf_mul(xx, b[i+1]) ;
+ t = gf_mul(xx, t) ^ b[i] ;
+ }
+ for (col = 0 ; col < k ; col++ )
+ src[col*k + row] = gf_mul(inverse[t], b[col] );
+ }
+ free(c) ;
+ free(b) ;
+ free(p) ;
+ return 0 ;
+}
+
+static int fec_initialized = 0 ;
+static void
+init_fec()
+{
+ TICK(ticks[0]);
+ generate_gf();
+ TOCK(ticks[0]);
+ DDB(fprintf(stderr, "generate_gf took %ldus\n", ticks[0]);)
+ TICK(ticks[0]);
+ init_mul_table();
+ TOCK(ticks[0]);
+ DDB(fprintf(stderr, "init_mul_table took %ldus\n", ticks[0]);)
+ fec_initialized = 1 ;
+}
+
+/*
+ * This section contains the proper FEC encoding/decoding routines.
+ * The encoding matrix is computed starting with a Vandermonde matrix,
+ * and then transforming it into a systematic matrix.
+ */
+
+#define FEC_MAGIC 0xFECC0DEC
+
+void
+fec_free(struct fec_parms *p)
+{
+ if (p==NULL ||
+ p->magic != ( ( (FEC_MAGIC ^ p->k) ^ p->n) ^ (unsigned long)(p->enc_matrix)) ) {
+ fprintf(stderr, "bad parameters to fec_free\n");
+ return ;
+ }
+ free(p->enc_matrix);
+ free(p);
+}
+
+/*
+ * create a new encoder, returning a descriptor. This contains k,n and
+ * the encoding matrix.
+ */
+struct fec_parms *
+fec_new(int k, int n)
+{
+ int row, col ;
+ gf *p, *tmp_m ;
+
+ struct fec_parms *retval ;
+
+ if (fec_initialized == 0)
+ init_fec();
+
+ if (k > GF_SIZE + 1 || n > GF_SIZE + 1 || k > n ) {
+ fprintf(stderr, "Invalid parameters k %d n %d GF_SIZE %d\n",
+ k, n, GF_SIZE );
+ return NULL ;
+ }
+ retval = (struct fec_parms *)my_malloc(sizeof(struct fec_parms), "new_code");
+ retval->k = k ;
+ retval->n = n ;
+ retval->enc_matrix = NEW_GF_MATRIX(n, k);
+ retval->magic = ( ( FEC_MAGIC ^ k) ^ n) ^ (unsigned long)(retval->enc_matrix) ;
+ tmp_m = NEW_GF_MATRIX(n, k);
+ /*
+ * fill the matrix with powers of field elements, starting from 0.
+ * The first row is special, cannot be computed with exp. table.
+ */
+ tmp_m[0] = 1 ;
+ for (col = 1; col < k ; col++)
+ tmp_m[col] = 0 ;
+ for (p = tmp_m + k, row = 0; row < n-1 ; row++, p += k) {
+ for ( col = 0 ; col < k ; col ++ )
+ p[col] = gf_exp[modnn(row*col)];
+ }
+
+ /*
+ * quick code to build systematic matrix: invert the top
+ * k*k vandermonde matrix, multiply right the bottom n-k rows
+ * by the inverse, and construct the identity matrix at the top.
+ */
+ TICK(ticks[3]);
+ invert_vdm(tmp_m, k); /* much faster than invert_mat */
+ matmul(tmp_m + k*k, tmp_m, retval->enc_matrix + k*k, n - k, k, k);
+ /*
+ * the upper matrix is I so do not bother with a slow multiply
+ */
+ bzero(retval->enc_matrix, k*k*sizeof(gf) );
+ for (p = retval->enc_matrix, col = 0 ; col < k ; col++, p += k+1 )
+ *p = 1 ;
+ free(tmp_m);
+ TOCK(ticks[3]);
+
+ DDB(fprintf(stderr, "--- %ld us to build encoding matrix\n",
+ ticks[3]);)
+ DEB(pr_matrix(retval->enc_matrix, n, k, "encoding_matrix");)
+ return retval ;
+}
+
+/*
+ * fec_encode accepts as input pointers to n data packets of size sz,
+ * and produces as output a packet pointed to by fec, computed
+ * with index "index".
+ */
+void
+fec_encode(struct fec_parms *code, gf *src[], gf *fec, int index, int sz)
+{
+ int i, k = code->k ;
+ gf *p ;
+
+ if (GF_BITS > 8)
+ sz /= 2 ;
+
+ if (index < k)
+ bcopy(src[index], fec, sz*sizeof(gf) ) ;
+ else if (index < code->n) {
+ p = &(code->enc_matrix[index*k] );
+ bzero(fec, sz*sizeof(gf));
+ for (i = 0; i < k ; i++)
+ addmul(fec, src[i], p[i], sz ) ;
+ } else
+ fprintf(stderr, "Invalid index %d (max %d)\n",
+ index, code->n - 1 );
+}
+
+/*
+ * shuffle move src packets in their position
+ */
+static int
+shuffle(gf *pkt[], int index[], int k)
+{
+ int i;
+
+ for ( i = 0 ; i < k ; ) {
+ if (index[i] >= k || index[i] == i)
+ i++ ;
+ else {
+ /*
+ * put pkt in the right position (first check for conflicts).
+ */
+ int c = index[i] ;
+
+ if (index[c] == c) {
+ DEB(fprintf(stderr, "\nshuffle, error at %d\n", i);)
+ return 1 ;
+ }
+ SWAP(index[i], index[c], int) ;
+ SWAP(pkt[i], pkt[c], gf *) ;
+ }
+ }
+ DEB( /* just test that it works... */
+ for ( i = 0 ; i < k ; i++ ) {
+ if (index[i] < k && index[i] != i) {
+ fprintf(stderr, "shuffle: after\n");
+ for (i=0; i<k ; i++) fprintf(stderr, "%3d ", index[i]);
+ fprintf(stderr, "\n");
+ return 1 ;
+ }
+ }
+ )
+ return 0 ;
+}
+
+/*
+ * build_decode_matrix constructs the encoding matrix given the
+ * indexes. The matrix must be already allocated as
+ * a vector of k*k elements, in row-major order
+ */
+static gf *
+build_decode_matrix(struct fec_parms *code, gf *pkt[], int index[])
+{
+ int i , k = code->k ;
+ gf *p, *matrix = NEW_GF_MATRIX(k, k);
+
+ TICK(ticks[9]);
+ for (i = 0, p = matrix ; i < k ; i++, p += k ) {
+#if 1 /* this is simply an optimization, not very useful indeed */
+ if (index[i] < k) {
+ bzero(p, k*sizeof(gf) );
+ p[i] = 1 ;
+ } else
+#endif
+ if (index[i] < code->n )
+ bcopy( &(code->enc_matrix[index[i]*k]), p, k*sizeof(gf) );
+ else {
+ fprintf(stderr, "decode: invalid index %d (max %d)\n",
+ index[i], code->n - 1 );
+ free(matrix) ;
+ return NULL ;
+ }
+ }
+ TICK(ticks[9]);
+ if (invert_mat(matrix, k)) {
+ free(matrix);
+ matrix = NULL ;
+ }
+ TOCK(ticks[9]);
+ return matrix ;
+}
+
+/*
+ * fec_decode receives as input a vector of packets, the indexes of
+ * packets, and produces the correct vector as output.
+ *
+ * Input:
+ * code: pointer to code descriptor
+ * pkt: pointers to received packets. They are modified
+ * to store the output packets (in place)
+ * index: pointer to packet indexes (modified)
+ * sz: size of each packet
+ */
+int
+fec_decode(struct fec_parms *code, gf *pkt[], int index[], int sz)
+{
+ gf *m_dec ;
+ gf **new_pkt ;
+ int row, col , k = code->k ;
+
+ if (GF_BITS > 8)
+ sz /= 2 ;
+
+ if (shuffle(pkt, index, k)) /* error if true */
+ return 1 ;
+ m_dec = build_decode_matrix(code, pkt, index);
+
+ if (m_dec == NULL)
+ return 1 ; /* error */
+ /*
+ * do the actual decoding
+ */
+ new_pkt = (gf**)my_malloc (k * sizeof (gf * ), "new pkt pointers" );
+ for (row = 0 ; row < k ; row++ ) {
+ if (index[row] >= k) {
+ new_pkt[row] = (gf*) my_malloc (sz * sizeof (gf), "new pkt buffer" );
+ bzero(new_pkt[row], sz * sizeof(gf) ) ;
+ for (col = 0 ; col < k ; col++ )
+ addmul(new_pkt[row], pkt[col], m_dec[row*k + col], sz) ;
+ }
+ }
+ /*
+ * move pkts to their final destination
+ */
+ for (row = 0 ; row < k ; row++ ) {
+ if (index[row] >= k) {
+ bcopy(new_pkt[row], pkt[row], sz*sizeof(gf));
+ free(new_pkt[row]);
+ }
+ }
+ free(new_pkt);
+ free(m_dec);
+
+ return 0;
+}
diff --git a/libtransport/src/core/fec.h b/libtransport/src/core/fec.h
new file mode 100644
index 0000000..8234057
--- /dev/null
+++ b/libtransport/src/core/fec.h
@@ -0,0 +1,65 @@
+/*
+ * fec.c -- forward error correction based on Vandermonde matrices
+ * 980614
+ * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)
+ *
+ * Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
+ * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
+ * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+/*
+ * The following parameter defines how many bits are used for
+ * field elements. The code supports any value from 2 to 16
+ * but fastest operation is achieved with 8 bit elements
+ * This is the only parameter you may want to change.
+ */
+#ifndef GF_BITS
+#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */
+#endif
+
+#if (GF_BITS <= 8)
+typedef unsigned char gf;
+#else
+typedef unsigned short gf;
+#endif
+
+#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */
+
+struct fec_parms {
+ unsigned long magic ;
+ int k, n ; /* parameters of the code */
+ gf *enc_matrix ;
+};
+
+void fec_free(struct fec_parms *p) ;
+struct fec_parms *fec_new(int k, int n) ;
+
+void fec_encode(struct fec_parms *code, gf *src[], gf *fec, int index, int sz);
+int fec_decode(struct fec_parms *code, gf *pkt[], int index[], int sz);
+
+/* end of file */
diff --git a/libtransport/src/core/global_configuration.cc b/libtransport/src/core/global_configuration.cc
new file mode 100644
index 0000000..e0b6c04
--- /dev/null
+++ b/libtransport/src/core/global_configuration.cc
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core/global_configuration.h>
+#include <hicn/transport/core/connector.h>
+#include <hicn/transport/utils/log.h>
+
+#include <libconfig.h++>
+#include <map>
+
+namespace transport {
+namespace core {
+
+GlobalConfiguration::GlobalConfiguration() {}
+
+bool GlobalConfiguration::parseTransportConfig(const std::string& path) {
+ using namespace libconfig;
+ Config cfg;
+
+ try {
+ cfg.readFile(path.c_str());
+ } catch (const FileIOException& fioex) {
+ TRANSPORT_LOGE("I/O error while reading file.");
+ return false;
+ } catch (const ParseException& pex) {
+ TRANSPORT_LOGE("Parse error at %s:%d - %s", pex.getFile(), pex.getLine(),
+ pex.getError());
+ return false;
+ }
+
+ Setting& root = cfg.getRoot();
+
+ /**
+ * Iterate over sections. Best thing to do here would be to have other
+ * components of the program registering a callback here, to parse their
+ * section of the configuration file.
+ */
+ for (auto section = root.begin(); section != root.end(); section++) {
+ std::string name = section->getName();
+ std::error_code ec;
+ TRANSPORT_LOGD("Parsing Section: %s", name.c_str());
+
+ auto it = configuration_parsers_.find(name);
+ if (it != configuration_parsers_.end() && !it->second.first) {
+ TRANSPORT_LOGD("Found valid configuration parser");
+ it->second.second(*section, ec);
+ it->second.first = true;
+ }
+ }
+
+ return true;
+}
+
+void GlobalConfiguration::parseConfiguration(const std::string& path) {
+ // Check if an environment variable with the configuration path exists. COnf
+ // variable comes first.
+ std::unique_lock<std::mutex> lck(cp_mtx_);
+ if (const char* env_c = std::getenv(GlobalConfiguration::conf_file)) {
+ parseTransportConfig(env_c);
+ } else if (!path.empty()) {
+ conf_file_path_ = path;
+ parseTransportConfig(conf_file_path_);
+ } else {
+ TRANSPORT_LOGD(
+ "Called parseConfiguration but no configuration file was provided.");
+ }
+}
+
+void GlobalConfiguration::registerConfigurationSetter(
+ const std::string& key, const SetCallback& set_callback) {
+ std::unique_lock<std::mutex> lck(cp_mtx_);
+ if (configuration_setters_.find(key) != configuration_setters_.end()) {
+ TRANSPORT_LOGW(
+ "Trying to register configuration setter %s twice. Ignoring second "
+ "registration attempt.",
+ key.c_str());
+ } else {
+ configuration_setters_.emplace(key, set_callback);
+ }
+}
+
+void GlobalConfiguration::registerConfigurationGetter(
+ const std::string& key, const GetCallback& get_callback) {
+ std::unique_lock<std::mutex> lck(cp_mtx_);
+ if (configuration_getters_.find(key) != configuration_getters_.end()) {
+ TRANSPORT_LOGW(
+ "Trying to register configuration getter %s twice. Ignoring second "
+ "registration attempt.",
+ key.c_str());
+ } else {
+ configuration_getters_.emplace(key, get_callback);
+ }
+}
+
+void GlobalConfiguration::registerConfigurationParser(
+ const std::string& key, const ParserCallback& parser) {
+ std::unique_lock<std::mutex> lck(cp_mtx_);
+ if (configuration_parsers_.find(key) != configuration_parsers_.end()) {
+ TRANSPORT_LOGW(
+ "Trying to register configuration key %s twice. Ignoring second "
+ "registration attempt.",
+ key.c_str());
+ } else {
+ configuration_parsers_.emplace(key, std::make_pair(false, parser));
+
+ // Trigger a parsing of the configuration.
+ if (!conf_file_path_.empty()) {
+ parseTransportConfig(conf_file_path_);
+ }
+ }
+}
+
+void GlobalConfiguration::unregisterConfigurationParser(
+ const std::string& key) {
+ std::unique_lock<std::mutex> lck(cp_mtx_);
+ auto it = configuration_parsers_.find(key);
+ if (it != configuration_parsers_.end()) {
+ configuration_parsers_.erase(it);
+ }
+}
+
+void GlobalConfiguration::unregisterConfigurationSetter(
+ const std::string& key) {
+ std::unique_lock<std::mutex> lck(cp_mtx_);
+ auto it = configuration_setters_.find(key);
+ if (it != configuration_setters_.end()) {
+ configuration_setters_.erase(it);
+ }
+}
+
+void GlobalConfiguration::unregisterConfigurationGetter(
+ const std::string& key) {
+ std::unique_lock<std::mutex> lck(cp_mtx_);
+ auto it = configuration_getters_.find(key);
+ if (it != configuration_getters_.end()) {
+ configuration_getters_.erase(it);
+ }
+}
+
+void GlobalConfiguration::getConfiguration(
+ interface::global_config::ConfigurationObject& configuration_object,
+ std::error_code& ec) {
+ auto it = configuration_getters_.find(configuration_object.getKey());
+
+ if (it != configuration_getters_.end()) {
+ it->second(configuration_object, ec);
+ }
+}
+
+void GlobalConfiguration::setConfiguration(
+ const interface::global_config::ConfigurationObject& configuration_object,
+ std::error_code& ec) {
+ auto it = configuration_setters_.find(configuration_object.getKey());
+
+ if (it != configuration_setters_.end()) {
+ it->second(configuration_object, ec);
+ }
+}
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/core/global_configuration.h b/libtransport/src/core/global_configuration.h
new file mode 100644
index 0000000..dcc8d94
--- /dev/null
+++ b/libtransport/src/core/global_configuration.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/interfaces/global_conf_interface.h>
+#include <hicn/transport/utils/singleton.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <system_error>
+
+namespace libconfig {
+class Setting;
+}
+
+namespace transport {
+namespace core {
+
+/**
+ * Class holding workflow for global configuration.
+ * This class does not contains the actual configuration, which is rather stored
+ * inside the modules to be configured. This class contains the handlers to call
+ * for getting/setting the configurations and to parse the corresponding
+ * sections of the configuration file. Each class register 3 callbacks: one to
+ * parse conf section and 2 to set/get the configuration through programming
+ * interface.
+ */
+class GlobalConfiguration : public utils::Singleton<GlobalConfiguration> {
+ static const constexpr char *conf_file = "TRANSPORT_CONFIG";
+ friend class utils::Singleton<GlobalConfiguration>;
+
+ public:
+ /**
+ * This callback will be called by GlobalConfiguration in
+ *
+ */
+ using ParserCallback = std::function<void(const libconfig::Setting &config,
+ std::error_code &ec)>;
+ using GetCallback =
+ std::function<void(interface::global_config::ConfigurationObject &object,
+ std::error_code &ec)>;
+
+ using SetCallback = std::function<void(
+ const interface::global_config::ConfigurationObject &object,
+ std::error_code &ec)>;
+
+ ~GlobalConfiguration() = default;
+
+ public:
+ void parseConfiguration(const std::string &path);
+
+ void registerConfigurationParser(const std::string &key,
+ const ParserCallback &parser);
+
+ void registerConfigurationSetter(const std::string &key,
+ const SetCallback &set_callback);
+ void registerConfigurationGetter(const std::string &key,
+ const GetCallback &get_callback);
+
+ void unregisterConfigurationParser(const std::string &key);
+
+ void unregisterConfigurationSetter(const std::string &key);
+
+ void unregisterConfigurationGetter(const std::string &key);
+
+ void getConfiguration(
+ interface::global_config::ConfigurationObject &configuration_object,
+ std::error_code &ec);
+ void setConfiguration(
+ const interface::global_config::ConfigurationObject &configuration_object,
+ std::error_code &ec);
+
+ private:
+ GlobalConfiguration();
+ std::string conf_file_path_;
+ bool parseTransportConfig(const std::string &path);
+
+ private:
+ std::mutex cp_mtx_;
+ using ParserPair = std::pair<bool, ParserCallback>;
+ std::map<std::string, ParserPair> configuration_parsers_;
+ std::map<std::string, GetCallback> configuration_getters_;
+ std::map<std::string, SetCallback> configuration_setters_;
+};
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/core/interest.cc b/libtransport/src/core/interest.cc
index 9ee6626..06cbe9f 100644
--- a/libtransport/src/core/interest.cc
+++ b/libtransport/src/core/interest.cc
@@ -31,8 +31,9 @@ namespace transport {
namespace core {
-Interest::Interest(const Name &interest_name, Packet::Format format)
- : Packet(format) {
+Interest::Interest(const Name &interest_name, Packet::Format format,
+ std::size_t additional_header_size)
+ : Packet(format, additional_header_size) {
if (hicn_interest_set_name(format_, packet_start_,
interest_name.getConstStructReference()) < 0) {
throw errors::MalformedPacketException();
@@ -45,20 +46,14 @@ Interest::Interest(const Name &interest_name, Packet::Format format)
}
#ifdef __ANDROID__
-Interest::Interest(hicn_format_t format) : Interest(Name("0::0|0"), format) {}
+Interest::Interest(hicn_format_t format, std::size_t additional_header_size)
+ : Interest(Name("0::0|0"), format, additional_header_size) {}
#else
-Interest::Interest(hicn_format_t format) : Interest(base_name, format) {}
+Interest::Interest(hicn_format_t format, std::size_t additional_header_size)
+ : Interest(base_name, format, additional_header_size) {}
#endif
-Interest::Interest(const uint8_t *buffer, std::size_t size)
- : Packet(buffer, size) {
- if (hicn_interest_get_name(format_, packet_start_,
- name_.getStructReference()) < 0) {
- throw errors::MalformedPacketException();
- }
-}
-
-Interest::Interest(MemBufPtr &&buffer) : Packet(std::move(buffer)) {
+Interest::Interest(MemBuf &&buffer) : Packet(std::move(buffer)) {
if (hicn_interest_get_name(format_, packet_start_,
name_.getStructReference()) < 0) {
throw errors::MalformedPacketException();
@@ -70,6 +65,14 @@ Interest::Interest(Interest &&other_interest)
name_ = std::move(other_interest.name_);
}
+Interest::Interest(const Interest &other_interest) : Packet(other_interest) {
+ name_ = other_interest.name_;
+}
+
+Interest &Interest::operator=(const Interest &other) {
+ return (Interest &)Packet::operator=(other);
+}
+
Interest::~Interest() {}
const Name &Interest::getName() const {
@@ -152,6 +155,59 @@ void Interest::resetForHash() {
}
}
+bool Interest::hasManifest() {
+ return (getPayloadType() == PayloadType::MANIFEST);
+}
+
+void Interest::appendSuffix(std::uint32_t suffix) {
+ if (TRANSPORT_EXPECT_FALSE(suffix_set_.empty())) {
+ setPayloadType(PayloadType::MANIFEST);
+ }
+
+ suffix_set_.emplace(suffix);
+}
+
+void Interest::encodeSuffixes() {
+ if (!hasManifest()) {
+ return;
+ }
+
+ // We assume interest does not hold signature for the moment.
+ auto int_manifest_header =
+ (InterestManifestHeader *)(writableData() + headerSize());
+ int_manifest_header->n_suffixes = suffix_set_.size();
+ std::size_t additional_length =
+ int_manifest_header->n_suffixes * sizeof(uint32_t);
+
+ uint32_t *suffix = (uint32_t *)(int_manifest_header + 1);
+ for (auto it = suffix_set_.begin(); it != suffix_set_.end(); it++, suffix++) {
+ *suffix = *it;
+ }
+
+ updateLength(additional_length);
+}
+
+uint32_t *Interest::firstSuffix() {
+ if (!hasManifest()) {
+ return nullptr;
+ }
+
+ auto ret = (InterestManifestHeader *)(writableData() + headerSize());
+ ret += 1;
+
+ return (uint32_t *)ret;
+}
+
+uint32_t Interest::numberOfSuffixes() {
+ if (!hasManifest()) {
+ return 0;
+ }
+
+ auto header = (InterestManifestHeader *)(writableData() + headerSize());
+
+ return header->n_suffixes;
+}
+
} // end namespace core
} // end namespace transport
diff --git a/libtransport/src/core/io_module.cc b/libtransport/src/core/io_module.cc
new file mode 100644
index 0000000..fef0c15
--- /dev/null
+++ b/libtransport/src/core/io_module.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlfcn.h>
+#include <hicn/transport/core/io_module.h>
+#include <hicn/transport/utils/log.h>
+
+#ifdef ANDROID
+#include <io_modules/udp/hicn_forwarder_module.h>
+#endif
+
+#include <deque>
+
+namespace transport {
+namespace core {
+
+IoModule::~IoModule() {}
+
+IoModule *IoModule::load(const char *module_name) {
+#ifdef ANDROID
+ return new HicnForwarderModule();
+#else
+ void *handle = 0;
+ IoModule *module = 0;
+ IoModule *(*creator)(void) = 0;
+ const char *error = 0;
+
+ // open module
+ handle = dlopen(module_name, RTLD_NOW);
+ if (!handle) {
+ if ((error = dlerror()) != 0) {
+ TRANSPORT_LOGE("%s", error);
+ }
+ return 0;
+ }
+
+ // link factory method
+ creator = (IoModule * (*)(void)) dlsym(handle, "create_module");
+ if (!creator) {
+ if ((error = dlerror()) != 0) {
+ TRANSPORT_LOGE("%s", error);
+ return 0;
+ }
+ }
+
+ // create object and return it
+ module = (*creator)();
+ module->handle_ = handle;
+
+ return module;
+#endif
+}
+
+bool IoModule::unload(IoModule *module) {
+ if (!module) {
+ return false;
+ }
+
+#ifdef ANDROID
+ delete module;
+#else
+ // destroy object and close module
+ void *handle = module->handle_;
+ delete module;
+ dlclose(handle);
+#endif
+
+ return true;
+}
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/core/local_connector.cc b/libtransport/src/core/local_connector.cc
new file mode 100644
index 0000000..f0e36a3
--- /dev/null
+++ b/libtransport/src/core/local_connector.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017-2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core/local_connector.h>
+#include <hicn/transport/core/content_object.h>
+#include <hicn/transport/core/interest.h>
+#include <hicn/transport/errors/not_implemented_exception.h>
+#include <hicn/transport/utils/log.h>
+
+#include <asio/io_service.hpp>
+
+namespace transport {
+namespace core {
+
+LocalConnector::~LocalConnector() {}
+
+void LocalConnector::close() { state_ = State::CLOSED; }
+
+void LocalConnector::send(Packet &packet) {
+ if (!isConnected()) {
+ return;
+ }
+
+ TRANSPORT_LOGD("Sending packet to local socket.");
+ io_service_.get().post([this, p{packet.shared_from_this()}]() mutable {
+ receive_callback_(this, *p, std::make_error_code(std::errc(0)));
+ });
+}
+
+void LocalConnector::send(const uint8_t *packet, std::size_t len) {
+ throw errors::NotImplementedException();
+}
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/core/local_connector.h b/libtransport/src/core/local_connector.h
new file mode 100644
index 0000000..b0daa4f
--- /dev/null
+++ b/libtransport/src/core/local_connector.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017-2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/connector.h>
+#include <hicn/transport/core/global_object_pool.h>
+#include <hicn/transport/utils/move_wrapper.h>
+#include <hicn/transport/utils/shared_ptr_utils.h>
+#include <io_modules/forwarder/errors.h>
+
+#ifndef ASIO_STANDALONE
+#define ASIO_STANDALONE
+#endif
+#include <asio/io_service.hpp>
+
+namespace transport {
+namespace core {
+
+class LocalConnector : public Connector {
+ public:
+ template <typename ReceiveCallback, typename SentCallback, typename OnClose,
+ typename OnReconnect>
+ LocalConnector(asio::io_service &io_service,
+ ReceiveCallback &&receive_callback, SentCallback &&packet_sent,
+ OnClose &&close_callback, OnReconnect &&on_reconnect)
+ : Connector(receive_callback, packet_sent, close_callback, on_reconnect),
+ io_service_(io_service),
+ io_service_work_(io_service_.get()) {
+ state_ = State::CONNECTED;
+ }
+
+ ~LocalConnector() override;
+
+ void send(Packet &packet) override;
+
+ void send(const uint8_t *packet, std::size_t len) override;
+
+ void close() override;
+
+ auto shared_from_this() { return utils::shared_from(this); }
+
+ private:
+ std::reference_wrapper<asio::io_service> io_service_;
+ asio::io_service::work io_service_work_;
+ std::string name_;
+};
+
+} // namespace core
+} // namespace transport
diff --git a/libtransport/src/core/manifest.h b/libtransport/src/core/manifest.h
index eadfed7..9b25ebd 100644
--- a/libtransport/src/core/manifest.h
+++ b/libtransport/src/core/manifest.h
@@ -15,11 +15,10 @@
#pragma once
+#include <core/manifest_format.h>
#include <hicn/transport/core/content_object.h>
#include <hicn/transport/core/name.h>
-#include <core/manifest_format.h>
-
#include <set>
namespace transport {
@@ -36,18 +35,20 @@ class Manifest : public Base {
"Base must inherit from packet!");
public:
+ // core::ContentObjectManifest::Ptr
+
using Encoder = typename FormatTraits::Encoder;
using Decoder = typename FormatTraits::Decoder;
Manifest(std::size_t signature_size = 0)
- : Base(HF_INET6_TCP_AH),
+ : Base(HF_INET6_TCP_AH, signature_size),
encoder_(*this, signature_size),
decoder_(*this) {
Base::setPayloadType(PayloadType::MANIFEST);
}
Manifest(const core::Name &name, std::size_t signature_size = 0)
- : Base(name, HF_INET6_TCP_AH),
+ : Base(name, HF_INET6_TCP_AH, signature_size),
encoder_(*this, signature_size),
decoder_(*this) {
Base::setPayloadType(PayloadType::MANIFEST);
@@ -55,7 +56,9 @@ class Manifest : public Base {
template <typename T>
Manifest(T &&base)
- : Base(std::forward<T &&>(base)), encoder_(*this), decoder_(*this) {
+ : Base(std::forward<T &&>(base)),
+ encoder_(*this, 0, false),
+ decoder_(*this) {
Base::setPayloadType(PayloadType::MANIFEST);
}
@@ -96,13 +99,13 @@ class Manifest : public Base {
return *this;
}
- Manifest &setHashAlgorithm(utils::CryptoHashType hash_algorithm) {
+ Manifest &setHashAlgorithm(auth::CryptoHashType hash_algorithm) {
hash_algorithm_ = hash_algorithm;
encoder_.setHashAlgorithm(hash_algorithm_);
return *this;
}
- utils::CryptoHashType getHashAlgorithm() { return hash_algorithm_; }
+ auth::CryptoHashType getHashAlgorithm() { return hash_algorithm_; }
ManifestType getManifestType() const { return manifest_type_; }
@@ -138,7 +141,7 @@ class Manifest : public Base {
protected:
ManifestType manifest_type_;
- utils::CryptoHashType hash_algorithm_;
+ auth::CryptoHashType hash_algorithm_;
bool is_last_;
Encoder encoder_;
diff --git a/libtransport/src/core/manifest_format.h b/libtransport/src/core/manifest_format.h
index 36d23f9..b759942 100644
--- a/libtransport/src/core/manifest_format.h
+++ b/libtransport/src/core/manifest_format.h
@@ -15,8 +15,8 @@
#pragma once
+#include <hicn/transport/auth/crypto_hasher.h>
#include <hicn/transport/core/name.h>
-#include <hicn/transport/security/crypto_hasher.h>
#include <cinttypes>
#include <type_traits>
@@ -63,8 +63,10 @@ template <typename T>
struct format_traits {
using Encoder = typename T::Encoder;
using Decoder = typename T::Decoder;
+ using Hash = typename T::Hash;
using HashType = typename T::HashType;
- using HashList = typename T::HashList;
+ using Suffix = typename T::Suffix;
+ using SuffixList = typename T::SuffixList;
};
class Packet;
@@ -86,7 +88,7 @@ class ManifestEncoder {
return static_cast<Implementation &>(*this).setManifestTypeImpl(type);
}
- ManifestEncoder &setHashAlgorithm(utils::CryptoHashType hash) {
+ ManifestEncoder &setHashAlgorithm(auth::CryptoHashType hash) {
return static_cast<Implementation &>(*this).setHashAlgorithmImpl(hash);
}
@@ -160,7 +162,7 @@ class ManifestDecoder {
return static_cast<const Implementation &>(*this).getManifestTypeImpl();
}
- utils::CryptoHashType getHashAlgorithm() const {
+ auth::CryptoHashType getHashAlgorithm() const {
return static_cast<const Implementation &>(*this).getHashAlgorithmImpl();
}
diff --git a/libtransport/src/core/manifest_format_fixed.cc b/libtransport/src/core/manifest_format_fixed.cc
index ca80c38..55280b4 100644
--- a/libtransport/src/core/manifest_format_fixed.cc
+++ b/libtransport/src/core/manifest_format_fixed.cc
@@ -13,49 +13,50 @@
* limitations under the License.
*/
+#include <core/manifest_format_fixed.h>
#include <hicn/transport/core/packet.h>
#include <hicn/transport/utils/literals.h>
-#include <core/manifest_format_fixed.h>
-
namespace transport {
namespace core {
// TODO use preallocated pool of membufs
FixedManifestEncoder::FixedManifestEncoder(Packet &packet,
- std::size_t signature_size)
+ std::size_t signature_size,
+ bool clear)
: packet_(packet),
- max_size_(Packet::default_mtu - packet_.headerSize() - signature_size),
- manifest_(
- utils::MemBuf::create(Packet::default_mtu - packet_.headerSize())),
- manifest_header_(
- reinterpret_cast<ManifestHeader *>(manifest_->writableData())),
- manifest_entries_(reinterpret_cast<ManifestEntry *>(
- manifest_->writableData() + sizeof(ManifestHeader))),
+ max_size_(Packet::default_mtu - packet_.headerSize()),
+ manifest_header_(reinterpret_cast<ManifestHeader *>(
+ packet_.writableData() + packet_.headerSize())),
+ manifest_entries_(
+ reinterpret_cast<ManifestEntry *>(manifest_header_ + 1)),
current_entry_(0),
signature_size_(signature_size) {
- *manifest_header_ = {0};
+ if (clear) {
+ *manifest_header_ = {0};
+ }
}
FixedManifestEncoder::~FixedManifestEncoder() {}
FixedManifestEncoder &FixedManifestEncoder::encodeImpl() {
- manifest_->append(sizeof(ManifestHeader) +
- manifest_header_->number_of_entries *
- sizeof(ManifestEntry));
- packet_.appendPayload(std::move(manifest_));
+ packet_.append(sizeof(ManifestHeader) +
+ manifest_header_->number_of_entries * sizeof(ManifestEntry));
+ packet_.updateLength();
return *this;
}
FixedManifestEncoder &FixedManifestEncoder::clearImpl() {
- manifest_ = utils::MemBuf::create(Packet::default_mtu - packet_.headerSize() -
- signature_size_);
+ packet_.trimEnd(sizeof(ManifestHeader) +
+ manifest_header_->number_of_entries * sizeof(ManifestEntry));
+ current_entry_ = 0;
+ *manifest_header_ = {0};
return *this;
}
FixedManifestEncoder &FixedManifestEncoder::setHashAlgorithmImpl(
- utils::CryptoHashType algorithm) {
+ auth::CryptoHashType algorithm) {
manifest_header_->hash_algorithm = static_cast<uint8_t>(algorithm);
return *this;
}
@@ -83,7 +84,7 @@ FixedManifestEncoder &FixedManifestEncoder::setBaseNameImpl(
}
FixedManifestEncoder &FixedManifestEncoder::addSuffixAndHashImpl(
- uint32_t suffix, const utils::CryptoHash &hash) {
+ uint32_t suffix, const auth::CryptoHash &hash) {
auto _hash = hash.getDigest<std::uint8_t>();
addSuffixHashBytes(suffix, _hash.data(), _hash.length());
return *this;
@@ -170,8 +171,8 @@ ManifestType FixedManifestDecoder::getManifestTypeImpl() const {
return static_cast<ManifestType>(manifest_header_->manifest_type);
}
-utils::CryptoHashType FixedManifestDecoder::getHashAlgorithmImpl() const {
- return static_cast<utils::CryptoHashType>(manifest_header_->hash_algorithm);
+auth::CryptoHashType FixedManifestDecoder::getHashAlgorithmImpl() const {
+ return static_cast<auth::CryptoHashType>(manifest_header_->hash_algorithm);
}
NextSegmentCalculationStrategy
diff --git a/libtransport/src/core/manifest_format_fixed.h b/libtransport/src/core/manifest_format_fixed.h
index 1d7cd7d..56ad4ef 100644
--- a/libtransport/src/core/manifest_format_fixed.h
+++ b/libtransport/src/core/manifest_format_fixed.h
@@ -15,9 +15,8 @@
#pragma once
-#include <hicn/transport/core/packet.h>
-
#include <core/manifest_format.h>
+#include <hicn/transport/core/packet.h>
#include <string>
@@ -53,8 +52,10 @@ class Packet;
struct Fixed {
using Encoder = FixedManifestEncoder;
using Decoder = FixedManifestDecoder;
- using HashType = utils::CryptoHash;
- using SuffixList = std::list<std::pair<std::uint32_t, std::uint8_t *>>;
+ using Hash = auth::CryptoHash;
+ using HashType = auth::CryptoHashType;
+ using Suffix = uint32_t;
+ using SuffixList = std::list<std::pair<uint32_t, uint8_t *>>;
};
struct Flags {
@@ -84,7 +85,8 @@ static const constexpr std::uint8_t manifest_version = 1;
class FixedManifestEncoder : public ManifestEncoder<FixedManifestEncoder> {
public:
- FixedManifestEncoder(Packet &packet, std::size_t signature_size = 0);
+ FixedManifestEncoder(Packet &packet, std::size_t signature_size = 0,
+ bool clear = true);
~FixedManifestEncoder();
@@ -94,7 +96,7 @@ class FixedManifestEncoder : public ManifestEncoder<FixedManifestEncoder> {
FixedManifestEncoder &setManifestTypeImpl(ManifestType manifest_type);
- FixedManifestEncoder &setHashAlgorithmImpl(utils::CryptoHashType algorithm);
+ FixedManifestEncoder &setHashAlgorithmImpl(Fixed::HashType algorithm);
FixedManifestEncoder &setNextSegmentCalculationStrategyImpl(
NextSegmentCalculationStrategy strategy);
@@ -102,7 +104,7 @@ class FixedManifestEncoder : public ManifestEncoder<FixedManifestEncoder> {
FixedManifestEncoder &setBaseNameImpl(const core::Name &base_name);
FixedManifestEncoder &addSuffixAndHashImpl(uint32_t suffix,
- const utils::CryptoHash &hash);
+ const Fixed::Hash &hash);
FixedManifestEncoder &setIsFinalManifestImpl(bool is_last);
@@ -125,7 +127,6 @@ class FixedManifestEncoder : public ManifestEncoder<FixedManifestEncoder> {
Packet &packet_;
std::size_t max_size_;
- std::unique_ptr<utils::MemBuf> manifest_;
ManifestHeader *manifest_header_;
ManifestEntry *manifest_entries_;
std::size_t current_entry_;
@@ -144,7 +145,7 @@ class FixedManifestDecoder : public ManifestDecoder<FixedManifestDecoder> {
ManifestType getManifestTypeImpl() const;
- utils::CryptoHashType getHashAlgorithmImpl() const;
+ Fixed::HashType getHashAlgorithmImpl() const;
NextSegmentCalculationStrategy getNextSegmentCalculationStrategyImpl() const;
diff --git a/libtransport/src/core/manifest_inline.h b/libtransport/src/core/manifest_inline.h
index dedf82b..fcb1d21 100644
--- a/libtransport/src/core/manifest_inline.h
+++ b/libtransport/src/core/manifest_inline.h
@@ -30,8 +30,12 @@ class ManifestInline
: public Manifest<Base, FormatTraits, ManifestInline<Base, FormatTraits>> {
using ManifestBase =
Manifest<Base, FormatTraits, ManifestInline<Base, FormatTraits>>;
+
+ using Hash = typename FormatTraits::Hash;
using HashType = typename FormatTraits::HashType;
+ using Suffix = typename FormatTraits::Suffix;
using SuffixList = typename FormatTraits::SuffixList;
+ using HashEntry = std::pair<auth::CryptoHashType, std::vector<uint8_t>>;
public:
ManifestInline() : ManifestBase() {}
@@ -44,7 +48,7 @@ class ManifestInline
static TRANSPORT_ALWAYS_INLINE ManifestInline *createManifest(
const core::Name &manifest_name, ManifestVersion version,
- ManifestType type, utils::CryptoHashType algorithm, bool is_last,
+ ManifestType type, auth::CryptoHashType algorithm, bool is_last,
const Name &base_name, NextSegmentCalculationStrategy strategy,
std::size_t signature_size) {
auto manifest = new ManifestInline(manifest_name, signature_size);
@@ -84,7 +88,7 @@ class ManifestInline
const Name &getBaseName() { return base_name_; }
- ManifestInline &addSuffixHash(uint32_t suffix, const HashType &hash) {
+ ManifestInline &addSuffixHash(Suffix suffix, const Hash &hash) {
ManifestBase::encoder_.addSuffixAndHash(suffix, hash);
return *this;
}
@@ -104,12 +108,35 @@ class ManifestInline
return next_segment_strategy_;
}
+ // Convert several manifests into a single map from suffixes to packet hashes.
+ // All manifests must have been decoded beforehand.
+ static std::unordered_map<Suffix, HashEntry> getSuffixMap(
+ const std::vector<ManifestInline *> &manifests) {
+ std::unordered_map<Suffix, HashEntry> suffix_map;
+
+ for (auto manifest_ptr : manifests) {
+ HashType hash_algorithm = manifest_ptr->getHashAlgorithm();
+ SuffixList suffix_list = manifest_ptr->getSuffixList();
+
+ for (auto it = suffix_list.begin(); it != suffix_list.end(); ++it) {
+ std::vector<uint8_t> hash(
+ it->second, it->second + auth::hash_size_map[hash_algorithm]);
+ suffix_map[it->first] = {hash_algorithm, hash};
+ }
+ }
+
+ return suffix_map;
+ }
+ static std::unordered_map<Suffix, HashEntry> getSuffixMap(
+ ManifestInline *manifest) {
+ return getSuffixMap(std::vector<ManifestInline *>{manifest});
+ }
+
private:
core::Name base_name_;
NextSegmentCalculationStrategy next_segment_strategy_;
SuffixList suffix_hash_map_;
};
-} // end namespace core
-
-} // end namespace transport \ No newline at end of file
+} // namespace core
+} // namespace transport
diff --git a/libtransport/src/core/name.cc b/libtransport/src/core/name.cc
index 811e93b..795c8a6 100644
--- a/libtransport/src/core/name.cc
+++ b/libtransport/src/core/name.cc
@@ -13,14 +13,13 @@
* limitations under the License.
*/
+#include <core/manifest_format.h>
#include <hicn/transport/core/name.h>
#include <hicn/transport/errors/errors.h>
#include <hicn/transport/errors/tokenizer_exception.h>
#include <hicn/transport/utils/hash.h>
#include <hicn/transport/utils/string_tokenizer.h>
-#include <core/manifest_format.h>
-
namespace transport {
namespace core {
@@ -98,7 +97,12 @@ bool Name::operator!=(const Name &name) const {
}
Name::operator bool() const {
- return bool(hicn_name_empty((hicn_name_t *)&name_));
+ auto ret = isValid();
+ return ret;
+}
+
+bool Name::isValid() const {
+ return bool(!hicn_name_empty((hicn_name_t *)&name_));
}
bool Name::equals(const Name &name, bool consider_segment) const {
diff --git a/libtransport/src/core/packet.cc b/libtransport/src/core/packet.cc
index cd2c5aa..6f23772 100644
--- a/libtransport/src/core/packet.cc
+++ b/libtransport/src/core/packet.cc
@@ -31,59 +31,94 @@ namespace core {
const core::Name Packet::base_name("0::0|0");
-Packet::Packet(Format format)
- : packet_(utils::MemBuf::create(getHeaderSizeFromFormat(format, 256))
- .release()),
- packet_start_(reinterpret_cast<hicn_header_t *>(packet_->writableData())),
- header_head_(packet_.get()),
- payload_head_(nullptr),
- format_(format) {
- if (hicn_packet_init_header(format, packet_start_) < 0) {
- throw errors::RuntimeException("Unexpected error initializing the packet.");
- }
-
- packet_->append(getHeaderSizeFromFormat(format_));
-}
-
-Packet::Packet(MemBufPtr &&buffer)
- : packet_(std::move(buffer)),
- packet_start_(reinterpret_cast<hicn_header_t *>(packet_->writableData())),
- header_head_(packet_.get()),
- payload_head_(nullptr),
- format_(getFormatFromBuffer(packet_->writableData(), packet_->length())) {
-}
-
-Packet::Packet(const uint8_t *buffer, std::size_t size)
- : Packet(MemBufPtr(utils::MemBuf::copyBuffer(buffer, size).release())) {}
+Packet::Packet(Format format, std::size_t additional_header_size)
+ : utils::MemBuf(utils::MemBuf(CREATE, 2048)),
+ packet_start_(reinterpret_cast<hicn_header_t *>(writableData())),
+ header_offset_(0),
+ format_(format),
+ payload_type_(PayloadType::UNSPECIFIED) {
+ setFormat(format_, additional_header_size);
+}
+
+Packet::Packet(MemBuf &&buffer)
+ : utils::MemBuf(std::move(buffer)),
+ packet_start_(reinterpret_cast<hicn_header_t *>(writableData())),
+ header_offset_(0),
+ format_(getFormatFromBuffer(data(), length())),
+ payload_type_(PayloadType::UNSPECIFIED) {}
+
+Packet::Packet(CopyBufferOp, const uint8_t *buffer, std::size_t size)
+ : utils::MemBuf(COPY_BUFFER, buffer, size),
+ packet_start_(reinterpret_cast<hicn_header_t *>(writableData())),
+ header_offset_(0),
+ format_(getFormatFromBuffer(data(), length())),
+ payload_type_(PayloadType::UNSPECIFIED) {}
+
+Packet::Packet(WrapBufferOp, uint8_t *buffer, std::size_t length,
+ std::size_t size)
+ : utils::MemBuf(WRAP_BUFFER, buffer, length, size),
+ packet_start_(reinterpret_cast<hicn_header_t *>(writableData())),
+ header_offset_(0),
+ format_(getFormatFromBuffer(this->data(), this->length())),
+ payload_type_(PayloadType::UNSPECIFIED) {}
+
+Packet::Packet(CreateOp, uint8_t *buffer, std::size_t length, std::size_t size,
+ Format format, std::size_t additional_header_size)
+ : utils::MemBuf(WRAP_BUFFER, buffer, length, size),
+ packet_start_(reinterpret_cast<hicn_header_t *>(writableData())),
+ header_offset_(0),
+ format_(format),
+ payload_type_(PayloadType::UNSPECIFIED) {
+ clear();
+ setFormat(format_, additional_header_size);
+}
+
+Packet::Packet(const Packet &other)
+ : utils::MemBuf(other),
+ packet_start_(reinterpret_cast<hicn_header_t *>(writableData())),
+ header_offset_(other.header_offset_),
+ format_(other.format_),
+ payload_type_(PayloadType::UNSPECIFIED) {}
Packet::Packet(Packet &&other)
- : packet_(std::move(other.packet_)),
+ : utils::MemBuf(std::move(other)),
packet_start_(other.packet_start_),
- header_head_(other.header_head_),
- payload_head_(other.payload_head_),
- format_(other.format_) {
+ header_offset_(other.header_offset_),
+ format_(other.format_),
+ payload_type_(PayloadType::UNSPECIFIED) {
other.packet_start_ = nullptr;
- other.header_head_ = nullptr;
- other.payload_head_ = nullptr;
other.format_ = HF_UNSPEC;
+ other.header_offset_ = 0;
}
Packet::~Packet() {}
+Packet &Packet::operator=(const Packet &other) {
+ if (this != &other) {
+ *this = other;
+ packet_start_ = reinterpret_cast<hicn_header_t *>(writableData());
+ }
+
+ return *this;
+}
+
std::size_t Packet::getHeaderSizeFromBuffer(Format format,
const uint8_t *buffer) {
size_t header_length;
+
if (hicn_packet_get_header_length(format, (hicn_header_t *)buffer,
&header_length) < 0) {
throw errors::MalformedPacketException();
}
+
return header_length;
}
bool Packet::isInterest(const uint8_t *buffer) {
bool is_interest = false;
- if (TRANSPORT_EXPECT_FALSE(hicn_packet_test_ece((const hicn_header_t *)buffer,
+ if (TRANSPORT_EXPECT_FALSE(hicn_packet_test_ece(HF_INET6_TCP,
+ (const hicn_header_t *)buffer,
&is_interest) < 0)) {
throw errors::RuntimeException(
"Impossible to retrieve ece flag from packet");
@@ -92,6 +127,25 @@ bool Packet::isInterest(const uint8_t *buffer) {
return !is_interest;
}
+void Packet::setFormat(Packet::Format format,
+ std::size_t additional_header_size) {
+ format_ = format;
+ if (hicn_packet_init_header(format_, packet_start_) < 0) {
+ throw errors::RuntimeException("Unexpected error initializing the packet.");
+ }
+
+ auto header_size = getHeaderSizeFromFormat(format_);
+ assert(header_size <= tailroom());
+ append(header_size);
+
+ assert(additional_header_size <= tailroom());
+ append(additional_header_size);
+
+ header_offset_ = length();
+}
+
+bool Packet::isInterest() { return Packet::isInterest(data()); }
+
std::size_t Packet::getPayloadSizeFromBuffer(Format format,
const uint8_t *buffer) {
std::size_t payload_length;
@@ -105,67 +159,58 @@ std::size_t Packet::getPayloadSizeFromBuffer(Format format,
}
std::size_t Packet::payloadSize() const {
- return getPayloadSizeFromBuffer(format_,
- reinterpret_cast<uint8_t *>(packet_start_));
+ std::size_t ret = 0;
+
+ if (length()) {
+ ret = getPayloadSizeFromBuffer(format_,
+ reinterpret_cast<uint8_t *>(packet_start_));
+ }
+
+ return ret;
}
std::size_t Packet::headerSize() const {
- return getHeaderSizeFromBuffer(format_,
- reinterpret_cast<uint8_t *>(packet_start_));
+ if (header_offset_ == 0 && length()) {
+ const_cast<Packet *>(this)->header_offset_ = getHeaderSizeFromBuffer(
+ format_, reinterpret_cast<uint8_t *>(packet_start_));
+ }
+
+ return header_offset_;
}
Packet &Packet::appendPayload(std::unique_ptr<utils::MemBuf> &&payload) {
- separateHeaderPayload();
-
- if (!payload_head_) {
- payload_head_ = payload.get();
- }
-
- header_head_->prependChain(std::move(payload));
+ prependChain(std::move(payload));
updateLength();
return *this;
}
Packet &Packet::appendPayload(const uint8_t *buffer, std::size_t length) {
- return appendPayload(utils::MemBuf::copyBuffer(buffer, length));
-}
-
-Packet &Packet::appendHeader(std::unique_ptr<utils::MemBuf> &&header) {
- separateHeaderPayload();
+ prependPayload(&buffer, &length);
- if (!payload_head_) {
- header_head_->prependChain(std::move(header));
- } else {
- payload_head_->prependChain(std::move(header));
+ if (length) {
+ appendPayload(utils::MemBuf::copyBuffer(buffer, length));
}
updateLength();
return *this;
}
-Packet &Packet::appendHeader(const uint8_t *buffer, std::size_t length) {
- return appendHeader(utils::MemBuf::copyBuffer(buffer, length));
-}
-
std::unique_ptr<utils::MemBuf> Packet::getPayload() const {
- const_cast<Packet *>(this)->separateHeaderPayload();
-
- // Hopefully the payload is contiguous
- if (TRANSPORT_EXPECT_FALSE(payload_head_ &&
- payload_head_->next() != header_head_)) {
- payload_head_->gather(payloadSize());
- }
-
- return payload_head_->cloneOne();
+ auto ret = clone();
+ ret->trimStart(headerSize());
+ return ret;
}
Packet &Packet::updateLength(std::size_t length) {
std::size_t total_length = length;
- for (utils::MemBuf *current = payload_head_;
- current && current != header_head_; current = current->next()) {
+ const utils::MemBuf *current = this;
+ do {
total_length += current->length();
- }
+ current = current->next();
+ } while (current != this);
+
+ total_length -= headerSize();
if (hicn_packet_set_payload_length(format_, packet_start_, total_length) <
0) {
@@ -176,13 +221,16 @@ Packet &Packet::updateLength(std::size_t length) {
}
PayloadType Packet::getPayloadType() const {
- hicn_payload_type_t ret = HPT_UNSPEC;
+ if (payload_type_ == PayloadType::UNSPECIFIED) {
+ hicn_payload_type_t ret;
+ if (hicn_packet_get_payload_type(packet_start_, &ret) < 0) {
+ throw errors::RuntimeException("Impossible to retrieve payload type.");
+ }
- if (hicn_packet_get_payload_type(packet_start_, &ret) < 0) {
- throw errors::RuntimeException("Impossible to retrieve payload type.");
+ payload_type_ = (PayloadType)ret;
}
- return PayloadType(ret);
+ return payload_type_;
}
Packet &Packet::setPayloadType(PayloadType payload_type) {
@@ -191,60 +239,76 @@ Packet &Packet::setPayloadType(PayloadType payload_type) {
throw errors::RuntimeException("Error setting payload type of the packet.");
}
+ payload_type_ = payload_type;
+
return *this;
}
Packet::Format Packet::getFormat() const {
- if (format_ == HF_UNSPEC) {
+ /**
+ * We check packet start because after a movement it will result in a nullptr
+ */
+ if (format_ == HF_UNSPEC && length()) {
if (hicn_packet_get_format(packet_start_, &format_) < 0) {
- throw errors::MalformedPacketException();
+ TRANSPORT_LOGE("Unexpected packet format.");
}
}
return format_;
}
-const std::shared_ptr<utils::MemBuf> Packet::acquireMemBufReference() const {
- return packet_;
+std::shared_ptr<utils::MemBuf> Packet::acquireMemBufReference() {
+ return std::static_pointer_cast<utils::MemBuf>(shared_from_this());
}
void Packet::dump() const {
- const_cast<Packet *>(this)->separateHeaderPayload();
-
TRANSPORT_LOGI("HEADER -- Length: %zu", headerSize());
- hicn_packet_dump((uint8_t *)header_head_->data(), headerSize());
-
TRANSPORT_LOGI("PAYLOAD -- Length: %zu", payloadSize());
- for (utils::MemBuf *current = payload_head_;
- current && current != header_head_; current = current->next()) {
+
+ const utils::MemBuf *current = this;
+ do {
TRANSPORT_LOGI("MemBuf Length: %zu", current->length());
- hicn_packet_dump((uint8_t *)current->data(), current->length());
- }
+ dump((uint8_t *)current->data(), current->length());
+ current = current->next();
+ } while (current != this);
+}
+
+void Packet::dump(uint8_t *buffer, std::size_t length) {
+ hicn_packet_dump(buffer, length);
}
void Packet::setSignatureSize(std::size_t size_bytes) {
+ if (!authenticationHeader()) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
int ret = hicn_packet_set_signature_size(format_, packet_start_, size_bytes);
if (ret < 0) {
- throw errors::RuntimeException("Packet without Authentication Header.");
+ throw errors::RuntimeException("Error setting signature size.");
}
-
- packet_->append(size_bytes);
- updateLength();
}
uint8_t *Packet::getSignature() const {
+ if (!authenticationHeader()) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
uint8_t *signature;
int ret = hicn_packet_get_signature(format_, packet_start_, &signature);
if (ret < 0) {
- throw errors::RuntimeException("Packet without Authentication Header.");
+ throw errors::RuntimeException("Error getting signature.");
}
return signature;
}
void Packet::setSignatureTimestamp(const uint64_t &timestamp) {
+ if (!authenticationHeader()) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
int ret =
hicn_packet_set_signature_timestamp(format_, packet_start_, timestamp);
@@ -254,6 +318,10 @@ void Packet::setSignatureTimestamp(const uint64_t &timestamp) {
}
uint64_t Packet::getSignatureTimestamp() const {
+ if (!authenticationHeader()) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
uint64_t return_value;
int ret = hicn_packet_get_signature_timestamp(format_, packet_start_,
&return_value);
@@ -266,7 +334,11 @@ uint64_t Packet::getSignatureTimestamp() const {
}
void Packet::setValidationAlgorithm(
- const utils::CryptoSuite &validation_algorithm) {
+ const auth::CryptoSuite &validation_algorithm) {
+ if (!authenticationHeader()) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
int ret = hicn_packet_set_validation_algorithm(format_, packet_start_,
uint8_t(validation_algorithm));
@@ -275,7 +347,11 @@ void Packet::setValidationAlgorithm(
}
}
-utils::CryptoSuite Packet::getValidationAlgorithm() const {
+auth::CryptoSuite Packet::getValidationAlgorithm() const {
+ if (!authenticationHeader()) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
uint8_t return_value;
int ret = hicn_packet_get_validation_algorithm(format_, packet_start_,
&return_value);
@@ -284,10 +360,14 @@ utils::CryptoSuite Packet::getValidationAlgorithm() const {
throw errors::RuntimeException("Error getting the validation algorithm.");
}
- return utils::CryptoSuite(return_value);
+ return auth::CryptoSuite(return_value);
}
-void Packet::setKeyId(const utils::KeyId &key_id) {
+void Packet::setKeyId(const auth::KeyId &key_id) {
+ if (!authenticationHeader()) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
int ret = hicn_packet_set_key_id(format_, packet_start_, key_id.first);
if (ret < 0) {
@@ -295,8 +375,12 @@ void Packet::setKeyId(const utils::KeyId &key_id) {
}
}
-utils::KeyId Packet::getKeyId() const {
- utils::KeyId return_value;
+auth::KeyId Packet::getKeyId() const {
+ if (!authenticationHeader()) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
+ auth::KeyId return_value;
int ret = hicn_packet_get_key_id(format_, packet_start_, &return_value.first,
&return_value.second);
@@ -307,8 +391,8 @@ utils::KeyId Packet::getKeyId() const {
return return_value;
}
-utils::CryptoHash Packet::computeDigest(utils::CryptoHashType algorithm) const {
- utils::CryptoHasher hasher(static_cast<utils::CryptoHashType>(algorithm));
+auth::CryptoHash Packet::computeDigest(auth::CryptoHashType algorithm) const {
+ auth::CryptoHasher hasher(static_cast<auth::CryptoHashType>(algorithm));
hasher.init();
// Copy IP+TCP/ICMP header before zeroing them
@@ -318,11 +402,11 @@ utils::CryptoHash Packet::computeDigest(utils::CryptoHashType algorithm) const {
const_cast<Packet *>(this)->resetForHash();
- auto current = header_head_;
+ const utils::MemBuf *current = this;
do {
hasher.updateBytes(current->data(), current->length());
current = current->next();
- } while (current != header_head_);
+ } while (current != this);
hicn_packet_copy_header(format_, &header_copy, packet_start_, false);
@@ -330,15 +414,33 @@ utils::CryptoHash Packet::computeDigest(utils::CryptoHashType algorithm) const {
}
bool Packet::checkIntegrity() const {
- if (hicn_packet_check_integrity(format_, packet_start_) < 0) {
+ uint16_t partial_csum =
+ csum(data() + HICN_V6_TCP_HDRLEN, length() - HICN_V6_TCP_HDRLEN, 0);
+
+ for (const utils::MemBuf *current = next(); current != this;
+ current = current->next()) {
+ partial_csum = csum(current->data(), current->length(), ~partial_csum);
+ }
+
+ if (hicn_packet_check_integrity_no_payload(format_, packet_start_,
+ partial_csum) < 0) {
return false;
}
return true;
}
+void Packet::prependPayload(const uint8_t **buffer, std::size_t *size) {
+ auto last = prev();
+ auto to_copy = std::min(*size, last->tailroom());
+ std::memcpy(last->writableTail(), *buffer, to_copy);
+ last->append(to_copy);
+ *size -= to_copy;
+ *buffer += to_copy;
+}
+
Packet &Packet::setSyn() {
- if (hicn_packet_set_syn(packet_start_) < 0) {
+ if (hicn_packet_set_syn(format_, packet_start_) < 0) {
throw errors::RuntimeException("Error setting syn bit in the packet.");
}
@@ -346,7 +448,7 @@ Packet &Packet::setSyn() {
}
Packet &Packet::resetSyn() {
- if (hicn_packet_reset_syn(packet_start_) < 0) {
+ if (hicn_packet_reset_syn(format_, packet_start_) < 0) {
throw errors::RuntimeException("Error resetting syn bit in the packet.");
}
@@ -355,7 +457,7 @@ Packet &Packet::resetSyn() {
bool Packet::testSyn() const {
bool res = false;
- if (hicn_packet_test_syn(packet_start_, &res) < 0) {
+ if (hicn_packet_test_syn(format_, packet_start_, &res) < 0) {
throw errors::RuntimeException("Error testing syn bit in the packet.");
}
@@ -363,7 +465,7 @@ bool Packet::testSyn() const {
}
Packet &Packet::setAck() {
- if (hicn_packet_set_ack(packet_start_) < 0) {
+ if (hicn_packet_set_ack(format_, packet_start_) < 0) {
throw errors::RuntimeException("Error setting ack bit in the packet.");
}
@@ -371,7 +473,7 @@ Packet &Packet::setAck() {
}
Packet &Packet::resetAck() {
- if (hicn_packet_reset_ack(packet_start_) < 0) {
+ if (hicn_packet_reset_ack(format_, packet_start_) < 0) {
throw errors::RuntimeException("Error resetting ack bit in the packet.");
}
@@ -380,7 +482,7 @@ Packet &Packet::resetAck() {
bool Packet::testAck() const {
bool res = false;
- if (hicn_packet_test_ack(packet_start_, &res) < 0) {
+ if (hicn_packet_test_ack(format_, packet_start_, &res) < 0) {
throw errors::RuntimeException("Error testing ack bit in the packet.");
}
@@ -388,7 +490,7 @@ bool Packet::testAck() const {
}
Packet &Packet::setRst() {
- if (hicn_packet_set_rst(packet_start_) < 0) {
+ if (hicn_packet_set_rst(format_, packet_start_) < 0) {
throw errors::RuntimeException("Error setting rst bit in the packet.");
}
@@ -396,7 +498,7 @@ Packet &Packet::setRst() {
}
Packet &Packet::resetRst() {
- if (hicn_packet_reset_rst(packet_start_) < 0) {
+ if (hicn_packet_reset_rst(format_, packet_start_) < 0) {
throw errors::RuntimeException("Error resetting rst bit in the packet.");
}
@@ -405,7 +507,7 @@ Packet &Packet::resetRst() {
bool Packet::testRst() const {
bool res = false;
- if (hicn_packet_test_rst(packet_start_, &res) < 0) {
+ if (hicn_packet_test_rst(format_, packet_start_, &res) < 0) {
throw errors::RuntimeException("Error testing rst bit in the packet.");
}
@@ -413,7 +515,7 @@ bool Packet::testRst() const {
}
Packet &Packet::setFin() {
- if (hicn_packet_set_fin(packet_start_) < 0) {
+ if (hicn_packet_set_fin(format_, packet_start_) < 0) {
throw errors::RuntimeException("Error setting fin bit in the packet.");
}
@@ -421,7 +523,7 @@ Packet &Packet::setFin() {
}
Packet &Packet::resetFin() {
- if (hicn_packet_reset_fin(packet_start_) < 0) {
+ if (hicn_packet_reset_fin(format_, packet_start_) < 0) {
throw errors::RuntimeException("Error resetting fin bit in the packet.");
}
@@ -430,7 +532,7 @@ Packet &Packet::resetFin() {
bool Packet::testFin() const {
bool res = false;
- if (hicn_packet_test_fin(packet_start_, &res) < 0) {
+ if (hicn_packet_test_fin(format_, packet_start_, &res) < 0) {
throw errors::RuntimeException("Error testing fin bit in the packet.");
}
@@ -447,24 +549,29 @@ Packet &Packet::resetFlags() {
}
std::string Packet::printFlags() const {
- std::string flags = "";
+ std::string flags;
+
if (testSyn()) {
flags += "S";
}
+
if (testAck()) {
flags += "A";
}
+
if (testRst()) {
flags += "R";
}
+
if (testFin()) {
flags += "F";
}
+
return flags;
}
Packet &Packet::setSrcPort(uint16_t srcPort) {
- if (hicn_packet_set_src_port(packet_start_, srcPort) < 0) {
+ if (hicn_packet_set_src_port(format_, packet_start_, srcPort) < 0) {
throw errors::RuntimeException("Error setting source port in the packet.");
}
@@ -472,7 +579,7 @@ Packet &Packet::setSrcPort(uint16_t srcPort) {
}
Packet &Packet::setDstPort(uint16_t dstPort) {
- if (hicn_packet_set_dst_port(packet_start_, dstPort) < 0) {
+ if (hicn_packet_set_dst_port(format_, packet_start_, dstPort) < 0) {
throw errors::RuntimeException(
"Error setting destination port in the packet.");
}
@@ -483,7 +590,7 @@ Packet &Packet::setDstPort(uint16_t dstPort) {
uint16_t Packet::getSrcPort() const {
uint16_t port = 0;
- if (hicn_packet_get_src_port(packet_start_, &port) < 0) {
+ if (hicn_packet_get_src_port(format_, packet_start_, &port) < 0) {
throw errors::RuntimeException("Error reading source port in the packet.");
}
@@ -493,7 +600,7 @@ uint16_t Packet::getSrcPort() const {
uint16_t Packet::getDstPort() const {
uint16_t port = 0;
- if (hicn_packet_get_dst_port(packet_start_, &port) < 0) {
+ if (hicn_packet_get_dst_port(format_, packet_start_, &port) < 0) {
throw errors::RuntimeException(
"Error reading destination port in the packet.");
}
@@ -518,37 +625,6 @@ uint8_t Packet::getTTL() const {
return hops;
}
-void Packet::separateHeaderPayload() {
- if (payload_head_) {
- return;
- }
-
- int signature_size = 0;
- if (_is_ah(format_)) {
- signature_size = (uint32_t)getSignatureSize();
- }
-
- auto header_size = getHeaderSizeFromFormat(format_, signature_size);
- auto payload_length = packet_->length() - header_size;
-
- packet_->trimEnd(packet_->length());
-
- auto payload = packet_->cloneOne();
- payload_head_ = payload.get();
- payload_head_->advance(header_size);
- payload_head_->append(payload_length);
- packet_->prependChain(std::move(payload));
- packet_->append(header_size);
-}
-
-void Packet::resetPayload() {
- if (packet_->isChained()) {
- packet_->separateChain(packet_->next(), packet_->prev());
- payload_head_ = nullptr;
- updateLength();
- }
-}
-
} // end namespace core
} // end namespace transport
diff --git a/libtransport/src/core/pending_interest.h b/libtransport/src/core/pending_interest.h
index aeff78e..ca6411d 100644
--- a/libtransport/src/core/pending_interest.h
+++ b/libtransport/src/core/pending_interest.h
@@ -21,7 +21,6 @@
#include <hicn/transport/core/name.h>
#include <hicn/transport/interfaces/portal.h>
#include <hicn/transport/portability/portability.h>
-
#include <utils/deadline_timer.h>
#include <asio/steady_timer.hpp>
@@ -34,24 +33,21 @@ class HicnForwarderInterface;
class VPPForwarderInterface;
class RawSocketInterface;
-template <typename ForwarderInt>
class Portal;
using OnContentObjectCallback = interface::Portal::OnContentObjectCallback;
using OnInterestTimeoutCallback = interface::Portal::OnInterestTimeoutCallback;
class PendingInterest {
- friend class Portal<HicnForwarderInterface>;
- friend class Portal<VPPForwarderInterface>;
- friend class Portal<RawSocketInterface>;
+ friend class Portal;
public:
using Ptr = utils::ObjectPool<PendingInterest>::Ptr;
- PendingInterest()
- : interest_(nullptr, nullptr),
- timer_(),
- on_content_object_callback_(),
- on_interest_timeout_callback_() {}
+ // PendingInterest()
+ // : interest_(nullptr, nullptr),
+ // timer_(),
+ // on_content_object_callback_(),
+ // on_interest_timeout_callback_() {}
PendingInterest(Interest::Ptr &&interest,
std::unique_ptr<asio::steady_timer> &&timer)
diff --git a/libtransport/src/core/portal.cc b/libtransport/src/core/portal.cc
new file mode 100644
index 0000000..d1d26c5
--- /dev/null
+++ b/libtransport/src/core/portal.cc
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core/errors.h>
+#include <core/global_configuration.h>
+#include <core/portal.h>
+#include <hicn/transport/interfaces/global_conf_interface.h>
+#include <hicn/transport/portability/platform.h>
+#include <hicn/transport/utils/file.h>
+
+#include <libconfig.h++>
+
+using namespace transport::interface::global_config;
+
+namespace transport {
+namespace core {
+
+#ifdef ANDROID
+static const constexpr char default_module[] = "";
+#elif defined(MACINTOSH)
+static const constexpr char default_module[] = "hicnlight_module.dylib";
+#elif defined(LINUX)
+static const constexpr char default_module[] = "hicnlight_module.so";
+#endif
+
+IoModuleConfiguration Portal::conf_;
+std::string Portal::io_module_path_ = defaultIoModule();
+
+std::string Portal::defaultIoModule() {
+ using namespace std::placeholders;
+ GlobalConfiguration::getInstance().registerConfigurationParser(
+ io_module_section,
+ std::bind(&Portal::parseIoModuleConfiguration, _1, _2));
+ GlobalConfiguration::getInstance().registerConfigurationGetter(
+ io_module_section, std::bind(&Portal::getModuleConfiguration, _1, _2));
+ GlobalConfiguration::getInstance().registerConfigurationSetter(
+ io_module_section, std::bind(&Portal::setModuleConfiguration, _1, _2));
+
+ // return default
+ conf_.name = default_module;
+ return default_module;
+}
+
+void Portal::getModuleConfiguration(ConfigurationObject& object,
+ std::error_code& ec) {
+ assert(object.getKey() == io_module_section);
+
+ auto conf = dynamic_cast<const IoModuleConfiguration&>(object);
+ conf = conf_;
+ ec = std::error_code();
+}
+
+std::string getIoModulePath(const std::string& name,
+ const std::vector<std::string>& paths,
+ std::error_code& ec) {
+#ifdef LINUX
+ std::string extension = ".so";
+#elif defined(MACINTOSH)
+ std::string extension = ".dylib";
+#else
+#error "Platform not supported.";
+#endif
+
+ std::string complete_path = name;
+
+ if (name.empty()) {
+ ec = make_error_code(core_error::configuration_parse_failed);
+ return "";
+ }
+
+ complete_path += extension;
+
+ for (auto& p : paths) {
+ if (p.at(0) != '/') {
+ TRANSPORT_LOGW("Path %s is not an absolute path. Ignoring it.",
+ p.c_str());
+ continue;
+ }
+
+ if (utils::File::exists(p + "/" + complete_path)) {
+ complete_path = p + "/" + complete_path;
+ break;
+ }
+ }
+
+ return complete_path;
+}
+
+void Portal::setModuleConfiguration(const ConfigurationObject& object,
+ std::error_code& ec) {
+ assert(object.getKey() == io_module_section);
+
+ const IoModuleConfiguration& conf =
+ dynamic_cast<const IoModuleConfiguration&>(object);
+ auto path = getIoModulePath(conf.name, conf.search_path, ec);
+ if (!ec) {
+ conf_ = conf;
+ io_module_path_ = path;
+ }
+}
+
+void Portal::parseIoModuleConfiguration(const libconfig::Setting& io_config,
+ std::error_code& ec) {
+ using namespace libconfig;
+ // path property: the list of paths where to look for the module.
+ std::vector<std::string> paths;
+ std::string name;
+
+ if (io_config.exists("path")) {
+ // get path where looking for modules
+ const Setting& path_list = io_config.lookup("path");
+ auto count = path_list.getLength();
+
+ for (int i = 0; i < count; i++) {
+ paths.emplace_back(path_list[i].c_str());
+ }
+ }
+
+ if (io_config.exists("name")) {
+ io_config.lookupValue("name", name);
+ } else {
+ ec = make_error_code(core_error::configuration_parse_failed);
+ return;
+ }
+
+ auto path = getIoModulePath(name, paths, ec);
+ if (!ec) {
+ conf_.name = name;
+ conf_.search_path = paths;
+ io_module_path_ = path;
+ }
+}
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/core/portal.h b/libtransport/src/core/portal.h
index b63eab3..59254cf 100644
--- a/libtransport/src/core/portal.h
+++ b/libtransport/src/core/portal.h
@@ -15,24 +15,20 @@
#pragma once
-#include <core/forwarder_interface.h>
#include <core/pending_interest.h>
-#include <core/udp_socket_connector.h>
#include <hicn/transport/config.h>
#include <hicn/transport/core/content_object.h>
#include <hicn/transport/core/interest.h>
+#include <hicn/transport/core/io_module.h>
#include <hicn/transport/core/name.h>
#include <hicn/transport/core/prefix.h>
#include <hicn/transport/errors/errors.h>
+#include <hicn/transport/interfaces/global_conf_interface.h>
#include <hicn/transport/interfaces/portal.h>
#include <hicn/transport/portability/portability.h>
#include <hicn/transport/utils/fixed_block_allocator.h>
#include <hicn/transport/utils/log.h>
-#ifdef __vpp__
-#include <core/memif_connector.h>
-#endif
-
#include <asio.hpp>
#include <asio/steady_timer.hpp>
#include <future>
@@ -40,17 +36,19 @@
#include <queue>
#include <unordered_map>
+namespace libconfig {
+class Setting;
+}
+
namespace transport {
namespace core {
namespace portal_details {
-static constexpr uint32_t pool_size = 2048;
+static constexpr uint32_t pit_size = 1024;
class HandlerMemory {
#ifdef __vpp__
- static constexpr std::size_t memory_size = 1024 * 1024;
-
public:
HandlerMemory() {}
@@ -58,12 +56,11 @@ class HandlerMemory {
HandlerMemory &operator=(const HandlerMemory &) = delete;
TRANSPORT_ALWAYS_INLINE void *allocate(std::size_t size) {
- return utils::FixedBlockAllocator<128, 4096>::getInstance()
- ->allocateBlock();
+ return utils::FixedBlockAllocator<128, 8192>::getInstance().allocateBlock();
}
TRANSPORT_ALWAYS_INLINE void deallocate(void *pointer) {
- utils::FixedBlockAllocator<128, 4096>::getInstance()->deallocateBlock(
+ utils::FixedBlockAllocator<128, 8192>::getInstance().deallocateBlock(
pointer);
}
#else
@@ -159,33 +156,16 @@ class Pool {
public:
Pool(asio::io_service &io_service) : io_service_(io_service) {
increasePendingInterestPool();
- increaseInterestPool();
- increaseContentObjectPool();
}
TRANSPORT_ALWAYS_INLINE void increasePendingInterestPool() {
// Create pool of pending interests to reuse
- for (uint32_t i = 0; i < pool_size; i++) {
+ for (uint32_t i = 0; i < pit_size; i++) {
pending_interests_pool_.add(new PendingInterest(
Interest::Ptr(nullptr),
std::make_unique<asio::steady_timer>(io_service_)));
}
}
-
- TRANSPORT_ALWAYS_INLINE void increaseInterestPool() {
- // Create pool of interests to reuse
- for (uint32_t i = 0; i < pool_size; i++) {
- interest_pool_.add(new Interest());
- }
- }
-
- TRANSPORT_ALWAYS_INLINE void increaseContentObjectPool() {
- // Create pool of content object to reuse
- for (uint32_t i = 0; i < pool_size; i++) {
- content_object_pool_.add(new ContentObject());
- }
- }
-
PendingInterest::Ptr getPendingInterest() {
auto res = pending_interests_pool_.get();
while (TRANSPORT_EXPECT_FALSE(!res.first)) {
@@ -196,35 +176,15 @@ class Pool {
return std::move(res.second);
}
- TRANSPORT_ALWAYS_INLINE ContentObject::Ptr getContentObject() {
- auto res = content_object_pool_.get();
- while (TRANSPORT_EXPECT_FALSE(!res.first)) {
- increaseContentObjectPool();
- res = content_object_pool_.get();
- }
-
- return std::move(res.second);
- }
-
- TRANSPORT_ALWAYS_INLINE Interest::Ptr getInterest() {
- auto res = interest_pool_.get();
- while (TRANSPORT_EXPECT_FALSE(!res.first)) {
- increaseInterestPool();
- res = interest_pool_.get();
- }
-
- return std::move(res.second);
- }
-
private:
utils::ObjectPool<PendingInterest> pending_interests_pool_;
- utils::ObjectPool<ContentObject> content_object_pool_;
- utils::ObjectPool<Interest> interest_pool_;
asio::io_service &io_service_;
};
} // namespace portal_details
+class PortalConfiguration;
+
using PendingInterestHashTable =
std::unordered_map<uint32_t, PendingInterest::Ptr>;
@@ -250,32 +210,32 @@ using interface::BindConfig;
* The portal class is not thread safe, appropriate locking is required by the
* users of this class.
*/
-template <typename ForwarderInt>
-class Portal {
- static_assert(
- std::is_base_of<ForwarderInterface<ForwarderInt,
- typename ForwarderInt::ConnectorType>,
- ForwarderInt>::value,
- "ForwarderInt must inherit from ForwarderInterface!");
+class Portal {
public:
using ConsumerCallback = interface::Portal::ConsumerCallback;
using ProducerCallback = interface::Portal::ProducerCallback;
+ friend class PortalConfiguration;
+
Portal() : Portal(internal_io_service_) {}
Portal(asio::io_service &io_service)
- : io_service_(io_service),
+ : io_module_(nullptr, [](IoModule *module) { IoModule::unload(module); }),
+ io_service_(io_service),
packet_pool_(io_service),
app_name_("libtransport_application"),
consumer_callback_(nullptr),
producer_callback_(nullptr),
- connector_(std::bind(&Portal::processIncomingMessages, this,
- std::placeholders::_1),
- std::bind(&Portal::setLocalRoutes, this), io_service_,
- app_name_),
- forwarder_interface_(connector_) {}
-
+ is_consumer_(false) {
+ /**
+ * This workaroung allows to initialize memory for packet buffers *before*
+ * any static variables that may be initialized in the io_modules. In this
+ * way static variables in modules will be destroyed before the packet
+ * memory.
+ */
+ PacketManager<>::getInstance();
+ }
/**
* Set the consumer callback.
*
@@ -304,7 +264,7 @@ class Portal {
*/
TRANSPORT_ALWAYS_INLINE void setOutputInterface(
const std::string &output_interface) {
- forwarder_interface_.setOutputInterface(output_interface);
+ io_module_->setOutputInterface(output_interface);
}
/**
@@ -314,8 +274,19 @@ class Portal {
* is a consumer or a producer.
*/
TRANSPORT_ALWAYS_INLINE void connect(bool is_consumer = true) {
- pending_interest_hash_table_.reserve(portal_details::pool_size);
- forwarder_interface_.connect(is_consumer);
+ if (!io_module_) {
+ pending_interest_hash_table_.reserve(portal_details::pit_size);
+ io_module_.reset(IoModule::load(io_module_path_.c_str()));
+ assert(io_module_);
+
+ io_module_->init(std::bind(&Portal::processIncomingMessages, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3),
+ std::bind(&Portal::setLocalRoutes, this), io_service_,
+ app_name_);
+ io_module_->connect(is_consumer);
+ is_consumer_ = is_consumer;
+ }
}
/**
@@ -324,13 +295,19 @@ class Portal {
~Portal() { killConnection(); }
/**
+ * Compute name hash
+ */
+ TRANSPORT_ALWAYS_INLINE uint32_t getHash(const Name &name) {
+ return name.getHash32() + name.getSuffix();
+ }
+
+ /**
* Check if there is already a pending interest for a given name.
*
* @param name - The interest name.
*/
TRANSPORT_ALWAYS_INLINE bool interestIsPending(const Name &name) {
- auto it =
- pending_interest_hash_table_.find(name.getHash32() + name.getSuffix());
+ auto it = pending_interest_hash_table_.find(getHash(name));
if (it != pending_interest_hash_table_.end()) {
return true;
}
@@ -357,31 +334,46 @@ class Portal {
OnContentObjectCallback &&on_content_object_callback = UNSET_CALLBACK,
OnInterestTimeoutCallback &&on_interest_timeout_callback =
UNSET_CALLBACK) {
- uint32_t hash =
- interest->getName().getHash32() + interest->getName().getSuffix();
// Send it
- forwarder_interface_.send(*interest);
-
- auto pending_interest = packet_pool_.getPendingInterest();
- pending_interest->setInterest(std::move(interest));
- pending_interest->setOnContentObjectCallback(
- std::move(on_content_object_callback));
- pending_interest->setOnTimeoutCallback(
- std::move(on_interest_timeout_callback));
- pending_interest->startCountdown(portal_details::makeCustomAllocatorHandler(
- async_callback_memory_, std::bind(&Portal<ForwarderInt>::timerHandler,
- this, std::placeholders::_1, hash)));
+ interest->encodeSuffixes();
+ io_module_->send(*interest);
+
+ uint32_t initial_hash = interest->getName().getHash32();
+ auto hash = initial_hash + interest->getName().getSuffix();
+ uint32_t *suffix = interest->firstSuffix();
+ auto n_suffixes = interest->numberOfSuffixes();
+ uint32_t counter = 0;
+ // Set timers
+ do {
+ auto pending_interest = packet_pool_.getPendingInterest();
+ pending_interest->setInterest(std::move(interest));
+ pending_interest->setOnContentObjectCallback(
+ std::move(on_content_object_callback));
+ pending_interest->setOnTimeoutCallback(
+ std::move(on_interest_timeout_callback));
+
+ pending_interest->startCountdown(
+ portal_details::makeCustomAllocatorHandler(
+ async_callback_memory_, std::bind(&Portal::timerHandler, this,
+ std::placeholders::_1, hash)));
+
+ auto it = pending_interest_hash_table_.find(hash);
+ if (it != pending_interest_hash_table_.end()) {
+ it->second->cancelTimer();
- auto it = pending_interest_hash_table_.find(hash);
- if (it != pending_interest_hash_table_.end()) {
- it->second->cancelTimer();
+ // Get reference to interest packet in order to have it destroyed.
+ auto _int = it->second->getInterest();
+ it->second = std::move(pending_interest);
+ } else {
+ pending_interest_hash_table_[hash] = std::move(pending_interest);
+ }
- // Get reference to interest packet in order to have it destroyed.
- auto _int = it->second->getInterest();
- it->second = std::move(pending_interest);
- } else {
- pending_interest_hash_table_[hash] = std::move(pending_interest);
- }
+ if (suffix) {
+ hash = initial_hash + *suffix;
+ suffix++;
+ }
+
+ } while (counter++ < n_suffixes);
}
/**
@@ -423,9 +415,9 @@ class Portal {
* @param config - The configuration for the local forwarder binding.
*/
TRANSPORT_ALWAYS_INLINE void bind(const BindConfig &config) {
- forwarder_interface_.setContentStoreSize(config.csReserved());
+ assert(io_module_);
+ io_module_->setContentStoreSize(config.csReserved());
served_namespaces_.push_back(config.prefix());
-
setLocalRoutes();
}
@@ -460,7 +452,7 @@ class Portal {
*/
TRANSPORT_ALWAYS_INLINE void sendContentObject(
ContentObject &content_object) {
- forwarder_interface_.send(content_object);
+ io_module_->send(content_object);
}
/**
@@ -482,7 +474,7 @@ class Portal {
* Disconnect the transport from the local forwarder.
*/
TRANSPORT_ALWAYS_INLINE void killConnection() {
- forwarder_interface_.closeConnection();
+ io_module_->closeConnection();
}
/**
@@ -497,6 +489,17 @@ class Portal {
}
/**
+ * Remove one pending interest.
+ */
+ TRANSPORT_ALWAYS_INLINE void clearOne(const Name &name) {
+ if (!io_service_.stopped()) {
+ io_service_.dispatch(std::bind(&Portal::doClearOne, this, name));
+ } else {
+ doClearOne(name);
+ }
+ }
+
+ /**
* Get a reference to the io_service object.
*/
TRANSPORT_ALWAYS_INLINE asio::io_service &getIoService() {
@@ -508,8 +511,8 @@ class Portal {
*/
TRANSPORT_ALWAYS_INLINE void registerRoute(Prefix &prefix) {
served_namespaces_.push_back(prefix);
- if (connector_.isConnected()) {
- forwarder_interface_.registerRoute(prefix);
+ if (io_module_->isConnected()) {
+ io_module_->registerRoute(prefix);
}
}
@@ -530,36 +533,49 @@ class Portal {
}
/**
+ * Remove one pending interest.
+ */
+ TRANSPORT_ALWAYS_INLINE void doClearOne(const Name &name) {
+ auto it = pending_interest_hash_table_.find(getHash(name));
+
+ if (it != pending_interest_hash_table_.end()) {
+ it->second->cancelTimer();
+
+ // Get interest packet from pending interest and do nothing with it. It
+ // will get destroyed as it goes out of scope.
+ auto _int = it->second->getInterest();
+
+ pending_interest_hash_table_.erase(it);
+ }
+ }
+
+ /**
* Callback called by the underlying connector upon reception of a packet from
* the local forwarder.
*
* @param packet_buffer - The bytes of the packet.
*/
TRANSPORT_ALWAYS_INLINE void processIncomingMessages(
- Packet::MemBufPtr &&packet_buffer) {
+ Connector *c, utils::MemBuf &buffer, const std::error_code &ec) {
bool is_stopped = io_service_.stopped();
if (TRANSPORT_EXPECT_FALSE(is_stopped)) {
return;
}
- if (TRANSPORT_EXPECT_FALSE(
- ForwarderInt::isControlMessage(packet_buffer->data()))) {
- processControlMessage(std::move(packet_buffer));
+ if (TRANSPORT_EXPECT_FALSE(io_module_->isControlMessage(buffer.data()))) {
+ processControlMessage(buffer);
return;
}
- Packet::Format format = Packet::getFormatFromBuffer(
- packet_buffer->data(), packet_buffer->length());
+ // The buffer is a base class for an interest or a content object
+ Packet &packet_buffer = static_cast<Packet &>(buffer);
+ auto format = packet_buffer.getFormat();
if (TRANSPORT_EXPECT_TRUE(_is_tcp(format))) {
- if (!Packet::isInterest(packet_buffer->data())) {
- auto content_object = packet_pool_.getContentObject();
- content_object->replace(std::move(packet_buffer));
- processContentObject(std::move(content_object));
+ if (is_consumer_) {
+ processContentObject(static_cast<ContentObject &>(packet_buffer));
} else {
- auto interest = packet_pool_.getInterest();
- interest->replace(std::move(packet_buffer));
- processInterest(std::move(interest));
+ processInterest(static_cast<Interest &>(packet_buffer));
}
} else {
TRANSPORT_LOGE("Received not supported packet. Ignoring it.");
@@ -573,16 +589,16 @@ class Portal {
*/
TRANSPORT_ALWAYS_INLINE void setLocalRoutes() {
for (auto &prefix : served_namespaces_) {
- if (connector_.isConnected()) {
- forwarder_interface_.registerRoute(prefix);
+ if (io_module_->isConnected()) {
+ io_module_->registerRoute(prefix);
}
}
}
- TRANSPORT_ALWAYS_INLINE void processInterest(Interest::Ptr &&interest) {
+ TRANSPORT_ALWAYS_INLINE void processInterest(Interest &interest) {
// Interest for a producer
if (TRANSPORT_EXPECT_TRUE(producer_callback_ != nullptr)) {
- producer_callback_->onInterest(std::move(interest));
+ producer_callback_->onInterest(interest);
}
}
@@ -595,24 +611,27 @@ class Portal {
* @param content_object - The data packet
*/
TRANSPORT_ALWAYS_INLINE void processContentObject(
- ContentObject::Ptr &&content_object) {
- uint32_t hash = content_object->getName().getHash32() +
- content_object->getName().getSuffix();
+ ContentObject &content_object) {
+ TRANSPORT_LOGD("processContentObject %s",
+ content_object.getName().toString().c_str());
+ uint32_t hash = getHash(content_object.getName());
auto it = pending_interest_hash_table_.find(hash);
if (it != pending_interest_hash_table_.end()) {
+ TRANSPORT_LOGD("Found pending interest.");
+
PendingInterest::Ptr interest_ptr = std::move(it->second);
pending_interest_hash_table_.erase(it);
interest_ptr->cancelTimer();
auto _int = interest_ptr->getInterest();
if (interest_ptr->getOnDataCallback() != UNSET_CALLBACK) {
- interest_ptr->on_content_object_callback_(std::move(_int),
- std::move(content_object));
+ interest_ptr->on_content_object_callback_(*_int, content_object);
} else if (consumer_callback_) {
- consumer_callback_->onContentObject(std::move(_int),
- std::move(content_object));
+ consumer_callback_->onContentObject(*_int, content_object);
}
+ } else {
+ TRANSPORT_LOGD("No interest pending for received content object.");
}
}
@@ -622,12 +641,13 @@ class Portal {
* them.
*/
TRANSPORT_ALWAYS_INLINE void processControlMessage(
- Packet::MemBufPtr &&packet_buffer) {
- forwarder_interface_.processControlMessageReply(std::move(packet_buffer));
+ utils::MemBuf &packet_buffer) {
+ io_module_->processControlMessageReply(packet_buffer);
}
private:
portal_details::HandlerMemory async_callback_memory_;
+ std::unique_ptr<IoModule, void (*)(IoModule *)> io_module_;
asio::io_service &io_service_;
asio::io_service internal_io_service_;
@@ -641,8 +661,19 @@ class Portal {
ConsumerCallback *consumer_callback_;
ProducerCallback *producer_callback_;
- typename ForwarderInt::ConnectorType connector_;
- ForwarderInt forwarder_interface_;
+ bool is_consumer_;
+
+ private:
+ static std::string defaultIoModule();
+ static void parseIoModuleConfiguration(const libconfig::Setting &io_config,
+ std::error_code &ec);
+ static void getModuleConfiguration(
+ interface::global_config::ConfigurationObject &conf, std::error_code &ec);
+ static void setModuleConfiguration(
+ const interface::global_config::ConfigurationObject &conf,
+ std::error_code &ec);
+ static interface::global_config::IoModuleConfiguration conf_;
+ static std::string io_module_path_;
};
} // namespace core
diff --git a/libtransport/src/core/prefix.cc b/libtransport/src/core/prefix.cc
index eea4aeb..1e2b2ed 100644
--- a/libtransport/src/core/prefix.cc
+++ b/libtransport/src/core/prefix.cc
@@ -25,12 +25,12 @@ extern "C" {
#include <hicn/transport/portability/win_portability.h>
#endif
+#include <openssl/rand.h>
+
#include <cstring>
#include <memory>
#include <random>
-#include <openssl/rand.h>
-
namespace transport {
namespace core {
@@ -99,7 +99,7 @@ void Prefix::buildPrefix(std::string &prefix, uint16_t prefix_length,
ip_prefix_.family = family;
}
-std::unique_ptr<Sockaddr> Prefix::toSockaddr() {
+std::unique_ptr<Sockaddr> Prefix::toSockaddr() const {
Sockaddr *ret = nullptr;
switch (ip_prefix_.family) {
@@ -120,14 +120,14 @@ std::unique_ptr<Sockaddr> Prefix::toSockaddr() {
return std::unique_ptr<Sockaddr>(ret);
}
-uint16_t Prefix::getPrefixLength() { return ip_prefix_.len; }
+uint16_t Prefix::getPrefixLength() const { return ip_prefix_.len; }
Prefix &Prefix::setPrefixLength(uint16_t prefix_length) {
ip_prefix_.len = prefix_length;
return *this;
}
-int Prefix::getAddressFamily() { return ip_prefix_.family; }
+int Prefix::getAddressFamily() const { return ip_prefix_.family; }
Prefix &Prefix::setAddressFamily(int address_family) {
ip_prefix_.family = address_family;
@@ -226,7 +226,7 @@ Name Prefix::getRandomName() const {
ip_prefix_.len;
size_t size = (size_t)ceil((float)addr_len / 8.0);
- uint8_t *buffer = (uint8_t *) malloc(sizeof(uint8_t) * size);
+ uint8_t *buffer = (uint8_t *)malloc(sizeof(uint8_t) * size);
RAND_bytes(buffer, size);
@@ -332,7 +332,7 @@ bool Prefix::checkPrefixLengthAndAddressFamily(uint16_t prefix_length,
return true;
}
-ip_prefix_t &Prefix::toIpPrefixStruct() { return ip_prefix_; }
+const ip_prefix_t &Prefix::toIpPrefixStruct() const { return ip_prefix_; }
} // namespace core
diff --git a/libtransport/src/core/rs.cc b/libtransport/src/core/rs.cc
new file mode 100644
index 0000000..44b5852
--- /dev/null
+++ b/libtransport/src/core/rs.cc
@@ -0,0 +1,365 @@
+
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core/fec.h>
+#include <core/rs.h>
+#include <hicn/transport/core/global_object_pool.h>
+#include <hicn/transport/utils/log.h>
+
+#include <cassert>
+
+namespace transport {
+namespace core {
+namespace fec {
+
+BlockCode::BlockCode(uint32_t k, uint32_t n, struct fec_parms *code)
+ : Packets(),
+ k_(k),
+ n_(n),
+ code_(code),
+ max_buffer_size_(0),
+ current_block_size_(0),
+ to_decode_(false) {
+ sorted_index_.reserve(n);
+}
+
+bool BlockCode::addRepairSymbol(const fec::buffer &packet, uint32_t i) {
+ // Get index
+ to_decode_ = true;
+ TRANSPORT_LOGD("adding symbol of size %zu", packet->length());
+ return addSymbol(packet, i, packet->length() - sizeof(fec_header));
+}
+
+bool BlockCode::addSourceSymbol(const fec::buffer &packet, uint32_t i) {
+ return addSymbol(packet, i, packet->length());
+}
+
+bool BlockCode::addSymbol(const fec::buffer &packet, uint32_t i,
+ std::size_t size) {
+ if (size > max_buffer_size_) {
+ max_buffer_size_ = size;
+ }
+
+ operator[](current_block_size_++) = std::make_pair(i, packet);
+
+ if (current_block_size_ >= k_) {
+ if (to_decode_) {
+ decode();
+ } else {
+ encode();
+ }
+
+ clear();
+ return false;
+ }
+
+ return true;
+}
+
+void BlockCode::encode() {
+ gf *data[n_];
+ std::uint16_t old_values[k_];
+ uint32_t base = operator[](0).first;
+
+ // Set packet length in first 2 bytes
+ for (uint32_t i = 0; i < k_; i++) {
+ auto &packet = operator[](i).second;
+
+ TRANSPORT_LOGD("Current buffer size: %zu", packet->length());
+
+ auto ret = packet->ensureCapacityAndFillUnused(max_buffer_size_, 0);
+ if (TRANSPORT_EXPECT_FALSE(ret == false)) {
+ throw errors::RuntimeException(
+ "Provided packet is not suitable to be used as FEC source packet. "
+ "Aborting.");
+ }
+
+ // Buffers should hold 2 bytes before the starting pointer, in order to be
+ // able to set the length for the encoding operation
+ packet->prepend(2);
+ uint16_t *length = reinterpret_cast<uint16_t *>(packet->writableData());
+
+ old_values[i] = *length;
+ *length = htons(packet->length() - LEN_SIZE_BYTES);
+
+ data[i] = packet->writableData();
+ }
+
+ // Finish to fill source block with the buffers to hold the repair symbols
+ for (uint32_t i = k_; i < n_; i++) {
+ // For the moment we get a packet from the pool here.. later we'll need to
+ // require a packet from the caller with a callback.
+ auto packet = PacketManager<>::getInstance().getMemBuf();
+ packet->append(max_buffer_size_ + sizeof(fec_header) + LEN_SIZE_BYTES);
+ fec_header *fh = reinterpret_cast<fec_header *>(packet->writableData());
+
+ fh->setSeqNumberBase(base);
+ fh->setNFecSymbols(n_ - k_);
+ fh->setEncodedSymbolId(i);
+ fh->setSourceBlockLen(n_);
+
+ packet->trimStart(sizeof(fec_header));
+
+ data[i] = packet->writableData();
+ operator[](i) = std::make_pair(i, std::move(packet));
+ }
+
+ // Generate repair symbols and put them in corresponding buffers
+ TRANSPORT_LOGD("Calling encode with max_buffer_size_ = %zu",
+ max_buffer_size_);
+ for (uint32_t i = k_; i < n_; i++) {
+ fec_encode(code_, data, data[i], i, max_buffer_size_ + LEN_SIZE_BYTES);
+ }
+
+ // Restore original content of buffer space used to store the length
+ for (uint32_t i = 0; i < k_; i++) {
+ auto &packet = operator[](i).second;
+ uint16_t *length = reinterpret_cast<uint16_t *>(packet->writableData());
+ *length = old_values[i];
+ packet->trimStart(2);
+ }
+
+ // Re-include header in repair packets
+ for (uint32_t i = k_; i < n_; i++) {
+ auto &packet = operator[](i).second;
+ TRANSPORT_LOGD("Produced repair symbol of size = %zu", packet->length());
+ packet->prepend(sizeof(fec_header));
+ }
+}
+
+void BlockCode::decode() {
+ gf *data[k_];
+ uint32_t index[k_];
+
+ for (uint32_t i = 0; i < k_; i++) {
+ auto &packet = operator[](i).second;
+ index[i] = operator[](i).first;
+ sorted_index_[i] = index[i];
+
+ if (index[i] < k_) {
+ TRANSPORT_LOGD("DECODE SOURCE - index %u - Current buffer size: %zu",
+ index[i], packet->length());
+ // This is a source packet. We need to prepend the length and fill
+ // additional space to 0
+
+ // Buffers should hold 2 bytes before the starting pointer, in order to be
+ // able to set the length for the encoding operation
+ packet->prepend(LEN_SIZE_BYTES);
+ packet->ensureCapacityAndFillUnused(max_buffer_size_, 0);
+ uint16_t *length = reinterpret_cast<uint16_t *>(packet->writableData());
+
+ *length = htons(packet->length() - LEN_SIZE_BYTES);
+ } else {
+ TRANSPORT_LOGD("DECODE SYMBOL - index %u - Current buffer size: %zu",
+ index[i], packet->length());
+ packet->trimStart(sizeof(fec_header));
+ }
+
+ data[i] = packet->writableData();
+ }
+
+ // We decode the source block
+ TRANSPORT_LOGD("Calling decode with max_buffer_size_ = %zu",
+ max_buffer_size_);
+ fec_decode(code_, data, reinterpret_cast<int *>(index), max_buffer_size_);
+
+ // Find the index in the block for recovered packets
+ for (uint32_t i = 0; i < k_; i++) {
+ if (index[i] != i) {
+ for (uint32_t j = 0; j < k_; j++)
+ if (sorted_index_[j] == uint32_t(index[i])) {
+ sorted_index_[j] = i;
+ }
+ }
+ }
+
+ // Reorder block by index with in-place sorting
+ for (uint32_t i = 0; i < k_; i++) {
+ for (uint32_t j = sorted_index_[i]; j != i; j = sorted_index_[i]) {
+ std::swap(sorted_index_[j], sorted_index_[i]);
+ std::swap(operator[](j), operator[](i));
+ }
+ }
+
+ // Adjust length according to the one written in the source packet
+ for (uint32_t i = 0; i < k_; i++) {
+ auto &packet = operator[](i).second;
+ uint16_t *length = reinterpret_cast<uint16_t *>(packet->writableData());
+ packet->trimStart(2);
+ packet->setLength(ntohs(*length));
+ }
+}
+
+void BlockCode::clear() {
+ current_block_size_ = 0;
+ max_buffer_size_ = 0;
+ sorted_index_.clear();
+ to_decode_ = false;
+}
+
+void rs::MatrixDeleter::operator()(struct fec_parms *params) {
+ fec_free(params);
+}
+
+rs::Codes rs::createCodes() {
+ Codes ret;
+
+ ret.emplace(std::make_pair(1, 3), Matrix(fec_new(1, 3), MatrixDeleter()));
+ ret.emplace(std::make_pair(6, 10), Matrix(fec_new(6, 10), MatrixDeleter()));
+ ret.emplace(std::make_pair(8, 32), Matrix(fec_new(8, 32), MatrixDeleter()));
+ ret.emplace(std::make_pair(10, 30), Matrix(fec_new(10, 30), MatrixDeleter()));
+ ret.emplace(std::make_pair(16, 24), Matrix(fec_new(16, 24), MatrixDeleter()));
+ ret.emplace(std::make_pair(10, 40), Matrix(fec_new(10, 40), MatrixDeleter()));
+ ret.emplace(std::make_pair(10, 60), Matrix(fec_new(10, 60), MatrixDeleter()));
+ ret.emplace(std::make_pair(10, 90), Matrix(fec_new(10, 90), MatrixDeleter()));
+
+ return ret;
+}
+
+rs::Codes rs::codes_ = createCodes();
+
+rs::rs(uint32_t k, uint32_t n) : k_(k), n_(n) {}
+
+void rs::setFECCallback(const PacketsReady &callback) {
+ fec_callback_ = callback;
+}
+
+encoder::encoder(uint32_t k, uint32_t n)
+ : rs(k, n),
+ current_code_(codes_[std::make_pair(k, n)].get()),
+ source_block_(k_, n_, current_code_) {}
+
+void encoder::consume(const fec::buffer &packet, uint32_t index) {
+ if (!source_block_.addSourceSymbol(packet, index)) {
+ std::vector<buffer> repair_packets;
+ for (uint32_t i = k_; i < n_; i++) {
+ repair_packets.emplace_back(std::move(source_block_[i].second));
+ }
+ fec_callback_(repair_packets);
+ }
+}
+
+decoder::decoder(uint32_t k, uint32_t n) : rs(k, n) {}
+
+void decoder::recoverPackets(SourceBlocks::iterator &src_block_it) {
+ TRANSPORT_LOGD("recoverPackets for %u", k_);
+ auto &src_block = src_block_it->second;
+ std::vector<buffer> source_packets(k_);
+ for (uint32_t i = 0; i < src_block.getK(); i++) {
+ source_packets[i] = std::move(src_block[i].second);
+ }
+
+ fec_callback_(source_packets);
+ processed_source_blocks_.emplace(src_block_it->first);
+
+ auto it = parked_packets_.find(src_block_it->first);
+ if (it != parked_packets_.end()) {
+ parked_packets_.erase(it);
+ }
+
+ src_blocks_.erase(src_block_it);
+}
+
+void decoder::consume(const fec::buffer &packet, uint32_t index) {
+ // Normalize index
+ auto i = index % n_;
+
+ // Get base
+ uint32_t base = index - i;
+
+ TRANSPORT_LOGD(
+ "Decoder consume called for source symbol. BASE = %u, index = %u and i = "
+ "%u",
+ base, index, i);
+
+ // check if a source block already exist for this symbol. If it does not
+ // exist, we lazily park this packet until we receive a repair symbol for the
+ // same block. This is done for 2 reason:
+ // 1) If we receive all the source packets of a block, we do not need to
+ // recover anything.
+ // 2) Sender may change n and k at any moment, so we construct the source
+ // block based on the (n, k) values written in the fec header. This is
+ // actually not used right now, since we use fixed value of n and k passed
+ // at construction time, but it paves the ground for a more dynamic
+ // protocol that may come in the future.
+ auto it = src_blocks_.find(base);
+ if (it != src_blocks_.end()) {
+ auto ret = it->second.addSourceSymbol(packet, i);
+ if (!ret) {
+ recoverPackets(it);
+ }
+ } else {
+ TRANSPORT_LOGD("Adding to parked source packets");
+ auto ret = parked_packets_.emplace(
+ base, std::vector<std::pair<buffer, uint32_t> >());
+ ret.first->second.emplace_back(packet, i);
+ }
+}
+
+void decoder::consume(const fec::buffer &packet) {
+ // Repair symbol! Get index and base source block.
+ fec_header *h = reinterpret_cast<fec_header *>(packet->writableData());
+ auto i = h->getEncodedSymbolId();
+ auto base = h->getSeqNumberBase();
+ auto n = h->getSourceBlockLen();
+ auto k = n - h->getNFecSymbols();
+
+ TRANSPORT_LOGD(
+ "Decoder consume called for repair symbol. BASE = %u, index = %u and i = "
+ "%u",
+ base, base + i, i);
+
+ // check if a source block already exist for this symbol
+ auto it = src_blocks_.find(base);
+ if (it == src_blocks_.end()) {
+ // Create new source block
+ auto code_it = codes_.find(std::make_pair(k, n));
+ if (code_it == codes_.end()) {
+ TRANSPORT_LOGE("Code for k = %u and n = %u does not exist.", k_, n_);
+ return;
+ }
+
+ auto emplace_result =
+ src_blocks_.emplace(base, BlockCode(k, n, code_it->second.get()));
+ it = emplace_result.first;
+
+ // Check in the parked packets and insert any packet that is part of this
+ // source block
+
+ auto it2 = parked_packets_.find(base);
+ if (it2 != parked_packets_.end()) {
+ for (auto &packet_index : it2->second) {
+ auto ret =
+ it->second.addSourceSymbol(packet_index.first, packet_index.second);
+ if (!ret) {
+ recoverPackets(it);
+ // Finish to delete packets in same source block that were
+ // eventually not used
+ return;
+ }
+ }
+ }
+ }
+
+ auto ret = it->second.addRepairSymbol(packet, i);
+ if (!ret) {
+ recoverPackets(it);
+ }
+}
+
+} // namespace fec
+} // namespace core
+} // namespace transport
diff --git a/libtransport/src/core/rs.h b/libtransport/src/core/rs.h
new file mode 100644
index 0000000..d630bd2
--- /dev/null
+++ b/libtransport/src/core/rs.h
@@ -0,0 +1,338 @@
+
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <arpa/inet.h>
+#include <hicn/transport/utils/membuf.h>
+#include <protocols/fec_base.h>
+
+#include <array>
+#include <cstdint>
+#include <map>
+#include <unordered_set>
+#include <vector>
+
+namespace transport {
+namespace core {
+
+namespace fec {
+
+static const constexpr uint16_t MAX_SOURCE_BLOCK_SIZE = 128;
+
+using buffer = typename utils::MemBuf::Ptr;
+/**
+ * We use a std::array in place of std::vector to avoid to allocate a new vector
+ * in the heap every time we build a new source block, which would be bad if
+ * the decoder has to allocate several source blocks for many concurrent bases.
+ * std::array allows to be constructed in place, saving the allocation at the
+ * price os knowing in advance its size.
+ */
+using Packets = std::array<std::pair<uint32_t, buffer>, MAX_SOURCE_BLOCK_SIZE>;
+
+/**
+ * FEC Header, prepended to symbol packets.
+ */
+struct fec_header {
+ /**
+ * The base source packet seq_number this FES symbol refers to
+ */
+ uint32_t seq_number;
+
+ /**
+ * The index of the symbol inside the source block, between k and n - 1
+ */
+ uint8_t encoded_symbol_id;
+
+ /**
+ * Total length of source block (n)
+ */
+ uint8_t source_block_len;
+
+ /**
+ * Total number of symbols (n - k)
+ */
+ uint8_t n_fec_symbols;
+
+ /**
+ * Align header to 64 bits
+ */
+ uint8_t padding;
+
+ void setSeqNumberBase(uint32_t suffix) { seq_number = htonl(suffix); }
+ uint32_t getSeqNumberBase() { return ntohl(seq_number); }
+ void setEncodedSymbolId(uint8_t esi) { encoded_symbol_id = esi; }
+ uint8_t getEncodedSymbolId() { return encoded_symbol_id; }
+ void setSourceBlockLen(uint8_t k) { source_block_len = k; }
+ uint8_t getSourceBlockLen() { return source_block_len; }
+ void setNFecSymbols(uint8_t n_r) { n_fec_symbols = n_r; }
+ uint8_t getNFecSymbols() { return n_fec_symbols; }
+};
+
+/**
+ * This class models the source block itself.
+ */
+class BlockCode : public Packets {
+ /**
+ * For variable length packet we need to prepend to the padded payload the
+ * real length of the packet. This is *not* sent over the network.
+ */
+ static constexpr std::size_t LEN_SIZE_BYTES = 2;
+
+ public:
+ BlockCode(uint32_t k, uint32_t n, struct fec_parms *code);
+
+ /**
+ * Add a repair symbol to the dource block.
+ */
+ bool addRepairSymbol(const fec::buffer &packet, uint32_t i);
+
+ /**
+ * Add a source symbol to the source block.
+ */
+ bool addSourceSymbol(const fec::buffer &packet, uint32_t i);
+
+ /**
+ * Get current length of source block.
+ */
+ std::size_t length() { return current_block_size_; }
+
+ /**
+ * Get N
+ */
+ uint32_t getN() { return n_; }
+
+ /**
+ * Get K
+ */
+ uint32_t getK() { return k_; }
+
+ /**
+ * Clear source block
+ */
+ void clear();
+
+ private:
+ /**
+ * Add symbol to source block
+ **/
+ bool addSymbol(const fec::buffer &packet, uint32_t i, std::size_t size);
+
+ /**
+ * Starting from k source symbols, get the n - k repair symbols
+ */
+ void encode();
+
+ /**
+ * Starting from k symbols (mixed repair and source), get k source symbols.
+ * NOTE: It does not make sense to retrieve the k source symbols using the
+ * very same k source symbols. With the current implementation that case can
+ * never happen.
+ */
+ void decode();
+
+ private:
+ uint32_t k_;
+ uint32_t n_;
+ struct fec_parms *code_;
+ std::size_t max_buffer_size_;
+ std::size_t current_block_size_;
+ std::vector<uint32_t> sorted_index_;
+ bool to_decode_;
+};
+
+/**
+ * This class contains common parameters between the fec encoder and decoder.
+ * In particular it contains:
+ * - The callback to be called when symbols are encoded / decoded
+ * - The reference to the static reed-solomon parameters, allocated at program
+ * startup
+ * - N and K. Ideally they are useful only for the encoder (the decoder can
+ * retrieve them from the FEC header). However right now we assume sender and
+ * receiver agreed on the parameters k and n to use. We will introduce a control
+ * message later to negotiate them, so that decoder cah dynamically change them
+ * during the download.
+ */
+class rs {
+ /**
+ * Deleter for static preallocated reed-solomon parameters.
+ */
+ struct MatrixDeleter {
+ void operator()(struct fec_parms *params);
+ };
+
+ /**
+ * unique_ptr to reed-solomon parameters, with custom deleter to call fec_free
+ * at the end of the program
+ */
+ using Matrix = std::unique_ptr<struct fec_parms, MatrixDeleter>;
+
+ /**
+ * Key to retrieve static preallocated reed-solomon parameters. It is pair of
+ * k and n
+ */
+ using Code = std::pair<std::uint32_t /* k */, std::uint32_t /* n */>;
+
+ /**
+ * Custom hash function for (k, n) pair.
+ */
+ struct CodeHasher {
+ std::size_t operator()(const transport::core::fec::rs::Code &code) const {
+ uint64_t ret = uint64_t(code.first) << 32 | uint64_t(code.second);
+ return std::hash<uint64_t>{}(ret);
+ }
+ };
+
+ protected:
+ /**
+ * Callback to be called after the encode or the decode operations. In the
+ * former case it will contain the symbols, while in the latter the sources.
+ */
+ using PacketsReady = std::function<void(std::vector<buffer> &)>;
+
+ /**
+ * The sequence number base.
+ */
+ using SNBase = std::uint32_t;
+
+ /**
+ * The map of source blocks, used at the decoder side. For the encoding
+ * operation we can use one source block only, since packet are produced in
+ * order.
+ */
+ using SourceBlocks = std::unordered_map<SNBase, BlockCode>;
+
+ /**
+ * Map (k, n) -> reed-solomon parameter
+ */
+ using Codes = std::unordered_map<Code, Matrix, CodeHasher>;
+
+ public:
+ rs(uint32_t k, uint32_t n);
+ ~rs() = default;
+
+ /**
+ * Set callback to call after packet encoding / decoding
+ */
+ void setFECCallback(const PacketsReady &callback);
+
+ virtual void clear() { processed_source_blocks_.clear(); }
+
+ private:
+ /**
+ * Create reed-solomon codes at program startup.
+ */
+ static Codes createCodes();
+
+ protected:
+ bool processed(SNBase seq_base) {
+ return processed_source_blocks_.find(seq_base) !=
+ processed_source_blocks_.end();
+ }
+
+ std::uint32_t k_;
+ std::uint32_t n_;
+ PacketsReady fec_callback_;
+
+ /**
+ * Keep track of processed source blocks
+ */
+ std::unordered_set<SNBase> processed_source_blocks_;
+
+ static Codes codes_;
+};
+
+/**
+ * The reed-solomon encoder. It is feeded with source symbols and it provide
+ * repair-symbols through the fec_callback_
+ */
+class encoder : public rs {
+ public:
+ encoder(uint32_t k, uint32_t n);
+ /**
+ * Always consume source symbols.
+ */
+ void consume(const fec::buffer &packet, uint32_t index);
+
+ void clear() override {
+ rs::clear();
+ source_block_.clear();
+ }
+
+ private:
+ struct fec_parms *current_code_;
+ /**
+ * The source block. As soon as it is filled with k source symbols, the
+ * encoder calls the callback fec_callback_ and the resets the block 0, ready
+ * to accept another batch of k source symbols.
+ */
+ BlockCode source_block_;
+};
+
+/**
+ * The reed-solomon encoder. It is feeded with source/repair symbols and it
+ * provides the original source symbols through the fec_callback_
+ */
+class decoder : public rs {
+ public:
+ decoder(uint32_t k, uint32_t n);
+
+ /**
+ * Consume source symbol
+ */
+ void consume(const fec::buffer &packet, uint32_t i);
+
+ /**
+ * Consume repair symbol
+ */
+ void consume(const fec::buffer &packet);
+
+ /**
+ * Clear decoder to reuse
+ */
+ void clear() override {
+ rs::clear();
+ src_blocks_.clear();
+ parked_packets_.clear();
+ }
+
+ private:
+ void recoverPackets(SourceBlocks::iterator &src_block_it);
+
+ private:
+ /**
+ * Map of source blocks. We use a map because we may receive symbols belonging
+ * to diffreent source blocks at the same time, so we need to be able to
+ * decode many source symbols at the same time.
+ */
+ SourceBlocks src_blocks_;
+
+ /**
+ * Unordered Map of source symbols for which we did not receive any repair
+ * symbol in the same source block. Notably this happens when:
+ *
+ * - We receive the source symbols first and the repair symbols after
+ * - We received only source symbols for a given block. In that case it does
+ * not make any sense to build the source block, since we received all the
+ * source packet of the block.
+ */
+ std::unordered_map<uint32_t, std::vector<std::pair<buffer, uint32_t>>>
+ parked_packets_;
+};
+
+} // namespace fec
+
+} // namespace core
+
+} // namespace transport
diff --git a/libtransport/src/core/tcp_socket_connector.h b/libtransport/src/core/tcp_socket_connector.h
index c57123e..9dbd250 100644
--- a/libtransport/src/core/tcp_socket_connector.h
+++ b/libtransport/src/core/tcp_socket_connector.h
@@ -15,12 +15,11 @@
#pragma once
+#include <core/connector.h>
#include <hicn/transport/config.h>
#include <hicn/transport/core/name.h>
#include <hicn/transport/utils/branch_prediction.h>
-#include <core/connector.h>
-
#include <asio.hpp>
#include <asio/steady_timer.hpp>
#include <deque>
diff --git a/libtransport/src/http/client_connection.cc b/libtransport/src/http/client_connection.cc
index 7a3a636..a24a821 100644
--- a/libtransport/src/http/client_connection.cc
+++ b/libtransport/src/http/client_connection.cc
@@ -43,12 +43,6 @@ class HTTPClientConnection::Implementation
read_buffer_(nullptr),
response_(std::make_shared<HTTPResponse>()),
timer_(nullptr) {
- consumer_.setSocketOption(
- ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY,
- (ConsumerContentObjectVerificationCallback)std::bind(
- &Implementation::verifyData, this, std::placeholders::_1,
- std::placeholders::_2));
-
consumer_.setSocketOption(ConsumerCallbacksOptions::READ_CALLBACK, this);
consumer_.connect();
@@ -124,10 +118,10 @@ class HTTPClientConnection::Implementation
return *http_client_;
}
- HTTPClientConnection &setCertificate(const std::string &cert_path) {
- if (consumer_.setSocketOption(GeneralTransportOptions::CERTIFICATE,
- cert_path) == SOCKET_OPTION_NOT_SET) {
- throw errors::RuntimeException("Error setting the certificate.");
+ HTTPClientConnection &setVerifier(std::shared_ptr<auth::Verifier> verifier) {
+ if (consumer_.setSocketOption(GeneralTransportOptions::VERIFIER,
+ verifier) == SOCKET_OPTION_NOT_SET) {
+ throw errors::RuntimeException("Error setting the verifier.");
}
return *http_client_;
@@ -177,17 +171,6 @@ class HTTPClientConnection::Implementation
consumer_.stop();
}
- bool verifyData(interface::ConsumerSocket &c,
- const core::ContentObject &contentObject) {
- if (contentObject.getPayloadType() == PayloadType::CONTENT_OBJECT) {
- TRANSPORT_LOGI("VERIFY CONTENT\n");
- } else if (contentObject.getPayloadType() == PayloadType::MANIFEST) {
- TRANSPORT_LOGI("VERIFY MANIFEST\n");
- }
-
- return true;
- }
-
void processLeavingInterest(interface::ConsumerSocket &c,
const core::Interest &interest) {
if (interest.payloadSize() == 0) {
@@ -307,9 +290,9 @@ HTTPClientConnection &HTTPClientConnection::setTimeout(
return implementation_->setTimeout(timeout);
}
-HTTPClientConnection &HTTPClientConnection::setCertificate(
- const std::string &cert_path) {
- return implementation_->setCertificate(cert_path);
+HTTPClientConnection &HTTPClientConnection::setVerifier(
+ std::shared_ptr<auth::Verifier> verifier) {
+ return implementation_->setVerifier(verifier);
}
} // namespace http
diff --git a/libtransport/src/implementation/CMakeLists.txt b/libtransport/src/implementation/CMakeLists.txt
index 5423a76..392c99e 100644
--- a/libtransport/src/implementation/CMakeLists.txt
+++ b/libtransport/src/implementation/CMakeLists.txt
@@ -13,13 +13,8 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
-list(APPEND SOURCE_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/rtc_socket_producer.cc
-)
-
list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/socket.h
- ${CMAKE_CURRENT_SOURCE_DIR}/rtc_socket_producer.h
${CMAKE_CURRENT_SOURCE_DIR}/socket_producer.h
${CMAKE_CURRENT_SOURCE_DIR}/socket_consumer.h
)
@@ -27,15 +22,16 @@ list(APPEND HEADER_FILES
if (${OPENSSL_VERSION} VERSION_EQUAL "1.1.1a" OR ${OPENSSL_VERSION} VERSION_GREATER "1.1.1a")
list(APPEND SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/tls_socket_producer.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/tls_rtc_socket_producer.cc
+ # ${CMAKE_CURRENT_SOURCE_DIR}/tls_rtc_socket_producer.cc
${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_producer.cc
${CMAKE_CURRENT_SOURCE_DIR}/tls_socket_consumer.cc
${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_consumer.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/socket.cc
)
list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/tls_socket_producer.h
- ${CMAKE_CURRENT_SOURCE_DIR}/tls_rtc_socket_producer.h
+ # ${CMAKE_CURRENT_SOURCE_DIR}/tls_rtc_socket_producer.h
${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_producer.h
${CMAKE_CURRENT_SOURCE_DIR}/tls_socket_consumer.h
${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_consumer.h
diff --git a/libtransport/src/implementation/p2psecure_socket_consumer.cc b/libtransport/src/implementation/p2psecure_socket_consumer.cc
index 9b79850..8c7c175 100644
--- a/libtransport/src/implementation/p2psecure_socket_consumer.cc
+++ b/libtransport/src/implementation/p2psecure_socket_consumer.cc
@@ -15,7 +15,6 @@
#include <implementation/p2psecure_socket_consumer.h>
#include <interfaces/tls_socket_consumer.h>
-
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/tls1.h>
@@ -175,7 +174,6 @@ P2PSecureConsumerSocket::P2PSecureConsumerSocket(
: ConsumerSocket(consumer, handshake_protocol),
name_(),
tls_consumer_(nullptr),
- buf_pool_(),
decrypted_content_(),
payload_(),
head_(),
diff --git a/libtransport/src/implementation/p2psecure_socket_consumer.h b/libtransport/src/implementation/p2psecure_socket_consumer.h
index d4c3b26..a35a503 100644
--- a/libtransport/src/implementation/p2psecure_socket_consumer.h
+++ b/libtransport/src/implementation/p2psecure_socket_consumer.h
@@ -16,7 +16,6 @@
#pragma once
#include <hicn/transport/interfaces/socket_consumer.h>
-
#include <implementation/tls_socket_consumer.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
@@ -75,7 +74,6 @@ class P2PSecureConsumerSocket : public ConsumerSocket,
BIO_METHOD *bio_meth_;
/* Chain of MemBuf to be used as a temporary buffer to pass descypted data
* from the underlying layer to the application */
- utils::ObjectPool<utils::MemBuf> buf_pool_;
std::unique_ptr<utils::MemBuf> decrypted_content_;
/* Chain of MemBuf holding the payload to be written into interest or data */
std::unique_ptr<utils::MemBuf> payload_;
diff --git a/libtransport/src/implementation/p2psecure_socket_producer.cc b/libtransport/src/implementation/p2psecure_socket_producer.cc
index 15c7d25..6dff2ba 100644
--- a/libtransport/src/implementation/p2psecure_socket_producer.cc
+++ b/libtransport/src/implementation/p2psecure_socket_producer.cc
@@ -14,13 +14,11 @@
*/
#include <hicn/transport/core/interest.h>
-
#include <implementation/p2psecure_socket_producer.h>
-#include <implementation/tls_rtc_socket_producer.h>
+// #include <implementation/tls_rtc_socket_producer.h>
#include <implementation/tls_socket_producer.h>
#include <interfaces/tls_rtc_socket_producer.h>
#include <interfaces/tls_socket_producer.h>
-
#include <openssl/bio.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
@@ -34,7 +32,8 @@ namespace implementation {
P2PSecureProducerSocket::P2PSecureProducerSocket(
interface::ProducerSocket *producer_socket)
- : ProducerSocket(producer_socket),
+ : ProducerSocket(producer_socket,
+ ProductionProtocolAlgorithms::BYTE_STREAM),
mtx_(),
cv_(),
map_producers(),
@@ -42,8 +41,9 @@ P2PSecureProducerSocket::P2PSecureProducerSocket(
P2PSecureProducerSocket::P2PSecureProducerSocket(
interface::ProducerSocket *producer_socket, bool rtc,
- const std::shared_ptr<utils::Identity> &identity)
- : ProducerSocket(producer_socket),
+ const std::shared_ptr<auth::Identity> &identity)
+ : ProducerSocket(producer_socket,
+ ProductionProtocolAlgorithms::BYTE_STREAM),
rtc_(rtc),
mtx_(),
cv_(),
@@ -51,9 +51,9 @@ P2PSecureProducerSocket::P2PSecureProducerSocket(
list_producers() {
/* Setup SSL context (identity and parameter to use TLS 1.3) */
der_cert_ = parcKeyStore_GetDEREncodedCertificate(
- (identity->getSigner()->getKeyStore()));
+ (identity->getSigner()->getParcKeyStore()));
der_prk_ = parcKeyStore_GetDEREncodedPrivateKey(
- (identity->getSigner()->getKeyStore()));
+ (identity->getSigner()->getParcKeyStore()));
int cert_size = parcBuffer_Limit(der_cert_);
int prk_size = parcBuffer_Limit(der_prk_);
@@ -88,15 +88,20 @@ void P2PSecureProducerSocket::initSessionSocket(
producer->setSocketOption(MAKE_MANIFEST, this->making_manifest_);
producer->setSocketOption(DATA_PACKET_SIZE,
(uint32_t)(this->data_packet_size_));
- producer->output_buffer_.setLimit(this->output_buffer_.getLimit());
+ uint32_t output_buffer_size = 0;
+ this->getSocketOption(GeneralTransportOptions::OUTPUT_BUFFER_SIZE,
+ output_buffer_size);
+ producer->setSocketOption(GeneralTransportOptions::OUTPUT_BUFFER_SIZE,
+ output_buffer_size);
if (!rtc_) {
producer->setInterface(new interface::TLSProducerSocket(producer.get()));
} else {
- TLSRTCProducerSocket *rtc_producer =
- dynamic_cast<TLSRTCProducerSocket *>(producer.get());
- rtc_producer->setInterface(
- new interface::TLSRTCProducerSocket(rtc_producer));
+ // TODO
+ // TLSRTCProducerSocket *rtc_producer =
+ // dynamic_cast<TLSRTCProducerSocket *>(producer.get());
+ // rtc_producer->setInterface(
+ // new interface::TLSRTCProducerSocket(rtc_producer));
}
}
@@ -114,8 +119,9 @@ void P2PSecureProducerSocket::onInterestCallback(interface::ProducerSocket &p,
tls_producer =
std::make_unique<TLSProducerSocket>(nullptr, this, interest.getName());
} else {
- tls_producer = std::make_unique<TLSRTCProducerSocket>(nullptr, this,
- interest.getName());
+ // TODO
+ // tls_producer = std::make_unique<TLSRTCProducerSocket>(nullptr, this,
+ // interest.getName());
}
initSessionSocket(tls_producer);
@@ -129,15 +135,19 @@ void P2PSecureProducerSocket::onInterestCallback(interface::ProducerSocket &p,
tls_producer_ptr->onInterest(*tls_producer_ptr, interest);
tls_producer_ptr->async_accept();
} else {
- TLSRTCProducerSocket *rtc_producer_ptr =
- dynamic_cast<TLSRTCProducerSocket *>(tls_producer_ptr);
- rtc_producer_ptr->onInterest(*rtc_producer_ptr, interest);
- rtc_producer_ptr->async_accept();
+ // TODO
+ // TLSRTCProducerSocket *rtc_producer_ptr =
+ // dynamic_cast<TLSRTCProducerSocket *>(tls_producer_ptr);
+ // rtc_producer_ptr->onInterest(*rtc_producer_ptr, interest);
+ // rtc_producer_ptr->async_accept();
}
}
-void P2PSecureProducerSocket::produce(const uint8_t *buffer,
- size_t buffer_size) {
+uint32_t P2PSecureProducerSocket::produceDatagram(
+ const Name &content_name, std::unique_ptr<utils::MemBuf> &&buffer) {
+ // TODO
+ throw errors::NotImplementedException();
+
if (!rtc_) {
throw errors::RuntimeException(
"RTC must be the transport protocol to start the production of current "
@@ -148,16 +158,20 @@ void P2PSecureProducerSocket::produce(const uint8_t *buffer,
if (list_producers.empty()) cv_.wait(lck);
- for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++) {
- TLSRTCProducerSocket *rtc_producer =
- dynamic_cast<TLSRTCProducerSocket *>(it->get());
- rtc_producer->produce(utils::MemBuf::copyBuffer(buffer, buffer_size));
- }
+ // TODO
+ // for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
+ // {
+ // TLSRTCProducerSocket *rtc_producer =
+ // dynamic_cast<TLSRTCProducerSocket *>(it->get());
+ // rtc_producer->produce(utils::MemBuf::copyBuffer(buffer, buffer_size));
+ // }
+
+ return 0;
}
-uint32_t P2PSecureProducerSocket::produce(
- Name content_name, std::unique_ptr<utils::MemBuf> &&buffer, bool is_last,
- uint32_t start_offset) {
+uint32_t P2PSecureProducerSocket::produceStream(
+ const Name &content_name, std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last, uint32_t start_offset) {
if (rtc_) {
throw errors::RuntimeException(
"RTC transport protocol is not compatible with the production of "
@@ -170,16 +184,17 @@ uint32_t P2PSecureProducerSocket::produce(
if (list_producers.empty()) cv_.wait(lck);
for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
- segments +=
- (*it)->produce(content_name, buffer->clone(), is_last, start_offset);
+ segments += (*it)->produceStream(content_name, buffer->clone(), is_last,
+ start_offset);
return segments;
}
-uint32_t P2PSecureProducerSocket::produce(Name content_name,
- const uint8_t *buffer,
- size_t buffer_size, bool is_last,
- uint32_t start_offset) {
+uint32_t P2PSecureProducerSocket::produceStream(const Name &content_name,
+ const uint8_t *buffer,
+ size_t buffer_size,
+ bool is_last,
+ uint32_t start_offset) {
if (rtc_) {
throw errors::RuntimeException(
"RTC transport protocol is not compatible with the production of "
@@ -191,29 +206,31 @@ uint32_t P2PSecureProducerSocket::produce(Name content_name,
if (list_producers.empty()) cv_.wait(lck);
for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
- segments += (*it)->produce(content_name, buffer, buffer_size, is_last,
- start_offset);
+ segments += (*it)->produceStream(content_name, buffer, buffer_size, is_last,
+ start_offset);
return segments;
}
-void P2PSecureProducerSocket::asyncProduce(const Name &content_name,
- const uint8_t *buf,
- size_t buffer_size, bool is_last,
- uint32_t *start_offset) {
- if (rtc_) {
- throw errors::RuntimeException(
- "RTC transport protocol is not compatible with the production of "
- "current data. Aborting.");
- }
-
- std::unique_lock<std::mutex> lck(mtx_);
- if (list_producers.empty()) cv_.wait(lck);
-
- for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++) {
- (*it)->asyncProduce(content_name, buf, buffer_size, is_last, start_offset);
- }
-}
+// void P2PSecureProducerSocket::asyncProduce(const Name &content_name,
+// const uint8_t *buf,
+// size_t buffer_size, bool is_last,
+// uint32_t *start_offset) {
+// if (rtc_) {
+// throw errors::RuntimeException(
+// "RTC transport protocol is not compatible with the production of "
+// "current data. Aborting.");
+// }
+
+// std::unique_lock<std::mutex> lck(mtx_);
+// if (list_producers.empty()) cv_.wait(lck);
+
+// for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
+// {
+// (*it)->asyncProduce(content_name, buf, buffer_size, is_last,
+// start_offset);
+// }
+// }
void P2PSecureProducerSocket::asyncProduce(
Name content_name, std::unique_ptr<utils::MemBuf> &&buffer, bool is_last,
@@ -269,7 +286,7 @@ int P2PSecureProducerSocket::setSocketOption(
int P2PSecureProducerSocket::setSocketOption(
int socket_option_key,
- const std::shared_ptr<utils::Signer> &socket_option_value) {
+ const std::shared_ptr<auth::Signer> &socket_option_value) {
if (!list_producers.empty())
for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
(*it)->setSocketOption(socket_option_key, socket_option_value);
@@ -323,16 +340,6 @@ int P2PSecureProducerSocket::setSocketOption(int socket_option_key,
}
int P2PSecureProducerSocket::setSocketOption(
- int socket_option_key, std::list<Prefix> socket_option_value) {
- if (!list_producers.empty())
- for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
- (*it)->setSocketOption(socket_option_key, socket_option_value);
-
- return ProducerSocket::setSocketOption(socket_option_key,
- socket_option_value);
-}
-
-int P2PSecureProducerSocket::setSocketOption(
int socket_option_key, ProducerContentObjectCallback socket_option_value) {
if (!list_producers.empty())
for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
@@ -361,17 +368,7 @@ int P2PSecureProducerSocket::setSocketOption(
}
int P2PSecureProducerSocket::setSocketOption(
- int socket_option_key, utils::CryptoHashType socket_option_value) {
- if (!list_producers.empty())
- for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
- (*it)->setSocketOption(socket_option_key, socket_option_value);
-
- return ProducerSocket::setSocketOption(socket_option_key,
- socket_option_value);
-}
-
-int P2PSecureProducerSocket::setSocketOption(
- int socket_option_key, utils::CryptoSuite socket_option_value) {
+ int socket_option_key, auth::CryptoHashType socket_option_value) {
if (!list_producers.empty())
for (auto it = list_producers.cbegin(); it != list_producers.cend(); it++)
(*it)->setSocketOption(socket_option_key, socket_option_value);
diff --git a/libtransport/src/implementation/p2psecure_socket_producer.h b/libtransport/src/implementation/p2psecure_socket_producer.h
index bfc9fc2..b7c3d19 100644
--- a/libtransport/src/implementation/p2psecure_socket_producer.h
+++ b/libtransport/src/implementation/p2psecure_socket_producer.h
@@ -15,15 +15,14 @@
#pragma once
-#include <hicn/transport/security/identity.h>
-#include <hicn/transport/security/signer.h>
-
+#include <hicn/transport/auth/identity.h>
+#include <hicn/transport/auth/signer.h>
#include <implementation/socket_producer.h>
-#include <implementation/tls_rtc_socket_producer.h>
+// #include <implementation/tls_rtc_socket_producer.h>
#include <implementation/tls_socket_producer.h>
+#include <openssl/ssl.h>
#include <utils/content_store.h>
-#include <openssl/ssl.h>
#include <condition_variable>
#include <forward_list>
#include <mutex>
@@ -33,39 +32,40 @@ namespace implementation {
class P2PSecureProducerSocket : public ProducerSocket {
friend class TLSProducerSocket;
- friend class TLSRTCProducerSocket;
+ // TODO
+ // friend class TLSRTCProducerSocket;
public:
explicit P2PSecureProducerSocket(interface::ProducerSocket *producer_socket);
explicit P2PSecureProducerSocket(
interface::ProducerSocket *producer_socket, bool rtc,
- const std::shared_ptr<utils::Identity> &identity);
+ const std::shared_ptr<auth::Identity> &identity);
~P2PSecureProducerSocket();
- void produce(const uint8_t *buffer, size_t buffer_size) override;
+ uint32_t produceDatagram(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer) override;
- uint32_t produce(Name content_name, const uint8_t *buffer, size_t buffer_size,
- bool is_last = true, uint32_t start_offset = 0) override;
+ uint32_t produceStream(const Name &content_name, const uint8_t *buffer,
+ size_t buffer_size, bool is_last = true,
+ uint32_t start_offset = 0) override;
- uint32_t produce(Name content_name, std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last = true, uint32_t start_offset = 0) override;
+ uint32_t produceStream(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last = true,
+ uint32_t start_offset = 0) override;
void asyncProduce(Name content_name, std::unique_ptr<utils::MemBuf> &&buffer,
bool is_last, uint32_t offset,
uint32_t **last_segment = nullptr) override;
- void asyncProduce(const Name &suffix, const uint8_t *buf, size_t buffer_size,
- bool is_last = true,
- uint32_t *start_offset = nullptr) override;
-
int setSocketOption(int socket_option_key,
ProducerInterestCallback socket_option_value) override;
int setSocketOption(
int socket_option_key,
- const std::shared_ptr<utils::Signer> &socket_option_value) override;
+ const std::shared_ptr<auth::Signer> &socket_option_value) override;
int setSocketOption(int socket_option_key,
uint32_t socket_option_value) override;
@@ -75,9 +75,6 @@ class P2PSecureProducerSocket : public ProducerSocket {
int setSocketOption(int socket_option_key,
Name *socket_option_value) override;
- int setSocketOption(int socket_option_key,
- std::list<Prefix> socket_option_value) override;
-
int setSocketOption(
int socket_option_key,
ProducerContentObjectCallback socket_option_value) override;
@@ -86,16 +83,13 @@ class P2PSecureProducerSocket : public ProducerSocket {
ProducerContentCallback socket_option_value) override;
int setSocketOption(int socket_option_key,
- utils::CryptoHashType socket_option_value) override;
-
- int setSocketOption(int socket_option_key,
- utils::CryptoSuite socket_option_value) override;
+ auth::CryptoHashType socket_option_value) override;
int setSocketOption(int socket_option_key,
const std::string &socket_option_value) override;
using ProducerSocket::getSocketOption;
- using ProducerSocket::onInterest;
+ // using ProducerSocket::onInterest;
protected:
/* Callback invoked once an interest has been received and its payload
diff --git a/libtransport/src/implementation/socket.cc b/libtransport/src/implementation/socket.cc
new file mode 100644
index 0000000..2e21f2b
--- /dev/null
+++ b/libtransport/src/implementation/socket.cc
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core/global_configuration.h>
+#include <implementation/socket.h>
+
+namespace transport {
+namespace implementation {
+
+Socket::Socket(std::shared_ptr<core::Portal> &&portal)
+ : portal_(std::move(portal)), is_async_(false) {}
+
+} // namespace implementation
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/implementation/socket.h b/libtransport/src/implementation/socket.h
index 2e51f30..cf22c03 100644
--- a/libtransport/src/implementation/socket.h
+++ b/libtransport/src/implementation/socket.h
@@ -15,13 +15,12 @@
#pragma once
+#include <core/facade.h>
#include <hicn/transport/config.h>
#include <hicn/transport/interfaces/callbacks.h>
#include <hicn/transport/interfaces/socket_options_default_values.h>
#include <hicn/transport/interfaces/socket_options_keys.h>
-#include <core/facade.h>
-
#define SOCKET_OPTION_GET 0
#define SOCKET_OPTION_NOT_GET 1
#define SOCKET_OPTION_SET 2
@@ -32,56 +31,23 @@ namespace transport {
namespace implementation {
// Forward Declarations
-template <typename PortalType>
class Socket;
-// Define the portal and its connector, depending on the compilation options
-// passed by the build tool.
-using HicnForwarderPortal = core::HicnForwarderPortal;
-
-#ifdef __linux__
-#ifndef __ANDROID__
-using RawSocketPortal = core::RawSocketPortal;
-#endif
-#endif
-
-#ifdef __vpp__
-using VPPForwarderPortal = core::VPPForwarderPortal;
-using BaseSocket = Socket<VPPForwarderPortal>;
-using BasePortal = VPPForwarderPortal;
-#else
-using BaseSocket = Socket<HicnForwarderPortal>;
-using BasePortal = HicnForwarderPortal;
-#endif
-
-template <typename PortalType>
class Socket {
- static_assert(std::is_same<PortalType, HicnForwarderPortal>::value
-#ifdef __linux__
-#ifndef __ANDROID__
- || std::is_same<PortalType, RawSocketPortal>::value
-#ifdef __vpp__
- || std::is_same<PortalType, VPPForwarderPortal>::value
-#endif
-#endif
- ,
-#else
- ,
-
-#endif
- "This class is not allowed as Portal");
-
public:
- using Portal = PortalType;
-
- virtual asio::io_service &getIoService() = 0;
-
virtual void connect() = 0;
-
virtual bool isRunning() = 0;
+ virtual asio::io_service &getIoService() { return portal_->getIoService(); }
+
protected:
+ Socket(std::shared_ptr<core::Portal> &&portal);
+
virtual ~Socket(){};
+
+ protected:
+ std::shared_ptr<core::Portal> portal_;
+ bool is_async_;
};
} // namespace implementation
diff --git a/libtransport/src/implementation/socket_consumer.h b/libtransport/src/implementation/socket_consumer.h
index 8796592..a7b6ac4 100644
--- a/libtransport/src/implementation/socket_consumer.h
+++ b/libtransport/src/implementation/socket_consumer.h
@@ -13,15 +13,17 @@
* limitations under the License.
*/
+#pragma once
+
#include <hicn/transport/interfaces/socket_consumer.h>
#include <hicn/transport/interfaces/socket_options_default_values.h>
#include <hicn/transport/interfaces/statistics.h>
-#include <hicn/transport/security/verifier.h>
+#include <hicn/transport/auth/verifier.h>
#include <hicn/transport/utils/event_thread.h>
#include <protocols/cbr.h>
-#include <protocols/protocol.h>
#include <protocols/raaqm.h>
-#include <protocols/rtc.h>
+#include <protocols/rtc/rtc.h>
+#include <protocols/transport_protocol.h>
namespace transport {
namespace implementation {
@@ -30,12 +32,12 @@ using namespace core;
using namespace interface;
using ReadCallback = interface::ConsumerSocket::ReadCallback;
-class ConsumerSocket : public Socket<BasePortal> {
+class ConsumerSocket : public Socket {
private:
ConsumerSocket(interface::ConsumerSocket *consumer, int protocol,
- std::shared_ptr<Portal> &&portal)
- : consumer_interface_(consumer),
- portal_(portal),
+ std::shared_ptr<core::Portal> &&portal)
+ : Socket(std::move(portal)),
+ consumer_interface_(consumer),
async_downloader_(),
interest_lifetime_(default_values::interest_lifetime),
min_window_size_(default_values::min_window_size),
@@ -54,16 +56,13 @@ class ConsumerSocket : public Socket<BasePortal> {
rate_estimation_observer_(nullptr),
rate_estimation_batching_parameter_(default_values::batch),
rate_estimation_choice_(0),
- is_async_(false),
- verifier_(std::make_shared<utils::Verifier>()),
+ verifier_(std::make_shared<auth::VoidVerifier>()),
verify_signature_(false),
- key_content_(false),
reset_window_(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),
stats_summary_(VOID_HANDLER),
read_callback_(nullptr),
timer_interval_milliseconds_(0),
@@ -75,7 +74,7 @@ class ConsumerSocket : public Socket<BasePortal> {
break;
case TransportProtocolAlgorithms::RTC:
transport_protocol_ =
- std::make_unique<protocol::RTCTransportProtocol>(this);
+ std::make_unique<protocol::rtc::RTCTransportProtocol>(this);
break;
case TransportProtocolAlgorithms::RAAQM:
default:
@@ -87,12 +86,12 @@ class ConsumerSocket : public Socket<BasePortal> {
public:
ConsumerSocket(interface::ConsumerSocket *consumer, int protocol)
- : ConsumerSocket(consumer, protocol, std::make_shared<Portal>()) {}
+ : ConsumerSocket(consumer, protocol, std::make_shared<core::Portal>()) {}
ConsumerSocket(interface::ConsumerSocket *consumer, int protocol,
asio::io_service &io_service)
: ConsumerSocket(consumer, protocol,
- std::make_shared<Portal>(io_service)) {
+ std::make_shared<core::Portal>(io_service)) {
is_async_ = true;
}
@@ -138,8 +137,6 @@ class ConsumerSocket : public Socket<BasePortal> {
return CONSUMER_RUNNING;
}
- bool verifyKeyPackets() { return transport_protocol_->verifyKeyPackets(); }
-
void stop() {
if (transport_protocol_->isRunning()) {
transport_protocol_->stop();
@@ -152,8 +149,6 @@ class ConsumerSocket : public Socket<BasePortal> {
}
}
- asio::io_service &getIoService() { return portal_->getIoService(); }
-
virtual int setSocketOption(int socket_option_key,
ReadCallback *socket_option_value) {
// Reschedule the function on the io_service to avoid race condition in
@@ -316,12 +311,6 @@ class ConsumerSocket : public Socket<BasePortal> {
break;
}
- case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY:
- if (socket_option_value == VOID_HANDLER) {
- on_content_object_verification_ = VOID_HANDLER;
- break;
- }
-
default:
return SOCKET_OPTION_NOT_SET;
}
@@ -334,16 +323,6 @@ class ConsumerSocket : public Socket<BasePortal> {
int result = SOCKET_OPTION_NOT_SET;
if (!transport_protocol_->isRunning()) {
switch (socket_option_key) {
- case GeneralTransportOptions::VERIFY_SIGNATURE:
- verify_signature_ = socket_option_value;
- result = SOCKET_OPTION_SET;
- break;
-
- case GeneralTransportOptions::KEY_CONTENT:
- key_content_ = socket_option_value;
- result = SOCKET_OPTION_SET;
- break;
-
case RaaqmTransportOptions::PER_SESSION_CWINDOW_RESET:
reset_window_ = socket_option_value;
result = SOCKET_OPTION_SET;
@@ -377,29 +356,6 @@ class ConsumerSocket : public Socket<BasePortal> {
});
}
- int setSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationCallback socket_option_value) {
- // Reschedule the function on the io_service to avoid race condition in
- // case setSocketOption is called while the io_service is running.
- return rescheduleOnIOService(
- socket_option_key, socket_option_value,
- [this](int socket_option_key,
- ConsumerContentObjectVerificationCallback socket_option_value)
- -> int {
- switch (socket_option_key) {
- case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY:
- on_content_object_verification_ = socket_option_value;
- break;
-
- default:
- return SOCKET_OPTION_NOT_SET;
- }
-
- return SOCKET_OPTION_SET;
- });
- }
-
int setSocketOption(int socket_option_key,
ConsumerInterestCallback socket_option_value) {
// Reschedule the function on the io_service to avoid race condition in
@@ -433,51 +389,6 @@ class ConsumerSocket : public Socket<BasePortal> {
});
}
- int setSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback socket_option_value) {
- return rescheduleOnIOService(
- socket_option_key, socket_option_value,
- [this](
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback socket_option_value)
- -> int {
- switch (socket_option_key) {
- case ConsumerCallbacksOptions::VERIFICATION_FAILED:
- verification_failed_callback_ = socket_option_value;
- break;
-
- default:
- return SOCKET_OPTION_NOT_SET;
- }
-
- return SOCKET_OPTION_SET;
- });
- }
-
- // int setSocketOption(
- // int socket_option_key,
- // ConsumerContentObjectVerificationFailedCallback socket_option_value) {
- // return rescheduleOnIOService(
- // socket_option_key, socket_option_value,
- // [this](
- // int socket_option_key,
- // ConsumerContentObjectVerificationFailedCallback
- // socket_option_value)
- // -> int {
- // switch (socket_option_key) {
- // case ConsumerCallbacksOptions::VERIFICATION_FAILED:
- // verification_failed_callback_ = socket_option_value;
- // break;
-
- // default:
- // return SOCKET_OPTION_NOT_SET;
- // }
-
- // return SOCKET_OPTION_SET;
- // });
- // }
-
int setSocketOption(int socket_option_key, IcnObserver *socket_option_value) {
utils::SpinLock::Acquire locked(guard_raaqm_params_);
switch (socket_option_key) {
@@ -494,7 +405,7 @@ class ConsumerSocket : public Socket<BasePortal> {
int setSocketOption(
int socket_option_key,
- const std::shared_ptr<utils::Verifier> &socket_option_value) {
+ const std::shared_ptr<auth::Verifier> &socket_option_value) {
int result = SOCKET_OPTION_NOT_SET;
if (!transport_protocol_->isRunning()) {
switch (socket_option_key) {
@@ -516,14 +427,6 @@ class ConsumerSocket : public Socket<BasePortal> {
int result = SOCKET_OPTION_NOT_SET;
if (!transport_protocol_->isRunning()) {
switch (socket_option_key) {
- case GeneralTransportOptions::CERTIFICATE:
- key_id_ = verifier_->addKeyFromCertificate(socket_option_value);
-
- if (key_id_ != nullptr) {
- result = SOCKET_OPTION_SET;
- }
- break;
-
case DataLinkOptions::OUTPUT_INTERFACE:
output_interface_ = socket_option_value;
portal_->setOutputInterface(output_interface_);
@@ -642,14 +545,6 @@ class ConsumerSocket : public Socket<BasePortal> {
socket_option_value = transport_protocol_->isRunning();
break;
- case GeneralTransportOptions::VERIFY_SIGNATURE:
- socket_option_value = verify_signature_;
- break;
-
- case GeneralTransportOptions::KEY_CONTENT:
- socket_option_value = key_content_;
- break;
-
case GeneralTransportOptions::ASYNC_MODE:
socket_option_value = is_async_;
break;
@@ -699,29 +594,6 @@ class ConsumerSocket : public Socket<BasePortal> {
});
}
- int getSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationCallback **socket_option_value) {
- // Reschedule the function on the io_service to avoid race condition in
- // case setSocketOption is called while the io_service is running.
- return rescheduleOnIOService(
- socket_option_key, socket_option_value,
- [this](int socket_option_key,
- ConsumerContentObjectVerificationCallback **socket_option_value)
- -> int {
- switch (socket_option_key) {
- case ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY:
- *socket_option_value = &on_content_object_verification_;
- break;
-
- default:
- return SOCKET_OPTION_NOT_GET;
- }
-
- return SOCKET_OPTION_GET;
- });
- }
-
int getSocketOption(int socket_option_key,
ConsumerInterestCallback **socket_option_value) {
// Reschedule the function on the io_service to avoid race condition in
@@ -755,30 +627,8 @@ class ConsumerSocket : public Socket<BasePortal> {
});
}
- int getSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback **socket_option_value) {
- // Reschedule the function on the io_service to avoid race condition in
- // case setSocketOption is called while the io_service is running.
- return rescheduleOnIOService(
- socket_option_key, socket_option_value,
- [this](int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback *
- *socket_option_value) -> int {
- switch (socket_option_key) {
- case ConsumerCallbacksOptions::VERIFICATION_FAILED:
- *socket_option_value = &verification_failed_callback_;
- break;
- default:
- return SOCKET_OPTION_NOT_GET;
- }
-
- return SOCKET_OPTION_GET;
- });
- }
-
int getSocketOption(int socket_option_key,
- std::shared_ptr<Portal> &socket_option_value) {
+ std::shared_ptr<core::Portal> &socket_option_value) {
switch (socket_option_key) {
case PORTAL:
socket_option_value = portal_;
@@ -807,7 +657,7 @@ class ConsumerSocket : public Socket<BasePortal> {
}
int getSocketOption(int socket_option_key,
- std::shared_ptr<utils::Verifier> &socket_option_value) {
+ std::shared_ptr<auth::Verifier> &socket_option_value) {
switch (socket_option_key) {
case GeneralTransportOptions::VERIFIER:
socket_option_value = verifier_;
@@ -871,7 +721,7 @@ class ConsumerSocket : public Socket<BasePortal> {
// To enforce type check
std::function<int(int, arg2)> func = lambda_func;
int result = SOCKET_OPTION_SET;
- if (transport_protocol_->isRunning()) {
+ if (transport_protocol_ && transport_protocol_->isRunning()) {
std::mutex mtx;
/* Condition variable for the wait */
std::condition_variable cv;
@@ -898,7 +748,6 @@ class ConsumerSocket : public Socket<BasePortal> {
protected:
interface::ConsumerSocket *consumer_interface_;
- std::shared_ptr<Portal> portal_;
utils::EventThread async_downloader_;
// No need to protect from multiple accesses in the async consumer
@@ -926,13 +775,10 @@ class ConsumerSocket : public Socket<BasePortal> {
int rate_estimation_batching_parameter_;
int rate_estimation_choice_;
- bool is_async_;
-
// Verification parameters
- std::shared_ptr<utils::Verifier> verifier_;
+ std::shared_ptr<auth::Verifier> verifier_;
PARCKeyId *key_id_;
std::atomic_bool verify_signature_;
- bool key_content_;
bool reset_window_;
ConsumerInterestCallback on_interest_retransmission_;
@@ -940,9 +786,7 @@ class ConsumerSocket : public Socket<BasePortal> {
ConsumerInterestCallback on_interest_timeout_;
ConsumerInterestCallback on_interest_satisfied_;
ConsumerContentObjectCallback on_content_object_input_;
- ConsumerContentObjectVerificationCallback on_content_object_verification_;
ConsumerTimerCallback stats_summary_;
- ConsumerContentObjectVerificationFailedCallback verification_failed_callback_;
ReadCallback *read_callback_;
@@ -959,4 +803,4 @@ class ConsumerSocket : public Socket<BasePortal> {
};
} // namespace implementation
-} // namespace transport \ No newline at end of file
+} // namespace transport
diff --git a/libtransport/src/implementation/socket_producer.h b/libtransport/src/implementation/socket_producer.h
index a6f0f96..af69cd8 100644
--- a/libtransport/src/implementation/socket_producer.h
+++ b/libtransport/src/implementation/socket_producer.h
@@ -15,9 +15,11 @@
#pragma once
-#include <hicn/transport/security/signer.h>
+#include <hicn/transport/auth/signer.h>
#include <hicn/transport/utils/event_thread.h>
#include <implementation/socket.h>
+#include <protocols/prod_protocol_bytestream.h>
+#include <protocols/prod_protocol_rtc.h>
#include <utils/content_store.h>
#include <utils/suffix_strategy.h>
@@ -39,21 +41,17 @@ namespace implementation {
using namespace core;
using namespace interface;
-class ProducerSocket : public Socket<BasePortal>,
- public BasePortal::ProducerCallback {
- static constexpr uint32_t burst_size = 256;
-
- public:
- explicit ProducerSocket(interface::ProducerSocket *producer_socket)
- : producer_interface_(producer_socket),
- portal_(std::make_shared<Portal>(io_service_)),
+class ProducerSocket : public Socket {
+ private:
+ ProducerSocket(interface::ProducerSocket *producer_socket, int protocol,
+ std::shared_ptr<core::Portal> &&portal)
+ : Socket(std::move(portal)),
+ producer_interface_(producer_socket),
data_packet_size_(default_values::content_object_packet_size),
content_object_expiry_time_(default_values::content_object_expiry_time),
- output_buffer_(default_values::producer_socket_output_buffer_size),
async_thread_(),
- registration_status_(REGISTRATION_NOT_ATTEMPTED),
making_manifest_(false),
- hash_algorithm_(utils::CryptoHashType::SHA_256),
+ hash_algorithm_(auth::CryptoHashType::SHA_256),
suffix_strategy_(core::NextSegmentCalculationStrategy::INCREMENTAL),
on_interest_input_(VOID_HANDLER),
on_interest_dropped_input_buffer_(VOID_HANDLER),
@@ -65,15 +63,33 @@ class ProducerSocket : public Socket<BasePortal>,
on_content_object_in_output_buffer_(VOID_HANDLER),
on_content_object_output_(VOID_HANDLER),
on_content_object_evicted_from_output_buffer_(VOID_HANDLER),
- on_content_produced_(VOID_HANDLER) {}
-
- virtual ~ProducerSocket() {
- stop();
- if (listening_thread_.joinable()) {
- listening_thread_.join();
+ on_content_produced_(VOID_HANDLER) {
+ switch (protocol) {
+ case ProductionProtocolAlgorithms::RTC_PROD:
+ production_protocol_ =
+ std::make_unique<protocol::RTCProductionProtocol>(this);
+ break;
+ case ProductionProtocolAlgorithms::BYTE_STREAM:
+ default:
+ production_protocol_ =
+ std::make_unique<protocol::ByteStreamProductionProtocol>(this);
+ break;
}
}
+ public:
+ ProducerSocket(interface::ProducerSocket *producer, int protocol)
+ : ProducerSocket(producer, protocol, std::make_shared<core::Portal>()) {}
+
+ ProducerSocket(interface::ProducerSocket *producer, int protocol,
+ asio::io_service &io_service)
+ : ProducerSocket(producer, protocol,
+ std::make_shared<core::Portal>(io_service)) {
+ is_async_ = true;
+ }
+
+ virtual ~ProducerSocket() {}
+
interface::ProducerSocket *getInterface() {
return producer_interface_;
}
@@ -84,296 +100,10 @@ class ProducerSocket : public Socket<BasePortal>,
void connect() override {
portal_->connect(false);
- listening_thread_ = std::thread(std::bind(&ProducerSocket::listen, this));
+ production_protocol_->start();
}
- bool isRunning() override { return !io_service_.stopped(); };
-
- virtual uint32_t produce(Name content_name, const uint8_t *buffer,
- size_t buffer_size, bool is_last = true,
- uint32_t start_offset = 0) {
- return ProducerSocket::produce(
- content_name, utils::MemBuf::copyBuffer(buffer, buffer_size), is_last,
- start_offset);
- }
-
- virtual uint32_t produce(Name content_name,
- std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last = true, uint32_t start_offset = 0) {
- if (TRANSPORT_EXPECT_FALSE(buffer->length() == 0)) {
- return 0;
- }
-
- // Copy the atomic variables to ensure they keep the same value
- // during the production
- std::size_t data_packet_size = data_packet_size_;
- uint32_t content_object_expiry_time = content_object_expiry_time_;
- utils::CryptoHashType hash_algo = hash_algorithm_;
- bool making_manifest = making_manifest_;
- auto suffix_strategy = utils::SuffixStrategyFactory::getSuffixStrategy(
- suffix_strategy_, start_offset);
- std::shared_ptr<utils::Signer> signer;
- getSocketOption(GeneralTransportOptions::SIGNER, signer);
-
- auto buffer_size = buffer->length();
- int bytes_segmented = 0;
- std::size_t header_size;
- std::size_t manifest_header_size = 0;
- std::size_t signature_length = 0;
- std::uint32_t final_block_number = start_offset;
- uint64_t free_space_for_content = 0;
-
- core::Packet::Format format;
- std::shared_ptr<ContentObjectManifest> manifest;
- bool is_last_manifest = false;
-
- // TODO Manifest may still be used for indexing
- if (making_manifest && !signer) {
- TRANSPORT_LOGE("Making manifests without setting producer identity.");
- }
-
- core::Packet::Format hf_format = core::Packet::Format::HF_UNSPEC;
- core::Packet::Format hf_format_ah = core::Packet::Format::HF_UNSPEC;
- if (content_name.getType() == HNT_CONTIGUOUS_V4 ||
- content_name.getType() == HNT_IOV_V4) {
- hf_format = core::Packet::Format::HF_INET_TCP;
- hf_format_ah = core::Packet::Format::HF_INET_TCP_AH;
- } else if (content_name.getType() == HNT_CONTIGUOUS_V6 ||
- content_name.getType() == HNT_IOV_V6) {
- hf_format = core::Packet::Format::HF_INET6_TCP;
- hf_format_ah = core::Packet::Format::HF_INET6_TCP_AH;
- } else {
- throw errors::RuntimeException("Unknown name format.");
- }
-
- format = hf_format;
- if (making_manifest) {
- manifest_header_size = core::Packet::getHeaderSizeFromFormat(
- signer ? hf_format_ah : hf_format,
- signer ? signer->getSignatureLength() : 0);
- } else if (signer) {
- format = hf_format_ah;
- signature_length = signer->getSignatureLength();
- }
-
- header_size =
- core::Packet::getHeaderSizeFromFormat(format, signature_length);
- free_space_for_content = data_packet_size - header_size;
- uint32_t number_of_segments = uint32_t(
- std::ceil(double(buffer_size) / double(free_space_for_content)));
- if (free_space_for_content * number_of_segments < buffer_size) {
- number_of_segments++;
- }
-
- // TODO allocate space for all the headers
- if (making_manifest) {
- uint32_t segment_in_manifest = static_cast<uint32_t>(
- std::floor(double(data_packet_size - manifest_header_size -
- ContentObjectManifest::getManifestHeaderSize()) /
- ContentObjectManifest::getManifestEntrySize()) -
- 1.0);
- uint32_t number_of_manifests = static_cast<uint32_t>(
- std::ceil(float(number_of_segments) / segment_in_manifest));
- final_block_number += number_of_segments + number_of_manifests - 1;
-
- manifest.reset(ContentObjectManifest::createManifest(
- content_name.setSuffix(suffix_strategy->getNextManifestSuffix()),
- core::ManifestVersion::VERSION_1, core::ManifestType::INLINE_MANIFEST,
- hash_algo, is_last_manifest, content_name, suffix_strategy_,
- signer ? signer->getSignatureLength() : 0));
- manifest->setLifetime(content_object_expiry_time);
-
- if (is_last) {
- manifest->setFinalBlockNumber(final_block_number);
- } else {
- manifest->setFinalBlockNumber(utils::SuffixStrategy::INVALID_SUFFIX);
- }
- }
-
- for (unsigned int packaged_segments = 0;
- packaged_segments < number_of_segments; packaged_segments++) {
- if (making_manifest) {
- if (manifest->estimateManifestSize(2) >
- data_packet_size - manifest_header_size) {
- // Send the current manifest
- manifest->encode();
-
- // If identity set, sign manifest
- if (signer) {
- signer->sign(*manifest);
- }
-
- passContentObjectToCallbacks(manifest);
- TRANSPORT_LOGD("Send manifest %s",
- manifest->getName().toString().c_str());
-
- // Send content objects stored in the queue
- while (!content_queue_.empty()) {
- passContentObjectToCallbacks(content_queue_.front());
- TRANSPORT_LOGD(
- "Send content %s",
- content_queue_.front()->getName().toString().c_str());
- content_queue_.pop();
- }
-
- // Create new manifest. The reference to the last manifest has been
- // acquired in the passContentObjectToCallbacks function, so we can
- // safely release this reference
- manifest.reset(ContentObjectManifest::createManifest(
- content_name.setSuffix(suffix_strategy->getNextManifestSuffix()),
- core::ManifestVersion::VERSION_1,
- core::ManifestType::INLINE_MANIFEST, hash_algo, is_last_manifest,
- content_name, suffix_strategy_,
- signer ? signer->getSignatureLength() : 0));
-
- manifest->setLifetime(content_object_expiry_time);
- manifest->setFinalBlockNumber(
- is_last ? final_block_number
- : utils::SuffixStrategy::INVALID_SUFFIX);
- }
- }
-
- auto content_suffix = suffix_strategy->getNextContentSuffix();
- auto content_object = std::make_shared<ContentObject>(
- content_name.setSuffix(content_suffix), format);
- content_object->setLifetime(content_object_expiry_time);
-
- auto b = buffer->cloneOne();
- b->trimStart(free_space_for_content * packaged_segments);
- b->trimEnd(b->length());
-
- if (TRANSPORT_EXPECT_FALSE(packaged_segments == number_of_segments - 1)) {
- b->append(buffer_size - bytes_segmented);
- bytes_segmented += (int)(buffer_size - bytes_segmented);
-
- if (is_last && making_manifest) {
- is_last_manifest = true;
- } else if (is_last) {
- content_object->setRst();
- }
-
- } else {
- b->append(free_space_for_content);
- bytes_segmented += (int)(free_space_for_content);
- }
-
- content_object->appendPayload(std::move(b));
-
- if (making_manifest) {
- using namespace std::chrono_literals;
- utils::CryptoHash hash = content_object->computeDigest(hash_algo);
- manifest->addSuffixHash(content_suffix, hash);
- content_queue_.push(content_object);
- } else {
- if (signer) {
- signer->sign(*content_object);
- }
- passContentObjectToCallbacks(content_object);
- TRANSPORT_LOGD("Send content %s",
- content_object->getName().toString().c_str());
- }
- }
-
- if (making_manifest) {
- if (is_last_manifest) {
- manifest->setFinalManifest(is_last_manifest);
- }
-
- manifest->encode();
- if (signer) {
- signer->sign(*manifest);
- }
-
- passContentObjectToCallbacks(manifest);
- TRANSPORT_LOGD("Send manifest %s",
- manifest->getName().toString().c_str());
-
- while (!content_queue_.empty()) {
- passContentObjectToCallbacks(content_queue_.front());
- TRANSPORT_LOGD("Send content %s",
- content_queue_.front()->getName().toString().c_str());
- content_queue_.pop();
- }
- }
-
- io_service_.post([this]() {
- std::shared_ptr<ContentObject> co;
- while (object_queue_for_callbacks_.pop(co)) {
- if (on_new_segment_) {
- on_new_segment_(*producer_interface_, *co);
- }
-
- if (on_content_object_to_sign_) {
- on_content_object_to_sign_(*producer_interface_, *co);
- }
-
- if (on_content_object_in_output_buffer_) {
- on_content_object_in_output_buffer_(*producer_interface_, *co);
- }
-
- if (on_content_object_output_) {
- on_content_object_output_(*producer_interface_, *co);
- }
- }
- });
-
- io_service_.dispatch([this, buffer_size]() {
- if (on_content_produced_) {
- on_content_produced_(*producer_interface_,
- std::make_error_code(std::errc(0)), buffer_size);
- }
- });
-
- return suffix_strategy->getTotalCount();
- }
-
- virtual void produce(ContentObject &content_object) {
- io_service_.dispatch([this, &content_object]() {
- if (on_content_object_in_output_buffer_) {
- on_content_object_in_output_buffer_(*producer_interface_,
- content_object);
- }
- });
-
- output_buffer_.insert(std::static_pointer_cast<ContentObject>(
- content_object.shared_from_this()));
-
- io_service_.dispatch([this, &content_object]() {
- if (on_content_object_output_) {
- on_content_object_output_(*producer_interface_, content_object);
- }
- });
-
- portal_->sendContentObject(content_object);
- }
-
- virtual void produce(const uint8_t *buffer, size_t buffer_size) {
- produce(utils::MemBuf::copyBuffer(buffer, buffer_size));
- }
-
- virtual void produce(std::unique_ptr<utils::MemBuf> &&buffer) {
- // This API is meant to be used just with the RTC producer.
- // Here it cannot be used since no name for the content is specified.
- throw errors::NotImplementedException();
- }
-
- virtual void asyncProduce(const Name &suffix, const uint8_t *buf,
- size_t buffer_size, bool is_last = true,
- uint32_t *start_offset = nullptr) {
- if (!async_thread_.stopped()) {
- async_thread_.add([this, suffix, buffer = buf, size = buffer_size,
- is_last, start_offset]() {
- if (start_offset != nullptr) {
- *start_offset = ProducerSocket::produce(suffix, buffer, size, is_last,
- *start_offset);
- } else {
- ProducerSocket::produce(suffix, buffer, size, is_last, 0);
- }
- });
- }
- }
-
- void asyncProduce(const Name &suffix);
+ bool isRunning() override { return !production_protocol_->isRunning(); };
virtual void asyncProduce(Name content_name,
std::unique_ptr<utils::MemBuf> &&buffer,
@@ -381,75 +111,56 @@ class ProducerSocket : public Socket<BasePortal>,
uint32_t **last_segment = nullptr) {
if (!async_thread_.stopped()) {
auto a = buffer.release();
- async_thread_.add(
- [this, content_name, a, is_last, offset, last_segment]() {
- auto buf = std::unique_ptr<utils::MemBuf>(a);
- if (last_segment != NULL) {
- **last_segment =
- offset + ProducerSocket::produce(content_name, std::move(buf),
- is_last, offset);
- } else {
- ProducerSocket::produce(content_name, std::move(buf), is_last,
- offset);
- }
- });
- }
- }
-
- virtual void asyncProduce(ContentObject &content_object) {
- if (!async_thread_.stopped()) {
- auto co_ptr = std::static_pointer_cast<ContentObject>(
- content_object.shared_from_this());
- async_thread_.add([this, content_object = std::move(co_ptr)]() {
- ProducerSocket::produce(*content_object);
+ async_thread_.add([this, content_name, a, is_last, offset,
+ last_segment]() {
+ auto buf = std::unique_ptr<utils::MemBuf>(a);
+ if (last_segment != NULL) {
+ **last_segment = offset + produceStream(content_name, std::move(buf),
+ is_last, offset);
+ } else {
+ produceStream(content_name, std::move(buf), is_last, offset);
+ }
});
}
}
- virtual void registerPrefix(const Prefix &producer_namespace) {
- served_namespaces_.push_back(producer_namespace);
+ virtual uint32_t produceStream(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last = true,
+ uint32_t start_offset = 0) {
+ return production_protocol_->produceStream(content_name, std::move(buffer),
+ is_last, start_offset);
}
- void serveForever() {
- if (listening_thread_.joinable()) {
- listening_thread_.join();
- }
+ virtual uint32_t produceStream(const Name &content_name,
+ const uint8_t *buffer, size_t buffer_size,
+ bool is_last = true,
+ uint32_t start_offset = 0) {
+ return production_protocol_->produceStream(
+ content_name, buffer, buffer_size, is_last, start_offset);
}
- void stop() { portal_->stopEventsLoop(); }
-
- asio::io_service &getIoService() override { return portal_->getIoService(); };
-
- virtual void onInterest(Interest &interest) {
- if (on_interest_input_) {
- on_interest_input_(*producer_interface_, interest);
- }
-
- const std::shared_ptr<ContentObject> content_object =
- output_buffer_.find(interest);
-
- if (content_object) {
- if (on_interest_satisfied_output_buffer_) {
- on_interest_satisfied_output_buffer_(*producer_interface_, interest);
- }
+ virtual uint32_t produceDatagram(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer) {
+ return production_protocol_->produceDatagram(content_name,
+ std::move(buffer));
+ }
- if (on_content_object_output_) {
- on_content_object_output_(*producer_interface_, *content_object);
- }
+ virtual uint32_t produceDatagram(const Name &content_name,
+ const uint8_t *buffer, size_t buffer_size) {
+ return production_protocol_->produceDatagram(content_name, buffer,
+ buffer_size);
+ }
- portal_->sendContentObject(*content_object);
- } else {
- if (on_interest_process_) {
- on_interest_process_(*producer_interface_, interest);
- }
- }
+ void produce(ContentObject &content_object) {
+ production_protocol_->produce(content_object);
}
- virtual void onInterest(Interest::Ptr &&interest) override {
- onInterest(*interest);
- };
+ void registerPrefix(const Prefix &producer_namespace) {
+ production_protocol_->registerNamespaceWithNetwork(producer_namespace);
+ }
- virtual void onError(std::error_code ec) override {}
+ void stop() { production_protocol_->stop(); }
virtual int setSocketOption(int socket_option_key,
uint32_t socket_option_value) {
@@ -462,7 +173,7 @@ class ProducerSocket : public Socket<BasePortal>,
break;
case GeneralTransportOptions::OUTPUT_BUFFER_SIZE:
- output_buffer_.setLimit(socket_option_value);
+ production_protocol_->setOutputBufferSize(socket_option_value);
break;
case GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME:
@@ -533,6 +244,12 @@ class ProducerSocket : public Socket<BasePortal>,
break;
}
+ case ProducerCallbacksOptions::CONTENT_OBJECT_TO_SIGN:
+ if (socket_option_value == VOID_HANDLER) {
+ on_content_object_to_sign_ = VOID_HANDLER;
+ break;
+ }
+
default:
return SOCKET_OPTION_NOT_SET;
}
@@ -559,19 +276,6 @@ class ProducerSocket : public Socket<BasePortal>,
return SOCKET_OPTION_NOT_SET;
}
- virtual int setSocketOption(int socket_option_key,
- std::list<Prefix> socket_option_value) {
- switch (socket_option_key) {
- case GeneralTransportOptions::NETWORK_NAME:
- served_namespaces_ = socket_option_value;
- break;
- default:
- return SOCKET_OPTION_NOT_SET;
- }
-
- return SOCKET_OPTION_SET;
- }
-
virtual int setSocketOption(
int socket_option_key,
interface::ProducerContentObjectCallback socket_option_value) {
@@ -594,6 +298,10 @@ class ProducerSocket : public Socket<BasePortal>,
on_content_object_output_ = socket_option_value;
break;
+ case ProducerCallbacksOptions::CONTENT_OBJECT_TO_SIGN:
+ on_content_object_to_sign_ = socket_option_value;
+ break;
+
default:
return SOCKET_OPTION_NOT_SET;
}
@@ -663,7 +371,7 @@ class ProducerSocket : public Socket<BasePortal>,
}
virtual int setSocketOption(int socket_option_key,
- utils::CryptoHashType socket_option_value) {
+ auth::CryptoHashType socket_option_value) {
switch (socket_option_key) {
case GeneralTransportOptions::HASH_ALGORITHM:
hash_algorithm_ = socket_option_value;
@@ -675,11 +383,12 @@ class ProducerSocket : public Socket<BasePortal>,
return SOCKET_OPTION_SET;
}
- virtual int setSocketOption(int socket_option_key,
- utils::CryptoSuite socket_option_value) {
+ virtual int setSocketOption(
+ int socket_option_key,
+ core::NextSegmentCalculationStrategy socket_option_value) {
switch (socket_option_key) {
- case GeneralTransportOptions::CRYPTO_SUITE:
- crypto_suite_ = socket_option_value;
+ case GeneralTransportOptions::SUFFIX_STRATEGY:
+ suffix_strategy_ = socket_option_value;
break;
default:
return SOCKET_OPTION_NOT_SET;
@@ -690,7 +399,7 @@ class ProducerSocket : public Socket<BasePortal>,
virtual int setSocketOption(
int socket_option_key,
- const std::shared_ptr<utils::Signer> &socket_option_value) {
+ const std::shared_ptr<auth::Signer> &socket_option_value) {
switch (socket_option_key) {
case GeneralTransportOptions::SIGNER: {
utils::SpinLock::Acquire locked(signer_lock_);
@@ -708,7 +417,7 @@ class ProducerSocket : public Socket<BasePortal>,
uint32_t &socket_option_value) {
switch (socket_option_key) {
case GeneralTransportOptions::OUTPUT_BUFFER_SIZE:
- socket_option_value = (uint32_t)output_buffer_.getLimit();
+ socket_option_value = production_protocol_->getOutputBufferSize();
break;
case GeneralTransportOptions::DATA_PACKET_SIZE:
@@ -733,18 +442,8 @@ class ProducerSocket : public Socket<BasePortal>,
socket_option_value = making_manifest_;
break;
- default:
- return SOCKET_OPTION_NOT_GET;
- }
-
- return SOCKET_OPTION_GET;
- }
-
- virtual int getSocketOption(int socket_option_key,
- std::list<Prefix> &socket_option_value) {
- switch (socket_option_key) {
- case GeneralTransportOptions::NETWORK_NAME:
- socket_option_value = served_namespaces_;
+ case GeneralTransportOptions::ASYNC_MODE:
+ socket_option_value = is_async_;
break;
default:
@@ -776,6 +475,10 @@ class ProducerSocket : public Socket<BasePortal>,
*socket_option_value = &on_content_object_output_;
break;
+ case ProducerCallbacksOptions::CONTENT_OBJECT_TO_SIGN:
+ *socket_option_value = &on_content_object_to_sign_;
+ break;
+
default:
return SOCKET_OPTION_NOT_GET;
}
@@ -828,11 +531,11 @@ class ProducerSocket : public Socket<BasePortal>,
*socket_option_value = &on_interest_inserted_input_buffer_;
break;
- case CACHE_HIT:
+ case ProducerCallbacksOptions::CACHE_HIT:
*socket_option_value = &on_interest_satisfied_output_buffer_;
break;
- case CACHE_MISS:
+ case ProducerCallbacksOptions::CACHE_MISS:
*socket_option_value = &on_interest_process_;
break;
@@ -844,8 +547,9 @@ class ProducerSocket : public Socket<BasePortal>,
});
}
- virtual int getSocketOption(int socket_option_key,
- std::shared_ptr<Portal> &socket_option_value) {
+ virtual int getSocketOption(
+ int socket_option_key,
+ std::shared_ptr<core::Portal> &socket_option_value) {
switch (socket_option_key) {
case PORTAL:
socket_option_value = portal_;
@@ -859,7 +563,7 @@ class ProducerSocket : public Socket<BasePortal>,
}
virtual int getSocketOption(int socket_option_key,
- utils::CryptoHashType &socket_option_value) {
+ auth::CryptoHashType &socket_option_value) {
switch (socket_option_key) {
case GeneralTransportOptions::HASH_ALGORITHM:
socket_option_value = hash_algorithm_;
@@ -871,22 +575,22 @@ class ProducerSocket : public Socket<BasePortal>,
return SOCKET_OPTION_GET;
}
- virtual int getSocketOption(int socket_option_key,
- utils::CryptoSuite &socket_option_value) {
+ virtual int getSocketOption(
+ int socket_option_key,
+ core::NextSegmentCalculationStrategy &socket_option_value) {
switch (socket_option_key) {
- case GeneralTransportOptions::HASH_ALGORITHM:
- socket_option_value = crypto_suite_;
+ case GeneralTransportOptions::SUFFIX_STRATEGY:
+ socket_option_value = suffix_strategy_;
break;
default:
return SOCKET_OPTION_NOT_GET;
}
-
return SOCKET_OPTION_GET;
}
virtual int getSocketOption(
int socket_option_key,
- std::shared_ptr<utils::Signer> &socket_option_value) {
+ std::shared_ptr<auth::Signer> &socket_option_value) {
switch (socket_option_key) {
case GeneralTransportOptions::SIGNER: {
utils::SpinLock::Acquire locked(signer_lock_);
@@ -907,19 +611,21 @@ class ProducerSocket : public Socket<BasePortal>,
// If the thread calling lambda_func is not the same of io_service, this
// function reschedule the function on it
template <typename Lambda, typename arg2>
- int rescheduleOnIOService(int socket_option_key, arg2 socket_option_value,
- Lambda lambda_func) {
+ int rescheduleOnIOServiceWithReference(int socket_option_key,
+ arg2 &socket_option_value,
+ Lambda lambda_func) {
// To enforce type check
- std::function<int(int, arg2)> func = lambda_func;
+ std::function<int(int, arg2 &)> func = lambda_func;
int result = SOCKET_OPTION_SET;
- if (listening_thread_.joinable() &&
- std::this_thread::get_id() != listening_thread_.get_id()) {
+ if (production_protocol_ && production_protocol_->isRunning()) {
std::mutex mtx;
/* Condition variable for the wait */
std::condition_variable cv;
+
bool done = false;
- io_service_.dispatch([&socket_option_key, &socket_option_value, &mtx, &cv,
- &result, &done, &func]() {
+ portal_->getIoService().dispatch([&socket_option_key,
+ &socket_option_value, &mtx, &cv,
+ &result, &done, &func]() {
std::unique_lock<std::mutex> lck(mtx);
done = true;
result = func(socket_option_key, socket_option_value);
@@ -939,21 +645,19 @@ class ProducerSocket : public Socket<BasePortal>,
// If the thread calling lambda_func is not the same of io_service, this
// function reschedule the function on it
template <typename Lambda, typename arg2>
- int rescheduleOnIOServiceWithReference(int socket_option_key,
- arg2 &socket_option_value,
- Lambda lambda_func) {
+ int rescheduleOnIOService(int socket_option_key, arg2 socket_option_value,
+ Lambda lambda_func) {
// To enforce type check
- std::function<int(int, arg2 &)> func = lambda_func;
+ std::function<int(int, arg2)> func = lambda_func;
int result = SOCKET_OPTION_SET;
- if (listening_thread_.joinable() &&
- std::this_thread::get_id() != this->listening_thread_.get_id()) {
+ if (production_protocol_ && production_protocol_->isRunning()) {
std::mutex mtx;
/* Condition variable for the wait */
std::condition_variable cv;
-
bool done = false;
- io_service_.dispatch([&socket_option_key, &socket_option_value, &mtx, &cv,
- &result, &done, &func]() {
+ portal_->getIoService().dispatch([&socket_option_key,
+ &socket_option_value, &mtx, &cv,
+ &result, &done, &func]() {
std::unique_lock<std::mutex> lck(mtx);
done = true;
result = func(socket_option_key, socket_option_value);
@@ -973,39 +677,20 @@ class ProducerSocket : public Socket<BasePortal>,
// Threads
protected:
interface::ProducerSocket *producer_interface_;
- std::thread listening_thread_;
asio::io_service io_service_;
- std::shared_ptr<Portal> portal_;
std::atomic<size_t> data_packet_size_;
- std::list<Prefix>
- served_namespaces_; // No need to be threadsafe, this is always modified
- // by the application thread
std::atomic<uint32_t> content_object_expiry_time_;
- utils::CircularFifo<std::shared_ptr<ContentObject>, 2048>
- object_queue_for_callbacks_;
-
- // buffers
- // ContentStore is thread-safe
- utils::ContentStore output_buffer_;
-
utils::EventThread async_thread_;
- int registration_status_;
std::atomic<bool> making_manifest_;
-
- // map for storing sequence numbers for several calls of the publish
- // function
- std::unordered_map<Name, std::unordered_map<int, uint32_t>> seq_number_map_;
-
- std::atomic<utils::CryptoHashType> hash_algorithm_;
- std::atomic<utils::CryptoSuite> crypto_suite_;
+ std::atomic<auth::CryptoHashType> hash_algorithm_;
+ std::atomic<auth::CryptoSuite> crypto_suite_;
utils::SpinLock signer_lock_;
- std::shared_ptr<utils::Signer> signer_;
+ std::shared_ptr<auth::Signer> signer_;
core::NextSegmentCalculationStrategy suffix_strategy_;
- // While manifests are being built, contents are stored in a queue
- std::queue<std::shared_ptr<ContentObject>> content_queue_;
+ std::unique_ptr<protocol::ProductionProtocol> production_protocol_;
// callbacks
ProducerInterestCallback on_interest_input_;
@@ -1021,63 +706,6 @@ class ProducerSocket : public Socket<BasePortal>,
ProducerContentObjectCallback on_content_object_evicted_from_output_buffer_;
ProducerContentCallback on_content_produced_;
-
- private:
- void listen() {
- bool first = true;
-
- for (core::Prefix &producer_namespace : served_namespaces_) {
- if (first) {
- core::BindConfig bind_config(producer_namespace, 1000);
- portal_->bind(bind_config);
- portal_->setProducerCallback(this);
- first = !first;
- } else {
- portal_->registerRoute(producer_namespace);
- }
- }
-
- portal_->runEventsLoop();
- }
-
- void scheduleSendBurst() {
- io_service_.post([this]() {
- std::shared_ptr<ContentObject> co;
-
- for (uint32_t i = 0; i < burst_size; i++) {
- if (object_queue_for_callbacks_.pop(co)) {
- if (on_new_segment_) {
- on_new_segment_(*producer_interface_, *co);
- }
-
- if (on_content_object_to_sign_) {
- on_content_object_to_sign_(*producer_interface_, *co);
- }
-
- if (on_content_object_in_output_buffer_) {
- on_content_object_in_output_buffer_(*producer_interface_, *co);
- }
-
- if (on_content_object_output_) {
- on_content_object_output_(*producer_interface_, *co);
- }
- } else {
- break;
- }
- }
- });
- }
-
- void passContentObjectToCallbacks(
- const std::shared_ptr<ContentObject> &content_object) {
- output_buffer_.insert(content_object);
- portal_->sendContentObject(*content_object);
- object_queue_for_callbacks_.push(std::move(content_object));
-
- if (object_queue_for_callbacks_.size() >= burst_size) {
- scheduleSendBurst();
- }
- }
};
} // namespace implementation
diff --git a/libtransport/src/implementation/tls_rtc_socket_producer.cc b/libtransport/src/implementation/tls_rtc_socket_producer.cc
index 9ef79ca..9a62c86 100644
--- a/libtransport/src/implementation/tls_rtc_socket_producer.cc
+++ b/libtransport/src/implementation/tls_rtc_socket_producer.cc
@@ -15,10 +15,8 @@
#include <hicn/transport/core/interest.h>
#include <hicn/transport/interfaces/p2psecure_socket_producer.h>
-
#include <implementation/p2psecure_socket_producer.h>
#include <implementation/tls_rtc_socket_producer.h>
-
#include <openssl/bio.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
diff --git a/libtransport/src/implementation/tls_rtc_socket_producer.h b/libtransport/src/implementation/tls_rtc_socket_producer.h
index 685c912..92c657a 100644
--- a/libtransport/src/implementation/tls_rtc_socket_producer.h
+++ b/libtransport/src/implementation/tls_rtc_socket_producer.h
@@ -15,7 +15,6 @@
#pragma once
-#include <implementation/rtc_socket_producer.h>
#include <implementation/tls_socket_producer.h>
namespace transport {
@@ -23,8 +22,7 @@ namespace implementation {
class P2PSecureProducerSocket;
-class TLSRTCProducerSocket : public RTCProducerSocket,
- public TLSProducerSocket {
+class TLSRTCProducerSocket : public TLSProducerSocket {
friend class P2PSecureProducerSocket;
public:
@@ -34,7 +32,8 @@ class TLSRTCProducerSocket : public RTCProducerSocket,
~TLSRTCProducerSocket() = default;
- void produce(std::unique_ptr<utils::MemBuf> &&buffer) override;
+ uint32_t produceDatagram(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer) override;
void accept() override;
diff --git a/libtransport/src/implementation/tls_socket_consumer.cc b/libtransport/src/implementation/tls_socket_consumer.cc
index 1be6f41..99bcd43 100644
--- a/libtransport/src/implementation/tls_socket_consumer.cc
+++ b/libtransport/src/implementation/tls_socket_consumer.cc
@@ -136,7 +136,6 @@ TLSConsumerSocket::TLSConsumerSocket(interface::ConsumerSocket *consumer_socket,
int protocol, SSL *ssl)
: ConsumerSocket(consumer_socket, protocol),
name_(),
- buf_pool_(),
decrypted_content_(),
payload_(),
head_(),
@@ -223,14 +222,15 @@ int TLSConsumerSocket::download_content(const Name &name) {
content_downloaded_ = false;
std::size_t max_buffer_size = read_callback_decrypted_->maxBufferSize();
- std::size_t buffer_size = read_callback_decrypted_->maxBufferSize() + SSL3_RT_MAX_PLAIN_LENGTH;
+ std::size_t buffer_size =
+ read_callback_decrypted_->maxBufferSize() + SSL3_RT_MAX_PLAIN_LENGTH;
decrypted_content_ = utils::MemBuf::createCombined(buffer_size);
int result = -1;
std::size_t size = 0;
while (!content_downloaded_ || something_to_read_) {
- result = SSL_read(
- this->ssl_, decrypted_content_->writableTail(), SSL3_RT_MAX_PLAIN_LENGTH);
+ result = SSL_read(this->ssl_, decrypted_content_->writableTail(),
+ SSL3_RT_MAX_PLAIN_LENGTH);
/* SSL_read returns the data only if there were SSL3_RT_MAX_PLAIN_LENGTH of
* the data has been fully downloaded */
diff --git a/libtransport/src/implementation/tls_socket_consumer.h b/libtransport/src/implementation/tls_socket_consumer.h
index 1c5df34..be08ec4 100644
--- a/libtransport/src/implementation/tls_socket_consumer.h
+++ b/libtransport/src/implementation/tls_socket_consumer.h
@@ -16,9 +16,7 @@
#pragma once
#include <hicn/transport/interfaces/socket_consumer.h>
-
#include <implementation/socket_consumer.h>
-
#include <openssl/ssl.h>
namespace transport {
@@ -74,7 +72,6 @@ class TLSConsumerSocket : public ConsumerSocket,
SSL_CTX *ctx_;
/* Chain of MemBuf to be used as a temporary buffer to pass descypted data
* from the underlying layer to the application */
- utils::ObjectPool<utils::MemBuf> buf_pool_;
std::unique_ptr<utils::MemBuf> decrypted_content_;
/* Chain of MemBuf holding the payload to be written into interest or data */
std::unique_ptr<utils::MemBuf> payload_;
diff --git a/libtransport/src/implementation/tls_socket_producer.cc b/libtransport/src/implementation/tls_socket_producer.cc
index 339a1ad..e54d38d 100644
--- a/libtransport/src/implementation/tls_socket_producer.cc
+++ b/libtransport/src/implementation/tls_socket_producer.cc
@@ -14,10 +14,8 @@
*/
#include <hicn/transport/interfaces/socket_producer.h>
-
#include <implementation/p2psecure_socket_producer.h>
#include <implementation/tls_socket_producer.h>
-
#include <openssl/bio.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
@@ -50,10 +48,14 @@ int TLSProducerSocket::readOld(BIO *b, char *buf, int size) {
std::unique_lock<std::mutex> lck(socket->mtx_);
+ TRANSPORT_LOGD("Start wait on the CV.");
+
if (!socket->something_to_read_) {
(socket->cv_).wait(lck);
}
+ TRANSPORT_LOGD("CV unlocked.");
+
/* Either there already is something to read, or the thread has been waken up.
* We must return the payload in the interest anyway */
utils::MemBuf *membuf = socket->handshake_packet_->next();
@@ -103,7 +105,7 @@ int TLSProducerSocket::writeOld(BIO *b, const char *buf, int num) {
socket->tls_chunks_--;
socket->parent_->setSocketOption(GeneralTransportOptions::MAKE_MANIFEST,
false);
- socket->parent_->ProducerSocket::produce(
+ socket->parent_->ProducerSocket::produceStream(
socket->name_, (const uint8_t *)buf, num, socket->tls_chunks_ == 0,
socket->last_segment_);
socket->parent_->setSocketOption(GeneralTransportOptions::MAKE_MANIFEST,
@@ -122,18 +124,18 @@ int TLSProducerSocket::writeOld(BIO *b, const char *buf, int num) {
socket->tls_chunks_--;
socket->to_call_oncontentproduced_--;
- socket->last_segment_ += socket->ProducerSocket::produce(
+ socket->last_segment_ += socket->ProducerSocket::produceStream(
socket->name_, std::move(mbuf), socket->tls_chunks_ == 0,
socket->last_segment_);
- ProducerContentCallback on_content_produced_application;
+ ProducerContentCallback *on_content_produced_application;
socket->getSocketOption(ProducerCallbacksOptions::CONTENT_PRODUCED,
- on_content_produced_application);
+ &on_content_produced_application);
if (socket->to_call_oncontentproduced_ == 0 &&
on_content_produced_application) {
- on_content_produced_application(*socket->getInterface(),
- std::error_code(), 0);
+ on_content_produced_application->operator()(*socket->getInterface(),
+ std::error_code(), 0);
}
});
}
@@ -144,7 +146,8 @@ int TLSProducerSocket::writeOld(BIO *b, const char *buf, int num) {
TLSProducerSocket::TLSProducerSocket(interface::ProducerSocket *producer_socket,
P2PSecureProducerSocket *parent,
const Name &handshake_name)
- : ProducerSocket(producer_socket),
+ : ProducerSocket(producer_socket,
+ ProductionProtocolAlgorithms::BYTE_STREAM),
on_content_produced_application_(),
mtx_(),
cv_(),
@@ -236,13 +239,14 @@ void TLSProducerSocket::accept() {
std::move(parent_->map_producers[handshake_name_]));
parent_->map_producers.erase(handshake_name_);
- ProducerInterestCallback on_interest_process_decrypted;
+ ProducerInterestCallback *on_interest_process_decrypted;
getSocketOption(ProducerCallbacksOptions::CACHE_MISS,
- on_interest_process_decrypted);
+ &on_interest_process_decrypted);
- if (on_interest_process_decrypted) {
- Interest inter(std::move(handshake_packet_));
- on_interest_process_decrypted(*getInterface(), inter);
+ if (*on_interest_process_decrypted) {
+ Interest inter(std::move(*handshake_packet_));
+ handshake_packet_.reset();
+ on_interest_process_decrypted->operator()(*getInterface(), inter);
} else {
throw errors::RuntimeException(
"On interest process unset: unable to perform handshake");
@@ -270,14 +274,14 @@ void TLSProducerSocket::onInterest(ProducerSocket &p, Interest &interest) {
std::unique_lock<std::mutex> lck(mtx_);
name_ = interest.getName();
- interest.separateHeaderPayload();
+ // interest.separateHeaderPayload();
handshake_packet_ = interest.acquireMemBufReference();
something_to_read_ = true;
cv_.notify_one();
return;
} else if (handshake_state == SERVER_FINISHED) {
- interest.separateHeaderPayload();
+ // interest.separateHeaderPayload();
handshake_packet_ = interest.acquireMemBufReference();
something_to_read_ = true;
@@ -288,12 +292,12 @@ void TLSProducerSocket::onInterest(ProducerSocket &p, Interest &interest) {
interest.getPayload()->length());
}
- ProducerInterestCallback on_interest_input_decrypted;
+ ProducerInterestCallback *on_interest_input_decrypted;
getSocketOption(ProducerCallbacksOptions::INTEREST_INPUT,
- on_interest_input_decrypted);
+ &on_interest_input_decrypted);
- if (on_interest_input_decrypted)
- (on_interest_input_decrypted)(*getInterface(), interest);
+ if (*on_interest_input_decrypted)
+ (*on_interest_input_decrypted)(*getInterface(), interest);
}
}
@@ -301,17 +305,19 @@ void TLSProducerSocket::cacheMiss(interface::ProducerSocket &p,
Interest &interest) {
HandshakeState handshake_state = getHandshakeState();
+ TRANSPORT_LOGD("On cache miss in TLS socket producer.");
+
if (handshake_state == CLIENT_HELLO) {
std::unique_lock<std::mutex> lck(mtx_);
- interest.separateHeaderPayload();
+ // interest.separateHeaderPayload();
handshake_packet_ = interest.acquireMemBufReference();
something_to_read_ = true;
handshake_state_ = CLIENT_FINISHED;
cv_.notify_one();
} else if (handshake_state == SERVER_FINISHED) {
- interest.separateHeaderPayload();
+ // interest.separateHeaderPayload();
handshake_packet_ = interest.acquireMemBufReference();
something_to_read_ = true;
@@ -343,16 +349,16 @@ void TLSProducerSocket::onContentProduced(interface::ProducerSocket &p,
const std::error_code &err,
uint64_t bytes_written) {}
-uint32_t TLSProducerSocket::produce(Name content_name,
- std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last, uint32_t start_offset) {
+uint32_t TLSProducerSocket::produceStream(
+ const Name &content_name, std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last, uint32_t start_offset) {
if (getHandshakeState() != SERVER_FINISHED) {
throw errors::RuntimeException(
"New handshake on the same P2P secure producer socket not supported");
}
size_t buf_size = buffer->length();
- name_ = served_namespaces_.front().mapName(content_name);
+ name_ = production_protocol_->getNamespaces().front().mapName(content_name);
tls_chunks_ = to_call_oncontentproduced_ =
ceil((float)buf_size / (float)SSL3_RT_MAX_PLAIN_LENGTH);
@@ -370,46 +376,6 @@ uint32_t TLSProducerSocket::produce(Name content_name,
return 0;
}
-void TLSProducerSocket::asyncProduce(const Name &content_name,
- const uint8_t *buf, size_t buffer_size,
- bool is_last, uint32_t *start_offset) {
- if (!encryption_thread_.stopped()) {
- encryption_thread_.add([this, content_name, buffer = buf,
- size = buffer_size, is_last, start_offset]() {
- if (start_offset != NULL) {
- produce(content_name, buffer, size, is_last, *start_offset);
- } else {
- produce(content_name, buffer, size, is_last, 0);
- }
- });
- }
-}
-
-void TLSProducerSocket::asyncProduce(Name content_name,
- std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last, uint32_t offset,
- uint32_t **last_segment) {
- if (!encryption_thread_.stopped()) {
- auto a = buffer.release();
- encryption_thread_.add(
- [this, content_name, a, is_last, offset, last_segment]() {
- auto buf = std::unique_ptr<utils::MemBuf>(a);
- if (last_segment != NULL) {
- *last_segment = &last_segment_;
- }
- produce(content_name, std::move(buf), is_last, offset);
- });
- }
-}
-
-void TLSProducerSocket::asyncProduce(ContentObject &content_object) {
- throw errors::RuntimeException("API not supported");
-}
-
-void TLSProducerSocket::produce(ContentObject &content_object) {
- throw errors::RuntimeException("API not supported");
-}
-
long TLSProducerSocket::ctrl(BIO *b, int cmd, long num, void *ptr) {
if (cmd == BIO_CTRL_FLUSH) {
}
@@ -424,13 +390,14 @@ int TLSProducerSocket::addHicnKeyIdCb(SSL *s, unsigned int ext_type,
void *add_arg) {
TLSProducerSocket *socket = reinterpret_cast<TLSProducerSocket *>(add_arg);
+ TRANSPORT_LOGD("On addHicnKeyIdCb, for the prefix registration.");
+
if (ext_type == 100) {
- ip_prefix_t ip_prefix =
- socket->parent_->served_namespaces_.front().toIpPrefixStruct();
- int inet_family =
- socket->parent_->served_namespaces_.front().getAddressFamily();
- uint16_t prefix_len_bits =
- socket->parent_->served_namespaces_.front().getPrefixLength();
+ auto &prefix =
+ socket->parent_->production_protocol_->getNamespaces().front();
+ const ip_prefix_t &ip_prefix = prefix.toIpPrefixStruct();
+ int inet_family = prefix.getAddressFamily();
+ uint16_t prefix_len_bits = prefix.getPrefixLength();
uint8_t prefix_len_bytes = prefix_len_bits / 8;
uint8_t prefix_len_u32 = prefix_len_bits / 32;
@@ -479,10 +446,9 @@ int TLSProducerSocket::addHicnKeyIdCb(SSL *s, unsigned int ext_type,
socket->parent_->on_interest_process_decrypted_;
socket->registerPrefix(
- Prefix(socket->parent_->served_namespaces_.front().getName(
- Name(inet_family, (uint8_t *)&mask),
- Name(inet_family, (uint8_t *)&keyId_component),
- socket->parent_->served_namespaces_.front().getName()),
+ Prefix(prefix.getName(Name(inet_family, (uint8_t *)&mask),
+ Name(inet_family, (uint8_t *)&keyId_component),
+ prefix.getName()),
out_ip->len));
socket->connect();
}
@@ -580,61 +546,5 @@ int TLSProducerSocket::getSocketOption(
});
}
-int TLSProducerSocket::getSocketOption(
- int socket_option_key, ProducerContentCallback &socket_option_value) {
- return rescheduleOnIOServiceWithReference(
- socket_option_key, socket_option_value,
- [this](int socket_option_key,
- ProducerContentCallback &socket_option_value) -> int {
- switch (socket_option_key) {
- case ProducerCallbacksOptions::CONTENT_PRODUCED:
- socket_option_value = on_content_produced_application_;
- break;
-
- default:
- return SOCKET_OPTION_NOT_GET;
- }
-
- return SOCKET_OPTION_GET;
- });
-}
-
-int TLSProducerSocket::getSocketOption(
- int socket_option_key, ProducerInterestCallback &socket_option_value) {
- // Reschedule the function on the io_service to avoid race condition in case
- // setSocketOption is called while the io_service is running.
- return rescheduleOnIOServiceWithReference(
- socket_option_key, socket_option_value,
- [this](int socket_option_key,
- ProducerInterestCallback &socket_option_value) -> int {
- switch (socket_option_key) {
- case ProducerCallbacksOptions::INTEREST_INPUT:
- socket_option_value = on_interest_input_decrypted_;
- break;
-
- case ProducerCallbacksOptions::INTEREST_DROP:
- socket_option_value = on_interest_dropped_input_buffer_;
- break;
-
- case ProducerCallbacksOptions::INTEREST_PASS:
- socket_option_value = on_interest_inserted_input_buffer_;
- break;
-
- case ProducerCallbacksOptions::CACHE_HIT:
- socket_option_value = on_interest_satisfied_output_buffer_;
- break;
-
- case ProducerCallbacksOptions::CACHE_MISS:
- socket_option_value = on_interest_process_decrypted_;
- break;
-
- default:
- return SOCKET_OPTION_NOT_GET;
- }
-
- return SOCKET_OPTION_GET;
- });
-}
-
} // namespace implementation
} // namespace transport
diff --git a/libtransport/src/implementation/tls_socket_producer.h b/libtransport/src/implementation/tls_socket_producer.h
index 2382e86..a542a4d 100644
--- a/libtransport/src/implementation/tls_socket_producer.h
+++ b/libtransport/src/implementation/tls_socket_producer.h
@@ -16,8 +16,8 @@
#pragma once
#include <implementation/socket_producer.h>
-
#include <openssl/ssl.h>
+
#include <condition_variable>
#include <mutex>
@@ -36,26 +36,18 @@ class TLSProducerSocket : virtual public ProducerSocket {
~TLSProducerSocket();
- uint32_t produce(Name content_name, const uint8_t *buffer, size_t buffer_size,
- bool is_last = true, uint32_t start_offset = 0) override {
- return produce(content_name, utils::MemBuf::copyBuffer(buffer, buffer_size),
- is_last, start_offset);
+ uint32_t produceStream(const Name &content_name, const uint8_t *buffer,
+ size_t buffer_size, bool is_last = true,
+ uint32_t start_offset = 0) override {
+ return produceStream(content_name,
+ utils::MemBuf::copyBuffer(buffer, buffer_size),
+ is_last, start_offset);
}
- uint32_t produce(Name content_name, std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last = true, uint32_t start_offset = 0) override;
-
- void produce(ContentObject &content_object) override;
-
- void asyncProduce(const Name &suffix, const uint8_t *buf, size_t buffer_size,
- bool is_last = true,
- uint32_t *start_offset = nullptr) override;
-
- void asyncProduce(Name content_name, std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last, uint32_t offset,
- uint32_t **last_segment = nullptr) override;
-
- void asyncProduce(ContentObject &content_object) override;
+ uint32_t produceStream(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last = true,
+ uint32_t start_offset = 0) override;
virtual void accept();
@@ -80,7 +72,7 @@ class TLSProducerSocket : virtual public ProducerSocket {
ProducerInterestCallback &socket_option_value);
using ProducerSocket::getSocketOption;
- using ProducerSocket::onInterest;
+ // using ProducerSocket::onInterest;
using ProducerSocket::setSocketOption;
protected:
@@ -119,6 +111,7 @@ class TLSProducerSocket : virtual public ProducerSocket {
int to_call_oncontentproduced_;
bool still_writing_;
utils::EventThread encryption_thread_;
+ utils::EventThread async_thread_;
void onInterest(ProducerSocket &p, Interest &interest);
diff --git a/libtransport/src/interfaces/CMakeLists.txt b/libtransport/src/interfaces/CMakeLists.txt
index e1d1445..0284aa4 100644
--- a/libtransport/src/interfaces/CMakeLists.txt
+++ b/libtransport/src/interfaces/CMakeLists.txt
@@ -14,24 +14,24 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
list(APPEND SOURCE_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/rtc_socket_producer.cc
${CMAKE_CURRENT_SOURCE_DIR}/socket_producer.cc
${CMAKE_CURRENT_SOURCE_DIR}/socket_consumer.cc
${CMAKE_CURRENT_SOURCE_DIR}/portal.cc
${CMAKE_CURRENT_SOURCE_DIR}/callbacks.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/global_configuration.cc
)
if (${OPENSSL_VERSION} VERSION_EQUAL "1.1.1a" OR ${OPENSSL_VERSION} VERSION_GREATER "1.1.1a")
list(APPEND SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_producer.cc
${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_consumer.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/tls_rtc_socket_producer.cc
+ # ${CMAKE_CURRENT_SOURCE_DIR}/tls_rtc_socket_producer.cc
${CMAKE_CURRENT_SOURCE_DIR}/tls_socket_producer.cc
${CMAKE_CURRENT_SOURCE_DIR}/tls_socket_consumer.cc
)
list(APPEND HEADER_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/tls_rtc_socket_producer.h
+ # ${CMAKE_CURRENT_SOURCE_DIR}/tls_rtc_socket_producer.h
${CMAKE_CURRENT_SOURCE_DIR}/tls_socket_producer.h
${CMAKE_CURRENT_SOURCE_DIR}/tls_socket_consumer.h
)
diff --git a/libtransport/src/interfaces/global_configuration.cc b/libtransport/src/interfaces/global_configuration.cc
new file mode 100644
index 0000000..8fb6601
--- /dev/null
+++ b/libtransport/src/interfaces/global_configuration.cc
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core/global_configuration.h>
+#include <hicn/transport/interfaces/global_conf_interface.h>
+#include <hicn/transport/utils/log.h>
+
+#include <system_error>
+
+namespace transport {
+namespace interface {
+namespace global_config {
+
+void parseConfigurationFile(const std::string& path) {
+ core::GlobalConfiguration::getInstance().parseConfiguration(path);
+}
+
+void ConfigurationObject::get() {
+ std::error_code ec;
+ core::GlobalConfiguration::getInstance().getConfiguration(*this, ec);
+
+ if (ec) {
+ TRANSPORT_LOGE("Error setting global config: %s", ec.message().c_str());
+ }
+}
+
+void ConfigurationObject::set() {
+ std::error_code ec;
+ core::GlobalConfiguration::getInstance().setConfiguration(*this, ec);
+
+ if (ec) {
+ TRANSPORT_LOGE("Error setting global config: %s", ec.message().c_str());
+ }
+}
+
+} // namespace global_config
+} // namespace interface
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/interfaces/p2psecure_socket_consumer.cc b/libtransport/src/interfaces/p2psecure_socket_consumer.cc
index 038441d..e473a1e 100644
--- a/libtransport/src/interfaces/p2psecure_socket_consumer.cc
+++ b/libtransport/src/interfaces/p2psecure_socket_consumer.cc
@@ -14,7 +14,6 @@
*/
#include <hicn/transport/interfaces/p2psecure_socket_consumer.h>
-
#include <implementation/p2psecure_socket_consumer.h>
namespace transport {
diff --git a/libtransport/src/interfaces/p2psecure_socket_producer.cc b/libtransport/src/interfaces/p2psecure_socket_producer.cc
index 3735225..10d8a13 100644
--- a/libtransport/src/interfaces/p2psecure_socket_producer.cc
+++ b/libtransport/src/interfaces/p2psecure_socket_producer.cc
@@ -14,7 +14,6 @@
*/
#include <hicn/transport/interfaces/p2psecure_socket_producer.h>
-
#include <implementation/p2psecure_socket_producer.h>
namespace transport {
@@ -25,7 +24,7 @@ P2PSecureProducerSocket::P2PSecureProducerSocket() {
}
P2PSecureProducerSocket::P2PSecureProducerSocket(
- bool rtc, const std::shared_ptr<utils::Identity> &identity) {
+ bool rtc, const std::shared_ptr<auth::Identity> &identity) {
socket_ = std::make_unique<implementation::P2PSecureProducerSocket>(this, rtc,
identity);
}
diff --git a/libtransport/src/interfaces/portal.cc b/libtransport/src/interfaces/portal.cc
index 36cbd0c..2ab51c4 100644
--- a/libtransport/src/interfaces/portal.cc
+++ b/libtransport/src/interfaces/portal.cc
@@ -14,38 +14,35 @@
*/
#include <hicn/transport/interfaces/portal.h>
-
#include <implementation/socket.h>
namespace transport {
namespace interface {
-using implementation::BasePortal;
-
-Portal::Portal() { implementation_ = new implementation::BasePortal(); }
+Portal::Portal() { implementation_ = new core::Portal(); }
Portal::Portal(asio::io_service &io_service) {
- implementation_ = new BasePortal(io_service);
+ implementation_ = new core::Portal(io_service);
}
-Portal::~Portal() { delete reinterpret_cast<BasePortal *>(implementation_); }
+Portal::~Portal() { delete reinterpret_cast<core::Portal *>(implementation_); }
void Portal::setConsumerCallback(ConsumerCallback *consumer_callback) {
- reinterpret_cast<BasePortal *>(implementation_)
+ reinterpret_cast<core::Portal *>(implementation_)
->setConsumerCallback(consumer_callback);
}
void Portal::setProducerCallback(ProducerCallback *producer_callback) {
- reinterpret_cast<BasePortal *>(implementation_)
+ reinterpret_cast<core::Portal *>(implementation_)
->setProducerCallback(producer_callback);
}
void Portal::connect(bool is_consumer) {
- reinterpret_cast<BasePortal *>(implementation_)->connect(is_consumer);
+ reinterpret_cast<core::Portal *>(implementation_)->connect(is_consumer);
}
bool Portal::interestIsPending(const core::Name &name) {
- return reinterpret_cast<BasePortal *>(implementation_)
+ return reinterpret_cast<core::Portal *>(implementation_)
->interestIsPending(name);
}
@@ -53,46 +50,46 @@ void Portal::sendInterest(
core::Interest::Ptr &&interest,
OnContentObjectCallback &&on_content_object_callback,
OnInterestTimeoutCallback &&on_interest_timeout_callback) {
- reinterpret_cast<BasePortal *>(implementation_)
+ reinterpret_cast<core::Portal *>(implementation_)
->sendInterest(std::move(interest), std::move(on_content_object_callback),
std::move(on_interest_timeout_callback));
}
void Portal::bind(const BindConfig &config) {
- reinterpret_cast<BasePortal *>(implementation_)->bind(config);
+ reinterpret_cast<core::Portal *>(implementation_)->bind(config);
}
void Portal::runEventsLoop() {
- reinterpret_cast<BasePortal *>(implementation_)->runEventsLoop();
+ reinterpret_cast<core::Portal *>(implementation_)->runEventsLoop();
}
void Portal::runOneEvent() {
- reinterpret_cast<BasePortal *>(implementation_)->runOneEvent();
+ reinterpret_cast<core::Portal *>(implementation_)->runOneEvent();
}
void Portal::sendContentObject(core::ContentObject &content_object) {
- reinterpret_cast<BasePortal *>(implementation_)
+ reinterpret_cast<core::Portal *>(implementation_)
->sendContentObject(content_object);
}
void Portal::stopEventsLoop() {
- reinterpret_cast<BasePortal *>(implementation_)->stopEventsLoop();
+ reinterpret_cast<core::Portal *>(implementation_)->stopEventsLoop();
}
void Portal::killConnection() {
- reinterpret_cast<BasePortal *>(implementation_)->killConnection();
+ reinterpret_cast<core::Portal *>(implementation_)->killConnection();
}
void Portal::clear() {
- reinterpret_cast<BasePortal *>(implementation_)->clear();
+ reinterpret_cast<core::Portal *>(implementation_)->clear();
}
asio::io_service &Portal::getIoService() {
- return reinterpret_cast<BasePortal *>(implementation_)->getIoService();
+ return reinterpret_cast<core::Portal *>(implementation_)->getIoService();
}
void Portal::registerRoute(core::Prefix &prefix) {
- reinterpret_cast<BasePortal *>(implementation_)->registerRoute(prefix);
+ reinterpret_cast<core::Portal *>(implementation_)->registerRoute(prefix);
}
} // namespace interface
diff --git a/libtransport/src/interfaces/socket_consumer.cc b/libtransport/src/interfaces/socket_consumer.cc
index ea06063..4eee73c 100644
--- a/libtransport/src/interfaces/socket_consumer.cc
+++ b/libtransport/src/interfaces/socket_consumer.cc
@@ -46,8 +46,6 @@ void ConsumerSocket::stop() { socket_->stop(); }
void ConsumerSocket::resume() { socket_->resume(); }
-bool ConsumerSocket::verifyKeyPackets() { return socket_->verifyKeyPackets(); }
-
asio::io_service &ConsumerSocket::getIoService() {
return socket_->getIoService();
}
@@ -88,22 +86,10 @@ int ConsumerSocket::setSocketOption(
}
int ConsumerSocket::setSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationCallback socket_option_value) {
- return socket_->setSocketOption(socket_option_key, socket_option_value);
-}
-
-int ConsumerSocket::setSocketOption(
int socket_option_key, ConsumerInterestCallback socket_option_value) {
return socket_->setSocketOption(socket_option_key, socket_option_value);
}
-int ConsumerSocket::setSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback socket_option_value) {
- return socket_->setSocketOption(socket_option_key, socket_option_value);
-}
-
int ConsumerSocket::setSocketOption(int socket_option_key,
IcnObserver *socket_option_value) {
return socket_->setSocketOption(socket_option_key, socket_option_value);
@@ -111,7 +97,7 @@ int ConsumerSocket::setSocketOption(int socket_option_key,
int ConsumerSocket::setSocketOption(
int socket_option_key,
- const std::shared_ptr<utils::Verifier> &socket_option_value) {
+ const std::shared_ptr<auth::Verifier> &socket_option_value) {
return socket_->setSocketOption(socket_option_key, socket_option_value);
}
@@ -152,22 +138,10 @@ int ConsumerSocket::getSocketOption(
}
int ConsumerSocket::getSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationCallback **socket_option_value) {
- return socket_->setSocketOption(socket_option_key, socket_option_value);
-}
-
-int ConsumerSocket::getSocketOption(
int socket_option_key, ConsumerInterestCallback **socket_option_value) {
return socket_->setSocketOption(socket_option_key, socket_option_value);
}
-int ConsumerSocket::getSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback **socket_option_value) {
- return socket_->setSocketOption(socket_option_key, socket_option_value);
-}
-
int ConsumerSocket::getSocketOption(int socket_option_key,
IcnObserver **socket_option_value) {
return socket_->getSocketOption(socket_option_key, socket_option_value);
@@ -175,7 +149,7 @@ int ConsumerSocket::getSocketOption(int socket_option_key,
int ConsumerSocket::getSocketOption(
int socket_option_key,
- std::shared_ptr<utils::Verifier> &socket_option_value) {
+ std::shared_ptr<auth::Verifier> &socket_option_value) {
return socket_->getSocketOption(socket_option_key, socket_option_value);
}
diff --git a/libtransport/src/interfaces/socket_producer.cc b/libtransport/src/interfaces/socket_producer.cc
index d030fe7..b04947d 100644
--- a/libtransport/src/interfaces/socket_producer.cc
+++ b/libtransport/src/interfaces/socket_producer.cc
@@ -14,7 +14,6 @@
*/
#include <hicn/transport/interfaces/socket_producer.h>
-
#include <implementation/socket_producer.h>
#include <atomic>
@@ -31,11 +30,12 @@ namespace interface {
using namespace core;
ProducerSocket::ProducerSocket(int protocol) {
- if (protocol != 0) {
- throw std::runtime_error("Production protocol must be 0.");
- }
+ socket_ = std::make_unique<implementation::ProducerSocket>(this, protocol);
+}
- socket_ = std::make_unique<implementation::ProducerSocket>(this);
+ProducerSocket::ProducerSocket(int protocol, asio::io_service &io_service) {
+ socket_ = std::make_unique<implementation::ProducerSocket>(this, protocol,
+ io_service);
}
ProducerSocket::ProducerSocket(bool) {}
@@ -46,19 +46,34 @@ void ProducerSocket::connect() { socket_->connect(); }
bool ProducerSocket::isRunning() { return socket_->isRunning(); }
-uint32_t ProducerSocket::produce(Name content_name,
- std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last, uint32_t start_offset) {
- return socket_->produce(content_name, std::move(buffer), is_last,
- start_offset);
+uint32_t ProducerSocket::produceStream(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last, uint32_t start_offset) {
+ return socket_->produceStream(content_name, std::move(buffer), is_last,
+ start_offset);
}
-void ProducerSocket::produce(ContentObject &content_object) {
- return socket_->produce(content_object);
+uint32_t ProducerSocket::produceStream(const Name &content_name,
+ const uint8_t *buffer,
+ size_t buffer_size, bool is_last,
+ uint32_t start_offset) {
+ return socket_->produceStream(content_name, buffer, buffer_size, is_last,
+ start_offset);
}
-void ProducerSocket::produce(std::unique_ptr<utils::MemBuf> &&buffer) {
- socket_->produce(std::move(buffer));
+uint32_t ProducerSocket::produceDatagram(
+ const Name &content_name, std::unique_ptr<utils::MemBuf> &&buffer) {
+ return socket_->produceDatagram(content_name, std::move(buffer));
+}
+
+uint32_t ProducerSocket::produceDatagram(const Name &content_name,
+ const uint8_t *buffer,
+ size_t buffer_size) {
+ return socket_->produceDatagram(content_name, buffer, buffer_size);
+}
+
+void ProducerSocket::produce(ContentObject &content_object) {
+ return socket_->produce(content_object);
}
void ProducerSocket::asyncProduce(Name content_name,
@@ -69,16 +84,10 @@ void ProducerSocket::asyncProduce(Name content_name,
last_segment);
}
-void ProducerSocket::asyncProduce(ContentObject &content_object) {
- return socket_->asyncProduce(content_object);
-}
-
void ProducerSocket::registerPrefix(const Prefix &producer_namespace) {
return socket_->registerPrefix(producer_namespace);
}
-void ProducerSocket::serveForever() { return socket_->serveForever(); }
-
void ProducerSocket::stop() { return socket_->stop(); }
asio::io_service &ProducerSocket::getIoService() {
@@ -105,11 +114,6 @@ int ProducerSocket::setSocketOption(int socket_option_key,
return socket_->setSocketOption(socket_option_key, socket_option_value);
}
-int ProducerSocket::setSocketOption(int socket_option_key,
- std::list<Prefix> socket_option_value) {
- return socket_->setSocketOption(socket_option_key, socket_option_value);
-}
-
int ProducerSocket::setSocketOption(
int socket_option_key, ProducerContentObjectCallback socket_option_value) {
return socket_->setSocketOption(socket_option_key, socket_option_value);
@@ -126,18 +130,13 @@ int ProducerSocket::setSocketOption(
}
int ProducerSocket::setSocketOption(int socket_option_key,
- utils::CryptoHashType socket_option_value) {
- return socket_->setSocketOption(socket_option_key, socket_option_value);
-}
-
-int ProducerSocket::setSocketOption(int socket_option_key,
- utils::CryptoSuite socket_option_value) {
+ auth::CryptoHashType socket_option_value) {
return socket_->setSocketOption(socket_option_key, socket_option_value);
}
int ProducerSocket::setSocketOption(
int socket_option_key,
- const std::shared_ptr<utils::Signer> &socket_option_value) {
+ const std::shared_ptr<auth::Signer> &socket_option_value) {
return socket_->setSocketOption(socket_option_key, socket_option_value);
}
@@ -156,11 +155,6 @@ int ProducerSocket::getSocketOption(int socket_option_key,
return socket_->getSocketOption(socket_option_key, socket_option_value);
}
-int ProducerSocket::getSocketOption(int socket_option_key,
- std::list<Prefix> &socket_option_value) {
- return socket_->getSocketOption(socket_option_key, socket_option_value);
-}
-
int ProducerSocket::getSocketOption(
int socket_option_key,
ProducerContentObjectCallback **socket_option_value) {
@@ -177,19 +171,13 @@ int ProducerSocket::getSocketOption(
return socket_->getSocketOption(socket_option_key, socket_option_value);
}
-int ProducerSocket::getSocketOption(
- int socket_option_key, utils::CryptoHashType &socket_option_value) {
- return socket_->getSocketOption(socket_option_key, socket_option_value);
-}
-
int ProducerSocket::getSocketOption(int socket_option_key,
- utils::CryptoSuite &socket_option_value) {
+ auth::CryptoHashType &socket_option_value) {
return socket_->getSocketOption(socket_option_key, socket_option_value);
}
int ProducerSocket::getSocketOption(
- int socket_option_key,
- std::shared_ptr<utils::Signer> &socket_option_value) {
+ int socket_option_key, std::shared_ptr<auth::Signer> &socket_option_value) {
return socket_->getSocketOption(socket_option_key, socket_option_value);
}
diff --git a/libtransport/src/interfaces/tls_rtc_socket_producer.cc b/libtransport/src/interfaces/tls_rtc_socket_producer.cc
index 132f347..7326fcb 100644
--- a/libtransport/src/interfaces/tls_rtc_socket_producer.cc
+++ b/libtransport/src/interfaces/tls_rtc_socket_producer.cc
@@ -13,9 +13,8 @@
* limitations under the License.
*/
-#include <interfaces/tls_rtc_socket_producer.h>
-
#include <implementation/tls_rtc_socket_producer.h>
+#include <interfaces/tls_rtc_socket_producer.h>
namespace transport {
namespace interface {
diff --git a/libtransport/src/interfaces/tls_socket_consumer.cc b/libtransport/src/interfaces/tls_socket_consumer.cc
index d87642f..6c1c535 100644
--- a/libtransport/src/interfaces/tls_socket_consumer.cc
+++ b/libtransport/src/interfaces/tls_socket_consumer.cc
@@ -13,9 +13,8 @@
* limitations under the License.
*/
-#include <interfaces/tls_socket_consumer.h>
-
#include <implementation/tls_socket_consumer.h>
+#include <interfaces/tls_socket_consumer.h>
namespace transport {
namespace interface {
diff --git a/libtransport/src/interfaces/tls_socket_producer.cc b/libtransport/src/interfaces/tls_socket_producer.cc
index 44aa0cf..037702f 100644
--- a/libtransport/src/interfaces/tls_socket_producer.cc
+++ b/libtransport/src/interfaces/tls_socket_producer.cc
@@ -13,9 +13,8 @@
* limitations under the License.
*/
-#include <interfaces/tls_socket_producer.h>
-
#include <implementation/tls_socket_producer.h>
+#include <interfaces/tls_socket_producer.h>
namespace transport {
namespace interface {
diff --git a/libtransport/src/io_modules/CMakeLists.txt b/libtransport/src/io_modules/CMakeLists.txt
new file mode 100644
index 0000000..6553b9a
--- /dev/null
+++ b/libtransport/src/io_modules/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (c) 2021 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+if (${CMAKE_SYSTEM_NAME} MATCHES Android)
+ list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp/hicn_forwarder_module.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp/udp_socket_connector.cc
+ )
+
+ list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp/hicn_forwarder_module.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp/udp_socket_connector.h
+ )
+
+ set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
+ set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE)
+else()
+ add_subdirectory(udp)
+ add_subdirectory(loopback)
+ add_subdirectory(forwarder)
+
+ if (__vpp__)
+ add_subdirectory(memif)
+ endif()
+endif() \ No newline at end of file
diff --git a/libtransport/src/io_modules/forwarder/CMakeLists.txt b/libtransport/src/io_modules/forwarder/CMakeLists.txt
new file mode 100644
index 0000000..92662bc
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/CMakeLists.txt
@@ -0,0 +1,44 @@
+# Copyright (c) 2021 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+
+list(APPEND MODULE_HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/connector.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/endpoint.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/errors.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/forwarder_module.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/forwarder.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnel_listener.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnel.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/global_counter.h
+)
+
+list(APPEND MODULE_SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/errors.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/forwarder_module.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/forwarder.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnel_listener.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnel.cc
+)
+
+build_module(forwarder_module
+ SHARED
+ SOURCES ${MODULE_SOURCE_FILES}
+ DEPENDS ${DEPENDENCIES}
+ COMPONENT lib${LIBTRANSPORT}
+ INCLUDE_DIRS ${LIBTRANSPORT_INCLUDE_DIRS} ${LIBTRANSPORT_INTERNAL_INCLUDE_DIRS}
+ DEFINITIONS ${COMPILER_DEFINITIONS}
+ COMPILE_OPTIONS ${COMPILE_FLAGS}
+)
diff --git a/libtransport/src/io_modules/forwarder/configuration.h b/libtransport/src/io_modules/forwarder/configuration.h
new file mode 100644
index 0000000..fcaa553
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/configuration.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace transport {
+namespace core {
+
+struct ListenerConfig {
+ std::string address;
+ std::uint16_t port;
+ std::string name;
+};
+
+struct ConnectorConfig {
+ std::string local_address;
+ std::uint16_t local_port;
+ std::string remote_address;
+ std::uint16_t remote_port;
+ std::string name;
+};
+
+struct RouteConfig {
+ std::string prefix;
+ uint16_t weight;
+ std::string connector;
+ std::string name;
+};
+
+class Configuration {
+ public:
+ Configuration() : n_threads_(1) {}
+
+ bool empty() {
+ return listeners_.empty() && connectors_.empty() && routes_.empty();
+ }
+
+ Configuration& setThreadNumber(std::size_t threads) {
+ n_threads_ = threads;
+ return *this;
+ }
+
+ std::size_t getThreadNumber() { return n_threads_; }
+
+ template <typename... Args>
+ Configuration& addListener(Args&&... args) {
+ listeners_.emplace_back(std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template <typename... Args>
+ Configuration& addConnector(Args&&... args) {
+ connectors_.emplace_back(std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template <typename... Args>
+ Configuration& addRoute(Args&&... args) {
+ routes_.emplace_back(std::forward<Args>(args)...);
+ return *this;
+ }
+
+ std::vector<ListenerConfig>& getListeners() { return listeners_; }
+
+ std::vector<ConnectorConfig>& getConnectors() { return connectors_; }
+
+ std::vector<RouteConfig>& getRoutes() { return routes_; }
+
+ private:
+ std::vector<ListenerConfig> listeners_;
+ std::vector<ConnectorConfig> connectors_;
+ std::vector<RouteConfig> routes_;
+ std::size_t n_threads_;
+};
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/io_modules/forwarder/errors.cc b/libtransport/src/io_modules/forwarder/errors.cc
new file mode 100644
index 0000000..b5f1314
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/errors.cc
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ */
+
+#include <io_modules/forwarder/errors.h>
+
+namespace transport {
+namespace core {
+
+const std::error_category& forwarder_category() {
+ static forwarder_category_impl instance;
+
+ return instance;
+}
+
+const char* forwarder_category_impl::name() const throw() {
+ return "proxy::connector::error";
+}
+
+std::string forwarder_category_impl::message(int ev) const {
+ switch (static_cast<forwarder_error>(ev)) {
+ case forwarder_error::success: {
+ return "Success";
+ }
+ case forwarder_error::disconnected: {
+ return "Connector is disconnected";
+ }
+ case forwarder_error::receive_failed: {
+ return "Packet reception failed";
+ }
+ case forwarder_error::send_failed: {
+ return "Packet send failed";
+ }
+ case forwarder_error::memory_allocation_error: {
+ return "Impossible to allocate memory for packet pool";
+ }
+ case forwarder_error::invalid_connector_type: {
+ return "Invalid type specified for connector.";
+ }
+ case forwarder_error::invalid_connector: {
+ return "Created connector was invalid.";
+ }
+ case forwarder_error::interest_cache_miss: {
+ return "interest cache miss.";
+ }
+ default: {
+ return "Unknown connector error";
+ }
+ }
+}
+} // namespace core
+} // namespace transport
diff --git a/libtransport/src/io_modules/forwarder/errors.h b/libtransport/src/io_modules/forwarder/errors.h
new file mode 100644
index 0000000..dd5cc8f
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/errors.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <system_error>
+
+namespace transport {
+namespace core {
+/**
+ * @brief Get the default server error category.
+ * @return The default server error category instance.
+ *
+ * @warning The first call to this function is thread-safe only starting with
+ * C++11.
+ */
+const std::error_category& forwarder_category();
+
+/**
+ * The list of errors.
+ */
+enum class forwarder_error {
+ success = 0,
+ send_failed,
+ receive_failed,
+ disconnected,
+ memory_allocation_error,
+ invalid_connector_type,
+ invalid_connector,
+ interest_cache_miss
+};
+
+/**
+ * @brief Create an error_code instance for the given error.
+ * @param error The error.
+ * @return The error_code instance.
+ */
+inline std::error_code make_error_code(forwarder_error error) {
+ return std::error_code(static_cast<int>(error), forwarder_category());
+}
+
+/**
+ * @brief Create an error_condition instance for the given error.
+ * @param error The error.
+ * @return The error_condition instance.
+ */
+inline std::error_condition make_error_condition(forwarder_error error) {
+ return std::error_condition(static_cast<int>(error), forwarder_category());
+}
+
+/**
+ * @brief A server error category.
+ */
+class forwarder_category_impl : public std::error_category {
+ public:
+ /**
+ * @brief Get the name of the category.
+ * @return The name of the category.
+ */
+ virtual const char* name() const throw();
+
+ /**
+ * @brief Get the error message for a given error.
+ * @param ev The error numeric value.
+ * @return The message associated to the error.
+ */
+ virtual std::string message(int ev) const;
+};
+} // namespace core
+} // namespace transport
+
+namespace std {
+// namespace system {
+template <>
+struct is_error_code_enum<::transport::core::forwarder_error>
+ : public std::true_type {};
+// } // namespace system
+} // namespace std
diff --git a/libtransport/src/io_modules/forwarder/forwarder.cc b/libtransport/src/io_modules/forwarder/forwarder.cc
new file mode 100644
index 0000000..7e89e2f
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/forwarder.cc
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core/global_configuration.h>
+#include <core/local_connector.h>
+#include <io_modules/forwarder/forwarder.h>
+#include <io_modules/forwarder/global_id_counter.h>
+#include <io_modules/forwarder/udp_tunnel.h>
+#include <io_modules/forwarder/udp_tunnel_listener.h>
+
+namespace transport {
+
+namespace core {
+
+constexpr char Forwarder::forwarder_config_section[];
+
+Forwarder::Forwarder() : config_() {
+ using namespace std::placeholders;
+ GlobalConfiguration::getInstance().registerConfigurationParser(
+ forwarder_config_section,
+ std::bind(&Forwarder::parseForwarderConfiguration, this, _1, _2));
+
+ if (!config_.empty()) {
+ initThreads();
+ initListeners();
+ initConnectors();
+ }
+}
+
+Forwarder::~Forwarder() {
+ for (auto &l : listeners_) {
+ l->close();
+ }
+
+ for (auto &c : remote_connectors_) {
+ c.second->close();
+ }
+
+ GlobalConfiguration::getInstance().unregisterConfigurationParser(
+ forwarder_config_section);
+}
+
+void Forwarder::initThreads() {
+ for (unsigned i = 0; i < config_.getThreadNumber(); i++) {
+ thread_pool_.emplace_back(io_service_, /* detached */ false);
+ }
+}
+
+void Forwarder::initListeners() {
+ using namespace std::placeholders;
+ for (auto &l : config_.getListeners()) {
+ listeners_.emplace_back(std::make_shared<UdpTunnelListener>(
+ io_service_,
+ std::bind(&Forwarder::onPacketFromListener, this, _1, _2, _3),
+ asio::ip::udp::endpoint(asio::ip::address::from_string(l.address),
+ l.port)));
+ }
+}
+
+void Forwarder::initConnectors() {
+ using namespace std::placeholders;
+ for (auto &c : config_.getConnectors()) {
+ auto id = GlobalCounter<Connector::Id>::getInstance().getNext();
+ auto conn = new UdpTunnelConnector(
+ io_service_, std::bind(&Forwarder::onPacketReceived, this, _1, _2, _3),
+ std::bind(&Forwarder::onPacketSent, this, _1, _2),
+ std::bind(&Forwarder::onConnectorClosed, this, _1),
+ std::bind(&Forwarder::onConnectorReconnected, this, _1));
+ conn->setConnectorId(id);
+ remote_connectors_.emplace(id, conn);
+ conn->connect(c.remote_address, c.remote_port, c.local_address,
+ c.local_port);
+ }
+}
+
+Connector::Id Forwarder::registerLocalConnector(
+ asio::io_service &io_service,
+ Connector::PacketReceivedCallback &&receive_callback,
+ Connector::OnReconnectCallback &&reconnect_callback) {
+ utils::SpinLock::Acquire locked(connector_lock_);
+ auto id = GlobalCounter<Connector::Id>::getInstance().getNext();
+ auto connector = std::make_shared<LocalConnector>(
+ io_service, receive_callback, nullptr, nullptr, reconnect_callback);
+ connector->setConnectorId(id);
+ local_connectors_.emplace(id, std::move(connector));
+ return id;
+}
+
+Forwarder &Forwarder::deleteConnector(Connector::Id id) {
+ utils::SpinLock::Acquire locked(connector_lock_);
+ auto it = local_connectors_.find(id);
+ if (it != local_connectors_.end()) {
+ it->second->close();
+ local_connectors_.erase(it);
+ }
+
+ return *this;
+}
+
+Connector::Ptr Forwarder::getConnector(Connector::Id id) {
+ utils::SpinLock::Acquire locked(connector_lock_);
+ auto it = local_connectors_.find(id);
+ if (it != local_connectors_.end()) {
+ return it->second;
+ }
+
+ return nullptr;
+}
+
+void Forwarder::onPacketFromListener(Connector *connector,
+ utils::MemBuf &packet_buffer,
+ const std::error_code &ec) {
+ // Create connector
+ connector->setReceiveCallback(
+ std::bind(&Forwarder::onPacketReceived, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3));
+
+ TRANSPORT_LOGD("Packet received from listener.");
+
+ {
+ utils::SpinLock::Acquire locked(connector_lock_);
+ remote_connectors_.emplace(connector->getConnectorId(),
+ connector->shared_from_this());
+ }
+ // TODO Check if control packet or not. For the moment it is not.
+ onPacketReceived(connector, packet_buffer, ec);
+}
+
+void Forwarder::onPacketReceived(Connector *connector,
+ utils::MemBuf &packet_buffer,
+ const std::error_code &ec) {
+ // Figure out the type of packet we received
+ bool is_interest = Packet::isInterest(packet_buffer.data());
+
+ Packet *packet = nullptr;
+ if (is_interest) {
+ packet = static_cast<Interest *>(&packet_buffer);
+ } else {
+ packet = static_cast<ContentObject *>(&packet_buffer);
+ }
+
+ for (auto &c : local_connectors_) {
+ auto role = c.second->getRole();
+ auto is_producer = role == Connector::Role::PRODUCER;
+ if ((is_producer && is_interest) || (!is_producer && !is_interest)) {
+ c.second->send(*packet);
+ } else {
+ TRANSPORT_LOGD(
+ "Error sending packet to local connector. is_interest = %d - "
+ "is_producer = %d",
+ (int)is_interest, (int)is_producer);
+ }
+ }
+
+ // PCS Lookup + FIB lookup. Skip for now
+
+ // Forward packet to local connectors
+}
+
+void Forwarder::send(Packet &packet) {
+ // TODo Here a nice PIT/CS / FIB would be required:)
+ // For now let's just forward the packet on the remote connector we get
+ if (remote_connectors_.begin() == remote_connectors_.end()) {
+ return;
+ }
+
+ auto remote_endpoint =
+ remote_connectors_.begin()->second->getRemoteEndpoint();
+ TRANSPORT_LOGD("Sending packet to: %s:%u",
+ remote_endpoint.getAddress().to_string().c_str(),
+ remote_endpoint.getPort());
+ remote_connectors_.begin()->second->send(packet);
+}
+
+void Forwarder::onPacketSent(Connector *connector, const std::error_code &ec) {}
+
+void Forwarder::onConnectorClosed(Connector *connector) {}
+
+void Forwarder::onConnectorReconnected(Connector *connector) {}
+
+void Forwarder::parseForwarderConfiguration(
+ const libconfig::Setting &forwarder_config, std::error_code &ec) {
+ using namespace libconfig;
+
+ // n_thread
+ if (forwarder_config.exists("n_threads")) {
+ // Get number of threads
+ int n_threads = 1;
+ forwarder_config.lookupValue("n_threads", n_threads);
+ TRANSPORT_LOGD("Forwarder threads from config file: %u", n_threads);
+ config_.setThreadNumber(n_threads);
+ }
+
+ // listeners
+ if (forwarder_config.exists("listeners")) {
+ // get path where looking for modules
+ const Setting &listeners = forwarder_config.lookup("listeners");
+ auto count = listeners.getLength();
+
+ for (int i = 0; i < count; i++) {
+ const Setting &listener = listeners[i];
+ ListenerConfig list;
+ unsigned port;
+
+ list.name = listener.getName();
+ listener.lookupValue("local_address", list.address);
+ listener.lookupValue("local_port", port);
+ list.port = (uint16_t)(port);
+
+ TRANSPORT_LOGD("Adding listener %s, (%s:%u)", list.name.c_str(),
+ list.address.c_str(), list.port);
+ config_.addListener(std::move(list));
+ }
+ }
+
+ // connectors
+ if (forwarder_config.exists("connectors")) {
+ // get path where looking for modules
+ const Setting &connectors = forwarder_config.lookup("connectors");
+ auto count = connectors.getLength();
+
+ for (int i = 0; i < count; i++) {
+ const Setting &connector = connectors[i];
+ ConnectorConfig conn;
+
+ conn.name = connector.getName();
+ unsigned port = 0;
+
+ if (!connector.lookupValue("local_address", conn.local_address)) {
+ conn.local_address = "";
+ }
+
+ if (!connector.lookupValue("local_port", port)) {
+ port = 0;
+ }
+
+ conn.local_port = (uint16_t)(port);
+
+ if (!connector.lookupValue("remote_address", conn.remote_address)) {
+ throw errors::RuntimeException(
+ "Error in configuration file: remote_address is a mandatory field "
+ "of Connectors.");
+ }
+
+ if (!connector.lookupValue("remote_port", port)) {
+ throw errors::RuntimeException(
+ "Error in configuration file: remote_port is a mandatory field "
+ "of Connectors.");
+ }
+
+ conn.remote_port = (uint16_t)(port);
+
+ TRANSPORT_LOGD("Adding connector %s, (%s:%u %s:%u)", conn.name.c_str(),
+ conn.local_address.c_str(), conn.local_port,
+ conn.remote_address.c_str(), conn.remote_port);
+ config_.addConnector(std::move(conn));
+ }
+ }
+
+ // Routes
+ if (forwarder_config.exists("routes")) {
+ const Setting &routes = forwarder_config.lookup("routes");
+ auto count = routes.getLength();
+
+ for (int i = 0; i < count; i++) {
+ const Setting &route = routes[i];
+ RouteConfig r;
+ unsigned weight;
+
+ r.name = route.getName();
+ route.lookupValue("prefix", r.prefix);
+ route.lookupValue("weight", weight);
+ route.lookupValue("connector", r.connector);
+ r.weight = (uint16_t)(weight);
+
+ TRANSPORT_LOGD("Adding route %s %s (%s %u)", r.name.c_str(),
+ r.prefix.c_str(), r.connector.c_str(), r.weight);
+ config_.addRoute(std::move(r));
+ }
+ }
+}
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/io_modules/forwarder/forwarder.h b/libtransport/src/io_modules/forwarder/forwarder.h
new file mode 100644
index 0000000..5b564bb
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/forwarder.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/io_module.h>
+#include <hicn/transport/core/prefix.h>
+#include <hicn/transport/utils/event_thread.h>
+#include <hicn/transport/utils/singleton.h>
+#include <hicn/transport/utils/spinlock.h>
+#include <io_modules/forwarder/configuration.h>
+#include <io_modules/forwarder/udp_tunnel_listener.h>
+
+#include <atomic>
+#include <libconfig.h++>
+#include <unordered_map>
+
+namespace transport {
+
+namespace core {
+
+class Forwarder : public utils::Singleton<Forwarder> {
+ static constexpr char forwarder_config_section[] = "forwarder";
+ friend class utils::Singleton<Forwarder>;
+
+ public:
+ Forwarder();
+
+ ~Forwarder();
+
+ void initThreads();
+ void initListeners();
+ void initConnectors();
+
+ Connector::Id registerLocalConnector(
+ asio::io_service &io_service,
+ Connector::PacketReceivedCallback &&receive_callback,
+ Connector::OnReconnectCallback &&reconnect_callback);
+
+ Forwarder &deleteConnector(Connector::Id id);
+
+ Connector::Ptr getConnector(Connector::Id id);
+
+ void send(Packet &packet);
+
+ void stop();
+
+ private:
+ void onPacketFromListener(Connector *connector, utils::MemBuf &packet_buffer,
+ const std::error_code &ec);
+ void onPacketReceived(Connector *connector, utils::MemBuf &packet_buffer,
+ const std::error_code &ec);
+ void onPacketSent(Connector *connector, const std::error_code &ec);
+ void onConnectorClosed(Connector *connector);
+ void onConnectorReconnected(Connector *connector);
+
+ void parseForwarderConfiguration(const libconfig::Setting &io_config,
+ std::error_code &ec);
+
+ asio::io_service io_service_;
+ utils::SpinLock connector_lock_;
+
+ /**
+ * Connectors and listeners must be declares *before* thread_pool_, so that
+ * threads destructors will wait for them to gracefully close before being
+ * destroyed.
+ */
+ std::unordered_map<Connector::Id, Connector::Ptr> remote_connectors_;
+ std::unordered_map<Connector::Id, Connector::Ptr> local_connectors_;
+ std::vector<UdpTunnelListener::Ptr> listeners_;
+
+ std::vector<utils::EventThread> thread_pool_;
+
+ Configuration config_;
+};
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/io_modules/forwarder/forwarder_module.cc b/libtransport/src/io_modules/forwarder/forwarder_module.cc
new file mode 100644
index 0000000..356b42d
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/forwarder_module.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017-2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/errors/not_implemented_exception.h>
+#include <hicn/transport/utils/log.h>
+#include <io_modules/forwarder/forwarder_module.h>
+
+namespace transport {
+
+namespace core {
+
+ForwarderModule::ForwarderModule()
+ : IoModule(),
+ name_(""),
+ connector_id_(Connector::invalid_connector),
+ forwarder_(Forwarder::getInstance()) {}
+
+ForwarderModule::~ForwarderModule() {
+ forwarder_.deleteConnector(connector_id_);
+}
+
+bool ForwarderModule::isConnected() { return true; }
+
+void ForwarderModule::send(Packet &packet) {
+ IoModule::send(packet);
+ forwarder_.send(packet);
+ // TRANSPORT_LOGD("ForwarderModule: sending from %u to %d", local_id_,
+ // 1 - local_id_);
+
+ // local_faces_.at(1 - local_id_).onPacket(packet);
+}
+
+void ForwarderModule::send(const uint8_t *packet, std::size_t len) {
+ // not supported
+ throw errors::NotImplementedException();
+}
+
+void ForwarderModule::registerRoute(const Prefix &prefix) {
+ // For the moment we route packets from one socket to the other.
+ // Next step will be to introduce a FIB
+ return;
+}
+
+void ForwarderModule::closeConnection() {
+ forwarder_.deleteConnector(connector_id_);
+}
+
+void ForwarderModule::init(Connector::PacketReceivedCallback &&receive_callback,
+ Connector::OnReconnectCallback &&reconnect_callback,
+ asio::io_service &io_service,
+ const std::string &app_name) {
+ connector_id_ = forwarder_.registerLocalConnector(
+ io_service, std::move(receive_callback), std::move(reconnect_callback));
+ name_ = app_name;
+}
+
+void ForwarderModule::processControlMessageReply(utils::MemBuf &packet_buffer) {
+ return;
+}
+
+void ForwarderModule::connect(bool is_consumer) {
+ forwarder_.getConnector(connector_id_)
+ ->setRole(is_consumer ? Connector::Role::CONSUMER
+ : Connector::Role::PRODUCER);
+}
+
+std::uint32_t ForwarderModule::getMtu() { return interface_mtu; }
+
+bool ForwarderModule::isControlMessage(const uint8_t *message) { return false; }
+
+extern "C" IoModule *create_module(void) { return new ForwarderModule(); }
+
+} // namespace core
+
+} // namespace transport
diff --git a/libtransport/src/io_modules/forwarder/forwarder_module.h b/libtransport/src/io_modules/forwarder/forwarder_module.h
new file mode 100644
index 0000000..58bfb79
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/forwarder_module.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/io_module.h>
+#include <hicn/transport/core/prefix.h>
+#include <io_modules/forwarder/forwarder.h>
+
+#include <atomic>
+
+namespace transport {
+
+namespace core {
+
+class Forwarder;
+
+class ForwarderModule : public IoModule {
+ static constexpr std::uint16_t interface_mtu = 1500;
+
+ public:
+ ForwarderModule();
+
+ ~ForwarderModule();
+
+ void connect(bool is_consumer) override;
+
+ void send(Packet &packet) override;
+ void send(const uint8_t *packet, std::size_t len) override;
+
+ bool isConnected() override;
+
+ void init(Connector::PacketReceivedCallback &&receive_callback,
+ Connector::OnReconnectCallback &&reconnect_callback,
+ asio::io_service &io_service,
+ const std::string &app_name = "Libtransport") override;
+
+ void registerRoute(const Prefix &prefix) override;
+
+ std::uint32_t getMtu() override;
+
+ bool isControlMessage(const uint8_t *message) override;
+
+ void processControlMessageReply(utils::MemBuf &packet_buffer) override;
+
+ void closeConnection() override;
+
+ private:
+ std::string name_;
+ Connector::Id connector_id_;
+ Forwarder &forwarder_;
+};
+
+extern "C" IoModule *create_module(void);
+
+} // namespace core
+
+} // namespace transport
diff --git a/libtransport/src/io_modules/forwarder/global_id_counter.h b/libtransport/src/io_modules/forwarder/global_id_counter.h
new file mode 100644
index 0000000..fe8d767
--- /dev/null
+++ b/libtransport/src/io_modules/forwarder/global_id_counter.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <mutex>
+
+namespace transport {
+
+namespace core {
+
+template <typename T = uint64_t>
+class GlobalCounter {
+ public:
+ static GlobalCounter& getInstance() {
+ std::lock_guard<std::mutex> lock(global_mutex_);
+
+ if (!instance_) {
+ instance_.reset(new GlobalCounter());
+ }
+
+ return *instance_;
+ }
+
+ T getNext() { return counter_++; }
+
+ private:
+ GlobalCounter() : counter_(0) {}
+ static std::unique_ptr<GlobalCounter<T>> instance_;
+ static std::mutex global_mutex_;
+ std::atomic<T> counter_;
+};
+
+template <typename T>
+std::unique_ptr<GlobalCounter<T>> GlobalCounter<T>::instance_ = nullptr;
+
+template <typename T>
+std::mutex GlobalCounter<T>::global_mutex_;
+
+} // namespace c