aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Muscariello <lumuscar+fdio@cisco.com>2019-01-17 13:47:57 +0100
committerLuca Muscariello <lumuscar+fdio@cisco.com>2019-01-17 16:32:51 +0100
commitbac3da61644515f05663789b122554dc77549286 (patch)
tree898210bc8e70371d77de7d446a26c5dd4fd1165a
parentd5165246787301d0f13b646fda5e8a8567aef5ac (diff)
This is the first commit of the hicn projectv19.01
Change-Id: I6f2544ad9b9f8891c88cc4bcce3cf19bd3cc863f Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
-rw-r--r--.gitreview4
-rwxr-xr-xAUTHORS6
-rwxr-xr-xCMakeLists.txt51
-rwxr-xr-xLICENSE202
-rwxr-xr-xREADME.md33
-rwxr-xr-xapps/README.md2
-rwxr-xr-xcmake/Modules/BuildMacros.cmake146
-rwxr-xr-xcmake/Modules/FindAsio.cmake41
-rwxr-xr-xcmake/Modules/FindGFlags.cmake36
-rwxr-xr-xcmake/Modules/FindGlog.cmake36
-rwxr-xr-xcmake/Modules/FindHicnBinaryApi.cmake31
-rwxr-xr-xcmake/Modules/FindLibEvent.cmake55
-rwxr-xr-xcmake/Modules/FindLibhicn.cmake49
-rwxr-xr-xcmake/Modules/FindLibmemif.cmake47
-rwxr-xr-xcmake/Modules/FindLibparc.cmake50
-rwxr-xr-xcmake/Modules/FindLibtransport.cmake48
-rwxr-xr-xcmake/Modules/FindLongBow.cmake55
-rwxr-xr-xcmake/Modules/FindUncrustify.cmake21
-rwxr-xr-xcmake/Modules/FindVpp.cmake67
-rwxr-xr-xcmake/Modules/IosMacros.cmake24
-rwxr-xr-xcmake/Modules/Packager.cmake105
-rwxr-xr-xcmake/Modules/detectCacheSize.cmake21
-rwxr-xr-xhicn-light/CMakeLists.txt74
-rwxr-xr-xhicn-light/README.md302
-rwxr-xr-xhicn-light/config/hicn-light.service29
-rwxr-xr-xhicn-light/src/CMakeLists.txt45
-rwxr-xr-xhicn-light/src/command_line/CMakeLists.txt2
-rwxr-xr-xhicn-light/src/command_line/controller/CMakeLists.txt23
-rwxr-xr-xhicn-light/src/command_line/controller/hicnLightControl_main.c284
-rwxr-xr-xhicn-light/src/command_line/daemon/CMakeLists.txt23
-rwxr-xr-xhicn-light/src/command_line/daemon/hicnLightDaemon_main.c336
-rwxr-xr-xhicn-light/src/config.h.in5
-rwxr-xr-xhicn-light/src/config/CMakeLists.txt97
-rwxr-xr-xhicn-light/src/config/commandOps.c72
-rwxr-xr-xhicn-light/src/config/commandOps.h126
-rwxr-xr-xhicn-light/src/config/commandParser.c216
-rwxr-xr-xhicn-light/src/config/commandParser.h196
-rwxr-xr-xhicn-light/src/config/commandReturn.h43
-rwxr-xr-xhicn-light/src/config/configuration.c1076
-rwxr-xr-xhicn-light/src/config/configuration.h152
-rwxr-xr-xhicn-light/src/config/configurationFile.c300
-rwxr-xr-xhicn-light/src/config/configurationFile.h93
-rwxr-xr-xhicn-light/src/config/configurationListeners.c535
-rwxr-xr-xhicn-light/src/config/configurationListeners.h62
-rwxr-xr-xhicn-light/src/config/controlAdd.c94
-rwxr-xr-xhicn-light/src/config/controlAdd.h32
-rwxr-xr-xhicn-light/src/config/controlAddConnection.c390
-rwxr-xr-xhicn-light/src/config/controlAddConnection.h31
-rwxr-xr-xhicn-light/src/config/controlAddListener.c178
-rwxr-xr-xhicn-light/src/config/controlAddListener.h30
-rwxr-xr-xhicn-light/src/config/controlAddPunting.c154
-rwxr-xr-xhicn-light/src/config/controlAddPunting.h22
-rwxr-xr-xhicn-light/src/config/controlAddRoute.c157
-rwxr-xr-xhicn-light/src/config/controlAddRoute.h30
-rwxr-xr-xhicn-light/src/config/controlCache.c91
-rwxr-xr-xhicn-light/src/config/controlCache.h22
-rwxr-xr-xhicn-light/src/config/controlCacheClear.c84
-rwxr-xr-xhicn-light/src/config/controlCacheClear.h30
-rwxr-xr-xhicn-light/src/config/controlCacheServe.c103
-rwxr-xr-xhicn-light/src/config/controlCacheServe.h22
-rwxr-xr-xhicn-light/src/config/controlCacheStore.c103
-rwxr-xr-xhicn-light/src/config/controlCacheStore.h22
-rwxr-xr-xhicn-light/src/config/controlList.c97
-rwxr-xr-xhicn-light/src/config/controlList.h30
-rwxr-xr-xhicn-light/src/config/controlListConnections.c160
-rwxr-xr-xhicn-light/src/config/controlListConnections.h30
-rwxr-xr-xhicn-light/src/config/controlListInterfaces.c76
-rwxr-xr-xhicn-light/src/config/controlListInterfaces.h31
-rwxr-xr-xhicn-light/src/config/controlListListeners.c141
-rwxr-xr-xhicn-light/src/config/controlListListeners.h31
-rwxr-xr-xhicn-light/src/config/controlListRoutes.c154
-rwxr-xr-xhicn-light/src/config/controlListRoutes.h29
-rwxr-xr-xhicn-light/src/config/controlMapMe.c94
-rwxr-xr-xhicn-light/src/config/controlMapMe.h22
-rwxr-xr-xhicn-light/src/config/controlMapMeDiscovery.c103
-rwxr-xr-xhicn-light/src/config/controlMapMeDiscovery.h22
-rwxr-xr-xhicn-light/src/config/controlMapMeEnable.c101
-rwxr-xr-xhicn-light/src/config/controlMapMeEnable.h22
-rwxr-xr-xhicn-light/src/config/controlMapMeRetx.c94
-rwxr-xr-xhicn-light/src/config/controlMapMeRetx.h22
-rwxr-xr-xhicn-light/src/config/controlMapMeTimescale.c97
-rwxr-xr-xhicn-light/src/config/controlMapMeTimescale.h22
-rwxr-xr-xhicn-light/src/config/controlQuit.c63
-rwxr-xr-xhicn-light/src/config/controlQuit.h29
-rwxr-xr-xhicn-light/src/config/controlRemove.c92
-rwxr-xr-xhicn-light/src/config/controlRemove.h29
-rwxr-xr-xhicn-light/src/config/controlRemoveConnection.c115
-rwxr-xr-xhicn-light/src/config/controlRemoveConnection.h31
-rwxr-xr-xhicn-light/src/config/controlRemovePunting.c76
-rwxr-xr-xhicn-light/src/config/controlRemovePunting.h27
-rwxr-xr-xhicn-light/src/config/controlRemoveRoute.c150
-rwxr-xr-xhicn-light/src/config/controlRemoveRoute.h31
-rwxr-xr-xhicn-light/src/config/controlRoot.c134
-rwxr-xr-xhicn-light/src/config/controlRoot.h31
-rwxr-xr-xhicn-light/src/config/controlSet.c88
-rwxr-xr-xhicn-light/src/config/controlSet.h29
-rwxr-xr-xhicn-light/src/config/controlSetDebug.c74
-rwxr-xr-xhicn-light/src/config/controlSetDebug.h30
-rwxr-xr-xhicn-light/src/config/controlSetStrategy.c183
-rwxr-xr-xhicn-light/src/config/controlSetStrategy.h22
-rwxr-xr-xhicn-light/src/config/controlSetWldr.c122
-rwxr-xr-xhicn-light/src/config/controlSetWldr.h22
-rwxr-xr-xhicn-light/src/config/controlState.c237
-rwxr-xr-xhicn-light/src/config/controlState.h233
-rwxr-xr-xhicn-light/src/config/controlUnset.c78
-rwxr-xr-xhicn-light/src/config/controlUnset.h29
-rwxr-xr-xhicn-light/src/config/controlUnsetDebug.c77
-rwxr-xr-xhicn-light/src/config/controlUnsetDebug.h30
-rwxr-xr-xhicn-light/src/config/symbolicNameTable.c175
-rwxr-xr-xhicn-light/src/config/symbolicNameTable.h131
-rwxr-xr-xhicn-light/src/content_store/CMakeLists.txt33
-rwxr-xr-xhicn-light/src/content_store/contentStoreEntry.c136
-rwxr-xr-xhicn-light/src/content_store/contentStoreEntry.h146
-rwxr-xr-xhicn-light/src/content_store/contentStoreInterface.c57
-rwxr-xr-xhicn-light/src/content_store/contentStoreInterface.h211
-rwxr-xr-xhicn-light/src/content_store/contentStoreLRU.c455
-rwxr-xr-xhicn-light/src/content_store/contentStoreLRU.h39
-rwxr-xr-xhicn-light/src/content_store/listLRU.c133
-rwxr-xr-xhicn-light/src/content_store/listLRU.h94
-rwxr-xr-xhicn-light/src/content_store/listTimeOrdered.c94
-rwxr-xr-xhicn-light/src/content_store/listTimeOrdered.h103
-rwxr-xr-xhicn-light/src/core/CMakeLists.txt55
-rwxr-xr-xhicn-light/src/core/connection.c265
-rwxr-xr-xhicn-light/src/core/connection.h148
-rwxr-xr-xhicn-light/src/core/connectionList.c68
-rwxr-xr-xhicn-light/src/core/connectionList.h70
-rwxr-xr-xhicn-light/src/core/connectionManager.c196
-rwxr-xr-xhicn-light/src/core/connectionManager.h37
-rwxr-xr-xhicn-light/src/core/connectionTable.c224
-rwxr-xr-xhicn-light/src/core/connectionTable.h99
-rwxr-xr-xhicn-light/src/core/dispatcher.c435
-rwxr-xr-xhicn-light/src/core/dispatcher.h286
-rwxr-xr-xhicn-light/src/core/forwarder.c499
-rwxr-xr-xhicn-light/src/core/forwarder.h287
-rwxr-xr-xhicn-light/src/core/logger.c173
-rwxr-xr-xhicn-light/src/core/logger.h168
-rwxr-xr-xhicn-light/src/core/mapMe.c816
-rwxr-xr-xhicn-light/src/core/mapMe.h89
-rwxr-xr-xhicn-light/src/core/message.c297
-rwxr-xr-xhicn-light/src/core/message.h180
-rwxr-xr-xhicn-light/src/core/messageHandler.h580
-rwxr-xr-xhicn-light/src/core/messagePacketType.h32
-rwxr-xr-xhicn-light/src/core/name.c236
-rwxr-xr-xhicn-light/src/core/name.h105
-rwxr-xr-xhicn-light/src/core/nameBitvector.c383
-rwxr-xr-xhicn-light/src/core/nameBitvector.h63
-rwxr-xr-xhicn-light/src/core/numberSet.c203
-rwxr-xr-xhicn-light/src/core/numberSet.h157
-rwxr-xr-xhicn-light/src/core/streamBuffer.c142
-rwxr-xr-xhicn-light/src/core/streamBuffer.h129
-rwxr-xr-xhicn-light/src/core/system.h60
-rwxr-xr-xhicn-light/src/core/ticks.h31
-rwxr-xr-xhicn-light/src/core/wldr.c182
-rwxr-xr-xhicn-light/src/core/wldr.h52
-rwxr-xr-xhicn-light/src/io/CMakeLists.txt53
-rwxr-xr-xhicn-light/src/io/addressPair.c129
-rwxr-xr-xhicn-light/src/io/addressPair.h128
-rwxr-xr-xhicn-light/src/io/hicnConnection.c517
-rwxr-xr-xhicn-light/src/io/hicnConnection.h53
-rwxr-xr-xhicn-light/src/io/hicnListener.c725
-rwxr-xr-xhicn-light/src/io/hicnListener.h42
-rwxr-xr-xhicn-light/src/io/hicnTunnel.c106
-rwxr-xr-xhicn-light/src/io/hicnTunnel.h65
-rwxr-xr-xhicn-light/src/io/ioOperations.c63
-rwxr-xr-xhicn-light/src/io/ioOperations.h394
-rwxr-xr-xhicn-light/src/io/listener.h105
-rwxr-xr-xhicn-light/src/io/listenerSet.c132
-rwxr-xr-xhicn-light/src/io/listenerSet.h137
-rwxr-xr-xhicn-light/src/io/streamConnection.c714
-rwxr-xr-xhicn-light/src/io/streamConnection.h75
-rwxr-xr-xhicn-light/src/io/tcpListener.c233
-rwxr-xr-xhicn-light/src/io/tcpListener.h37
-rwxr-xr-xhicn-light/src/io/tcpTunnel.c43
-rwxr-xr-xhicn-light/src/io/tcpTunnel.h42
-rwxr-xr-xhicn-light/src/io/udpConnection.c406
-rwxr-xr-xhicn-light/src/io/udpConnection.h53
-rwxr-xr-xhicn-light/src/io/udpListener.c533
-rwxr-xr-xhicn-light/src/io/udpListener.h32
-rwxr-xr-xhicn-light/src/io/udpTunnel.c91
-rwxr-xr-xhicn-light/src/io/udpTunnel.h42
-rwxr-xr-xhicn-light/src/messenger/CMakeLists.txt32
-rwxr-xr-xhicn-light/src/messenger/messenger.c171
-rwxr-xr-xhicn-light/src/messenger/messenger.h69
-rwxr-xr-xhicn-light/src/messenger/messengerRecipient.c62
-rwxr-xr-xhicn-light/src/messenger/messengerRecipient.h104
-rwxr-xr-xhicn-light/src/messenger/missive.c54
-rwxr-xr-xhicn-light/src/messenger/missive.h89
-rwxr-xr-xhicn-light/src/messenger/missiveDeque.c77
-rwxr-xr-xhicn-light/src/messenger/missiveDeque.h55
-rwxr-xr-xhicn-light/src/messenger/missiveType.h55
-rwxr-xr-xhicn-light/src/platforms/CMakeLists.txt31
-rwxr-xr-xhicn-light/src/platforms/README.txt17
-rwxr-xr-xhicn-light/src/platforms/android/system.c183
-rwxr-xr-xhicn-light/src/platforms/darwin/system.c146
-rwxr-xr-xhicn-light/src/platforms/linux/system.c184
-rwxr-xr-xhicn-light/src/processor/CMakeLists.txt40
-rwxr-xr-xhicn-light/src/processor/fib.c448
-rwxr-xr-xhicn-light/src/processor/fib.h43
-rwxr-xr-xhicn-light/src/processor/fibEntry.c223
-rwxr-xr-xhicn-light/src/processor/fibEntry.h143
-rwxr-xr-xhicn-light/src/processor/fibEntryList.c72
-rwxr-xr-xhicn-light/src/processor/fibEntryList.h96
-rwxr-xr-xhicn-light/src/processor/hashTableFunction.c47
-rwxr-xr-xhicn-light/src/processor/hashTableFunction.h73
-rwxr-xr-xhicn-light/src/processor/matchingRulesTable.c132
-rwxr-xr-xhicn-light/src/processor/matchingRulesTable.h113
-rwxr-xr-xhicn-light/src/processor/messageProcessor.c742
-rwxr-xr-xhicn-light/src/processor/messageProcessor.h166
-rwxr-xr-xhicn-light/src/processor/pit.c45
-rwxr-xr-xhicn-light/src/processor/pit.h114
-rwxr-xr-xhicn-light/src/processor/pitEntry.c142
-rwxr-xr-xhicn-light/src/processor/pitEntry.h164
-rwxr-xr-xhicn-light/src/processor/pitStandard.c304
-rwxr-xr-xhicn-light/src/processor/pitStandard.h41
-rwxr-xr-xhicn-light/src/processor/pitVerdict.h36
-rwxr-xr-xhicn-light/src/socket/CMakeLists.txt31
-rwxr-xr-xhicn-light/src/socket/api.c604
-rwxr-xr-xhicn-light/src/socket/api.h216
-rwxr-xr-xhicn-light/src/socket/error.c7
-rwxr-xr-xhicn-light/src/socket/error.h46
-rwxr-xr-xhicn-light/src/socket/ops.h54
-rwxr-xr-xhicn-light/src/socket/ops_linux.c1723
-rwxr-xr-xhicn-light/src/strategies/CMakeLists.txt36
-rwxr-xr-xhicn-light/src/strategies/loadBalancer.c278
-rwxr-xr-xhicn-light/src/strategies/loadBalancer.h26
-rwxr-xr-xhicn-light/src/strategies/loadBalancerWithPD.c368
-rwxr-xr-xhicn-light/src/strategies/loadBalancerWithPD.h30
-rwxr-xr-xhicn-light/src/strategies/nexthopState.c206
-rwxr-xr-xhicn-light/src/strategies/nexthopState.h94
-rwxr-xr-xhicn-light/src/strategies/nexthopStateWithPD.c254
-rwxr-xr-xhicn-light/src/strategies/nexthopStateWithPD.h106
-rwxr-xr-xhicn-light/src/strategies/rnd.c175
-rwxr-xr-xhicn-light/src/strategies/rnd.h26
-rwxr-xr-xhicn-light/src/strategies/rndSegment.c207
-rwxr-xr-xhicn-light/src/strategies/rndSegment.h27
-rwxr-xr-xhicn-light/src/strategies/strategyImpl.h66
-rwxr-xr-xhicn-light/src/utils/CMakeLists.txt36
-rwxr-xr-xhicn-light/src/utils/address.c419
-rwxr-xr-xhicn-light/src/utils/address.h498
-rwxr-xr-xhicn-light/src/utils/addressList.c133
-rwxr-xr-xhicn-light/src/utils/addressList.h196
-rwxr-xr-xhicn-light/src/utils/commands.h282
-rwxr-xr-xhicn-light/src/utils/interface.c168
-rwxr-xr-xhicn-light/src/utils/interface.h208
-rwxr-xr-xhicn-light/src/utils/interfaceSet.c149
-rwxr-xr-xhicn-light/src/utils/interfaceSet.h198
-rwxr-xr-xhicn-light/src/utils/punting.c98
-rwxr-xr-xhicn-light/src/utils/punting.h72
-rwxr-xr-xhicn-light/src/utils/utils.c258
-rwxr-xr-xhicn-light/src/utils/utils.h82
-rwxr-xr-xhicn-plugin/AUTHORS4
-rwxr-xr-xhicn-plugin/CMakeLists.txt235
-rwxr-xr-xhicn-plugin/README.md168
-rwxr-xr-xhicn-plugin/src/cache_policies/cs_lru.c213
-rwxr-xr-xhicn-plugin/src/cache_policies/cs_lru.h67
-rwxr-xr-xhicn-plugin/src/cache_policies/cs_policy.h81
-rwxr-xr-xhicn-plugin/src/cli.c1247
-rwxr-xr-xhicn-plugin/src/data_fwd.h209
-rwxr-xr-xhicn-plugin/src/data_fwd_node.c541
-rwxr-xr-xhicn-plugin/src/data_pcslookup.h55
-rwxr-xr-xhicn-plugin/src/data_pcslookup_node.c246
-rwxr-xr-xhicn-plugin/src/data_push_node.c349
-rwxr-xr-xhicn-plugin/src/error.c28
-rwxr-xr-xhicn-plugin/src/error.h100
-rwxr-xr-xhicn-plugin/src/face_db.h153
-rwxr-xr-xhicn-plugin/src/faces/app/address_mgr.c243
-rwxr-xr-xhicn-plugin/src/faces/app/address_mgr.h76
-rwxr-xr-xhicn-plugin/src/faces/app/face_app_cli.c203
-rwxr-xr-xhicn-plugin/src/faces/app/face_cons.c126
-rwxr-xr-xhicn-plugin/src/faces/app/face_cons.h75
-rwxr-xr-xhicn-plugin/src/faces/app/face_prod.c375
-rwxr-xr-xhicn-plugin/src/faces/app/face_prod.h113
-rwxr-xr-xhicn-plugin/src/faces/app/face_prod_node.c341
-rwxr-xr-xhicn-plugin/src/faces/face.c141
-rwxr-xr-xhicn-plugin/src/faces/face.h240
-rwxr-xr-xhicn-plugin/src/faces/face_cli.c131
-rwxr-xr-xhicn-plugin/src/faces/ip/dpo_ip.c187
-rwxr-xr-xhicn-plugin/src/faces/ip/dpo_ip.h255
-rwxr-xr-xhicn-plugin/src/faces/ip/face_ip.c326
-rwxr-xr-xhicn-plugin/src/faces/ip/face_ip.h241
-rwxr-xr-xhicn-plugin/src/faces/ip/face_ip_cli.c158
-rwxr-xr-xhicn-plugin/src/faces/ip/face_ip_node.c761
-rwxr-xr-xhicn-plugin/src/faces/ip/face_ip_node.h40
-rwxr-xr-xhicn-plugin/src/faces/ip/iface_ip_node.c845
-rwxr-xr-xhicn-plugin/src/faces/ip/iface_ip_node.h35
-rwxr-xr-xhicn-plugin/src/faces/udp/dpo_udp.c158
-rwxr-xr-xhicn-plugin/src/faces/udp/dpo_udp.h312
-rwxr-xr-xhicn-plugin/src/faces/udp/face_udp.c371
-rwxr-xr-xhicn-plugin/src/faces/udp/face_udp.h248
-rwxr-xr-xhicn-plugin/src/faces/udp/face_udp_cli.c164
-rwxr-xr-xhicn-plugin/src/faces/udp/face_udp_node.c864
-rwxr-xr-xhicn-plugin/src/faces/udp/face_udp_node.h35
-rwxr-xr-xhicn-plugin/src/faces/udp/iface_udp_node.c894
-rwxr-xr-xhicn-plugin/src/faces/udp/iface_udp_node.h36
-rwxr-xr-xhicn-plugin/src/hashtb.c1008
-rwxr-xr-xhicn-plugin/src/hashtb.h550
-rwxr-xr-xhicn-plugin/src/hicn.api538
-rwxr-xr-xhicn-plugin/src/hicn.c253
-rwxr-xr-xhicn-plugin/src/hicn.h86
-rwxr-xr-xhicn-plugin/src/hicn_all_api_h.h22
-rwxr-xr-xhicn-plugin/src/hicn_api.c570
-rwxr-xr-xhicn-plugin/src/hicn_api.h32
-rwxr-xr-xhicn-plugin/src/hicn_api_test.c1046
-rwxr-xr-xhicn-plugin/src/hicn_msg_enum.h36
-rwxr-xr-xhicn-plugin/src/infra.h101
-rwxr-xr-xhicn-plugin/src/interest_hitcs.h55
-rwxr-xr-xhicn-plugin/src/interest_hitcs_node.c300
-rwxr-xr-xhicn-plugin/src/interest_hitpit.h56
-rwxr-xr-xhicn-plugin/src/interest_hitpit_node.c313
-rwxr-xr-xhicn-plugin/src/interest_pcslookup.h57
-rwxr-xr-xhicn-plugin/src/interest_pcslookup_node.c240
-rwxr-xr-xhicn-plugin/src/mapme.h307
-rwxr-xr-xhicn-plugin/src/mapme_ack.h53
-rwxr-xr-xhicn-plugin/src/mapme_ack_node.c224
-rwxr-xr-xhicn-plugin/src/mapme_ctrl.h92
-rwxr-xr-xhicn-plugin/src/mapme_ctrl_node.c333
-rwxr-xr-xhicn-plugin/src/mapme_eventmgr.c559
-rwxr-xr-xhicn-plugin/src/mapme_eventmgr.h48
-rwxr-xr-xhicn-plugin/src/mgmt.c100
-rwxr-xr-xhicn-plugin/src/mgmt.h132
-rwxr-xr-xhicn-plugin/src/params.h104
-rwxr-xr-xhicn-plugin/src/parser.h102
-rwxr-xr-xhicn-plugin/src/pcs.c53
-rwxr-xr-xhicn-plugin/src/pcs.h836
-rwxr-xr-xhicn-plugin/src/pg.c1147
-rwxr-xr-xhicn-plugin/src/pg.h56
-rwxr-xr-xhicn-plugin/src/punt.c1005
-rwxr-xr-xhicn-plugin/src/punt.h338
-rwxr-xr-xhicn-plugin/src/route.c392
-rwxr-xr-xhicn-plugin/src/route.h61
-rwxr-xr-xhicn-plugin/src/state.h102
-rwxr-xr-xhicn-plugin/src/strategies/dpo_mw.c305
-rwxr-xr-xhicn-plugin/src/strategies/dpo_mw.h131
-rwxr-xr-xhicn-plugin/src/strategies/strategy_mw.c171
-rwxr-xr-xhicn-plugin/src/strategies/strategy_mw.h31
-rwxr-xr-xhicn-plugin/src/strategies/strategy_mw_cli.c148
-rwxr-xr-xhicn-plugin/src/strategy.c265
-rwxr-xr-xhicn-plugin/src/strategy.h82
-rwxr-xr-xhicn-plugin/src/strategy_dpo_ctx.h69
-rwxr-xr-xhicn-plugin/src/strategy_dpo_manager.c159
-rwxr-xr-xhicn-plugin/src/strategy_dpo_manager.h186
-rwxr-xr-xhicn-plugin/src/utils.h66
-rwxr-xr-xhicn-plugin/src/vface_db.h155
-rwxr-xr-xlib/CMakeLists.txt50
-rwxr-xr-xlib/README.md114
-rwxr-xr-xlib/doc/CMakeLists.txt23
-rwxr-xr-xlib/doc/Doxyfile.in12
-rwxr-xr-xlib/src/CMakeLists.txt81
-rwxr-xr-xlib/src/base.h136
-rwxr-xr-xlib/src/common.c165
-rwxr-xr-xlib/src/common.h231
-rwxr-xr-xlib/src/compat.c1177
-rwxr-xr-xlib/src/compat.h462
-rwxr-xr-xlib/src/error.c35
-rwxr-xr-xlib/src/error.h58
-rwxr-xr-xlib/src/header.h105
-rwxr-xr-xlib/src/hicn.h79
-rwxr-xr-xlib/src/mapme.c224
-rwxr-xr-xlib/src/mapme.h152
-rwxr-xr-xlib/src/name.c676
-rwxr-xr-xlib/src/name.h336
-rwxr-xr-xlib/src/ops.c93
-rwxr-xr-xlib/src/ops.h624
-rwxr-xr-xlib/src/protocol.h51
-rwxr-xr-xlib/src/protocol/ah.c211
-rwxr-xr-xlib/src/protocol/ah.h72
-rwxr-xr-xlib/src/protocol/icmp.c229
-rwxr-xr-xlib/src/protocol/icmp.h68
-rwxr-xr-xlib/src/protocol/icmprd.h47
-rwxr-xr-xlib/src/protocol/ipv4.c452
-rwxr-xr-xlib/src/protocol/ipv4.h91
-rwxr-xr-xlib/src/protocol/ipv6.c412
-rwxr-xr-xlib/src/protocol/ipv6.h67
-rwxr-xr-xlib/src/protocol/tcp.c370
-rwxr-xr-xlib/src/protocol/tcp.h166
-rwxr-xr-xlib/src/protocol/udp.h37
-rwxr-xr-xlibtransport/AUTHORS8
-rwxr-xr-xlibtransport/CMakeLists.txt122
-rwxr-xr-xlibtransport/README.md126
-rwxr-xr-xlibtransport/cmake/Modules/Android.cmake19
-rwxr-xr-xlibtransport/cmake/Modules/DefaultConfiguration.cmake48
-rwxr-xr-xlibtransport/cmake/Modules/Ios.cmake23
-rwxr-xr-xlibtransport/cmake/Modules/Packager.cmake197
-rwxr-xr-xlibtransport/cmake/Modules/TestMacros.cmake15
-rwxr-xr-xlibtransport/src/hicn/transport/CMakeLists.txt54
-rwxr-xr-xlibtransport/src/hicn/transport/config.h.in22
-rwxr-xr-xlibtransport/src/hicn/transport/core/CMakeLists.txt87
-rwxr-xr-xlibtransport/src/hicn/transport/core/connector.cc44
-rwxr-xr-xlibtransport/src/hicn/transport/core/connector.h89
-rwxr-xr-xlibtransport/src/hicn/transport/core/content_object.cc170
-rwxr-xr-xlibtransport/src/hicn/transport/core/content_object.h69
-rwxr-xr-xlibtransport/src/hicn/transport/core/facade.h53
-rwxr-xr-xlibtransport/src/hicn/transport/core/forwarder_interface.h136
-rwxr-xr-xlibtransport/src/hicn/transport/core/hicn_binary_api.c228
-rwxr-xr-xlibtransport/src/hicn/transport/core/hicn_binary_api.h103
-rwxr-xr-xlibtransport/src/hicn/transport/core/hicn_forwarder_interface.cc84
-rwxr-xr-xlibtransport/src/hicn/transport/core/hicn_forwarder_interface.h67
-rwxr-xr-xlibtransport/src/hicn/transport/core/hicn_memif_api.c0
-rwxr-xr-xlibtransport/src/hicn/transport/core/interest.cc149
-rwxr-xr-xlibtransport/src/hicn/transport/core/interest.h66
-rwxr-xr-xlibtransport/src/hicn/transport/core/key_locator.cc42
-rwxr-xr-xlibtransport/src/hicn/transport/core/key_locator.h48
-rwxr-xr-xlibtransport/src/hicn/transport/core/key_locator_type.h28
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest.cc33
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest.h164
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest_format.h196
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest_format_fixed.cc221
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest_format_fixed.h168
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest_format_json_jsoncpp.cc244
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest_format_json_jsoncpp.h162
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest_format_json_libparc_deprecated.cc298
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest_format_json_libparc_deprecated.h152
-rwxr-xr-xlibtransport/src/hicn/transport/core/manifest_inline.h116
-rwxr-xr-xlibtransport/src/hicn/transport/core/memif_binary_api.c218
-rwxr-xr-xlibtransport/src/hicn/transport/core/memif_binary_api.h61
-rwxr-xr-xlibtransport/src/hicn/transport/core/memif_connector.cc493
-rwxr-xr-xlibtransport/src/hicn/transport/core/memif_connector.h162
-rwxr-xr-xlibtransport/src/hicn/transport/core/name.cc236
-rwxr-xr-xlibtransport/src/hicn/transport/core/name.h133
-rwxr-xr-xlibtransport/src/hicn/transport/core/packet.cc614
-rwxr-xr-xlibtransport/src/hicn/transport/core/packet.h195
-rwxr-xr-xlibtransport/src/hicn/transport/core/payload_type.h29
-rwxr-xr-xlibtransport/src/hicn/transport/core/pending_interest.cc49
-rwxr-xr-xlibtransport/src/hicn/transport/core/pending_interest.h81
-rwxr-xr-xlibtransport/src/hicn/transport/core/portal.h343
-rwxr-xr-xlibtransport/src/hicn/transport/core/prefix.cc211
-rwxr-xr-xlibtransport/src/hicn/transport/core/prefix.h68
-rwxr-xr-xlibtransport/src/hicn/transport/core/raw_socket_connector.cc214
-rwxr-xr-xlibtransport/src/hicn/transport/core/raw_socket_connector.h85
-rwxr-xr-xlibtransport/src/hicn/transport/core/raw_socket_interface.cc57
-rwxr-xr-xlibtransport/src/hicn/transport/core/raw_socket_interface.h51
-rwxr-xr-xlibtransport/src/hicn/transport/core/socket_connector.cc237
-rwxr-xr-xlibtransport/src/hicn/transport/core/socket_connector.h89
-rwxr-xr-xlibtransport/src/hicn/transport/core/test/CMakeLists.txt10
-rwxr-xr-xlibtransport/src/hicn/transport/core/test/test_core_manifest.cc296
-rwxr-xr-xlibtransport/src/hicn/transport/core/vpp_binary_api.c221
-rwxr-xr-xlibtransport/src/hicn/transport/core/vpp_binary_api.h64
-rwxr-xr-xlibtransport/src/hicn/transport/core/vpp_binary_api_internal.h61
-rwxr-xr-xlibtransport/src/hicn/transport/core/vpp_forwarder_interface.cc184
-rwxr-xr-xlibtransport/src/hicn/transport/core/vpp_forwarder_interface.h68
-rwxr-xr-xlibtransport/src/hicn/transport/errors/CMakeLists.txt29
-rwxr-xr-xlibtransport/src/hicn/transport/errors/errors.h24
-rwxr-xr-xlibtransport/src/hicn/transport/errors/invalid_ip_address_exception.h31
-rwxr-xr-xlibtransport/src/hicn/transport/errors/malformed_ahpacket_exception.h31
-rwxr-xr-xlibtransport/src/hicn/transport/errors/malformed_name_exception.h31
-rwxr-xr-xlibtransport/src/hicn/transport/errors/malformed_packet_exception.h29
-rwxr-xr-xlibtransport/src/hicn/transport/errors/not_implemented_exception.h30
-rwxr-xr-xlibtransport/src/hicn/transport/errors/null_pointer_exception.h31
-rwxr-xr-xlibtransport/src/hicn/transport/errors/runtime_exception.h32
-rwxr-xr-xlibtransport/src/hicn/transport/errors/tokenizer_exception.h31
-rwxr-xr-xlibtransport/src/hicn/transport/http/CMakeLists.txt36
-rwxr-xr-xlibtransport/src/hicn/transport/http/callbacks.h46
-rwxr-xr-xlibtransport/src/hicn/transport/http/client_connection.cc194
-rwxr-xr-xlibtransport/src/hicn/transport/http/client_connection.h82
-rwxr-xr-xlibtransport/src/hicn/transport/http/default_values.h32
-rwxr-xr-xlibtransport/src/hicn/transport/http/facade.h22
-rwxr-xr-xlibtransport/src/hicn/transport/http/message.h58
-rwxr-xr-xlibtransport/src/hicn/transport/http/request.cc83
-rwxr-xr-xlibtransport/src/hicn/transport/http/request.h61
-rwxr-xr-xlibtransport/src/hicn/transport/http/response.cc134
-rwxr-xr-xlibtransport/src/hicn/transport/http/response.h58
-rwxr-xr-xlibtransport/src/hicn/transport/http/server_acceptor.cc112
-rwxr-xr-xlibtransport/src/hicn/transport/http/server_acceptor.h62
-rwxr-xr-xlibtransport/src/hicn/transport/http/server_publisher.cc173
-rwxr-xr-xlibtransport/src/hicn/transport/http/server_publisher.h72
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/CMakeLists.txt38
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/async_transport.h640
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/full_duplex_socket.cc490
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/full_duplex_socket.h254
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/publication_options.h34
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/rtc_socket_consumer.cc35
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/rtc_socket_consumer.h35
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc157
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/rtc_socket_producer.h60
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/socket.h270
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/socket_consumer.cc735
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/socket_consumer.h259
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/socket_options_default_values.h68
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/socket_options_keys.h108
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/socket_producer.cc948
-rwxr-xr-xlibtransport/src/hicn/transport/interfaces/socket_producer.h269
-rwxr-xr-xlibtransport/src/hicn/transport/portability/CMakeLists.txt26
-rwxr-xr-xlibtransport/src/hicn/transport/portability/c_portability.h36
-rwxr-xr-xlibtransport/src/hicn/transport/portability/portability.h46
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/CMakeLists.txt46
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/cbr.cc47
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/cbr.h48
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/consumer.conf21
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/download_observer.h32
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/protocol.cc45
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/protocol.h79
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/raaqm.cc416
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/raaqm.h94
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/raaqm_data_path.cc158
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/raaqm_data_path.h230
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/rate_estimation.cc353
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/rate_estimation.h175
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/rtc.cc813
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/rtc.h210
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/rtc_data_path.cc85
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/rtc_data_path.h62
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/test/CMakeLists.txt10
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/test/test_transport_producer.cc80
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/vegas.cc630
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/vegas.h161
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/vegas_rto_estimator.cc57
-rwxr-xr-xlibtransport/src/hicn/transport/protocols/vegas_rto_estimator.h48
-rwxr-xr-xlibtransport/src/hicn/transport/utils/CMakeLists.txt76
-rwxr-xr-xlibtransport/src/hicn/transport/utils/array.h62
-rwxr-xr-xlibtransport/src/hicn/transport/utils/branch_prediction.h22
-rwxr-xr-xlibtransport/src/hicn/transport/utils/content_store.cc109
-rwxr-xr-xlibtransport/src/hicn/transport/utils/content_store.h75
-rwxr-xr-xlibtransport/src/hicn/transport/utils/conversions.h37
-rwxr-xr-xlibtransport/src/hicn/transport/utils/crypto_hash.h115
-rwxr-xr-xlibtransport/src/hicn/transport/utils/crypto_hash_type.h31
-rwxr-xr-xlibtransport/src/hicn/transport/utils/crypto_hasher.h68
-rwxr-xr-xlibtransport/src/hicn/transport/utils/crypto_suite.h35
-rwxr-xr-xlibtransport/src/hicn/transport/utils/daemonizator.cc73
-rwxr-xr-xlibtransport/src/hicn/transport/utils/daemonizator.h25
-rwxr-xr-xlibtransport/src/hicn/transport/utils/deadline_timer.h114
-rwxr-xr-xlibtransport/src/hicn/transport/utils/endianess.h136
-rwxr-xr-xlibtransport/src/hicn/transport/utils/epoll_event_reactor.cc183
-rwxr-xr-xlibtransport/src/hicn/transport/utils/epoll_event_reactor.h65
-rwxr-xr-xlibtransport/src/hicn/transport/utils/event_reactor.h37
-rwxr-xr-xlibtransport/src/hicn/transport/utils/event_thread.h101
-rwxr-xr-xlibtransport/src/hicn/transport/utils/fd_deadline_timer.h127
-rwxr-xr-xlibtransport/src/hicn/transport/utils/hash.h101
-rwxr-xr-xlibtransport/src/hicn/transport/utils/identity.cc130
-rwxr-xr-xlibtransport/src/hicn/transport/utils/identity.h64
-rwxr-xr-xlibtransport/src/hicn/transport/utils/key_id.h25
-rwxr-xr-xlibtransport/src/hicn/transport/utils/linux.h64
-rwxr-xr-xlibtransport/src/hicn/transport/utils/literals.h55
-rwxr-xr-xlibtransport/src/hicn/transport/utils/log.cc1405
-rwxr-xr-xlibtransport/src/hicn/transport/utils/log.h1057
-rwxr-xr-xlibtransport/src/hicn/transport/utils/membuf.cc864
-rwxr-xr-xlibtransport/src/hicn/transport/utils/membuf.h916
-rwxr-xr-xlibtransport/src/hicn/transport/utils/min_filter.h56
-rwxr-xr-xlibtransport/src/hicn/transport/utils/object_pool.h76
-rwxr-xr-xlibtransport/src/hicn/transport/utils/ring_buffer.h129
-rwxr-xr-xlibtransport/src/hicn/transport/utils/sharable_vector.h30
-rwxr-xr-xlibtransport/src/hicn/transport/utils/signer.cc173
-rwxr-xr-xlibtransport/src/hicn/transport/utils/signer.h69
-rwxr-xr-xlibtransport/src/hicn/transport/utils/socket.h267
-rwxr-xr-xlibtransport/src/hicn/transport/utils/spinlock.h53
-rwxr-xr-xlibtransport/src/hicn/transport/utils/stream_buffer.h31
-rwxr-xr-xlibtransport/src/hicn/transport/utils/string_tokenizer.cc47
-rwxr-xr-xlibtransport/src/hicn/transport/utils/string_tokenizer.h35
-rwxr-xr-xlibtransport/src/hicn/transport/utils/test.h46
-rwxr-xr-xlibtransport/src/hicn/transport/utils/uri.cc122
-rwxr-xr-xlibtransport/src/hicn/transport/utils/uri.h47
-rwxr-xr-xlibtransport/src/hicn/transport/utils/verifier.cc193
-rwxr-xr-xlibtransport/src/hicn/transport/utils/verifier.h85
-rwxr-xr-xutils/CMakeLists.txt54
-rwxr-xr-xutils/src/hiperf.cc724
-rwxr-xr-xutils/src/ping_client.cc428
-rwxr-xr-xutils/src/ping_server.cc300
556 files changed, 94971 insertions, 0 deletions
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..2579a4a
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.fd.io
+port=29418
+project=hicn
diff --git a/AUTHORS b/AUTHORS
new file mode 100755
index 0000000..ab60dbd
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,6 @@
+Jordan Augé <jordan.auge@cisco.com>
+Alberto Compagno <acompagn@cisco.com>
+Giovanni Conte <gconte@cisco.com>
+Luca Muscariello <lumuscar@cisco.com>
+Michele Papalini <mpapal@cisco.com>
+Mauro Sardara <msardara@cisco.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755
index 0000000..c47f8e6
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,51 @@
+# 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)
+
+project(hicn-fdio)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
+
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+set(HICN_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/lib)
+
+## Target names
+set(LIBHICN hicn)
+set(LIBHICN_SHARED hicn.shared)
+set(LIBHICN_LIGHT hicn-light)
+set(HICN_LIGHT_CONTROL hicnLightControl)
+set(HICN_LIGHT_DAEMON hicnLightDaemon)
+set(LIBTRANSPORT transport)
+set(LIBTRANSPORT_SHARED transport.shared)
+
+## HEADER FILES
+set(LIBHICN_HEADER_FILES)
+set(LIBHICN_LIGHT_HEADER_FILES)
+set(LIBTRANSPORT_HEADER_FILES)
+
+set(SUBDIRS lib hicn-light libtransport utils)
+
+if (BUILD_VPP_PLUGIN AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" )
+list(APPEND SUBDIRS
+ hicn-plugin
+)
+list(APPEND HICN_BINARY_API_INCLUDE_DIRS
+ ${PROJECT_BINARY_DIR}/hicn-plugin
+ ${PROJECT_BINARY_DIR}/hicn-plugin/vpp_plugins)
+endif()
+
+foreach(dir ${SUBDIRS})
+ add_subdirectory(${dir})
+endforeach() \ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100755
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..c43dbb4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+Hybrid Information-Centric Networking (hICN)
+========================
+
+## Introduction
+hicn is an open source implementation of Cisco's hICN. It includes a network
+stack, that implements ICN forwarding path in IPv6, and a transport stack
+that implements two main transport protocols and a socket API.
+The transport protocols provide one reliable transport service implementaton
+and a real-time transport service for audio/video media.
+
+## Directory layout
+
+| Directory name | Description |
+| ---------------------- | ---------------------------------------------- |
+| lib | Core support library |
+| hicn-plugin | VPP plugin |
+| hicn-light | Lightweight packet forwarder |
+| libtransport | Support library with transport layer and API |
+| utils | Tools for testing |
+| apps | Application examples using hicn stack |
+
+
+## Supported platforms
+
+- Ubuntu 16.04 LTS (x86_64)
+- Ubuntu 18.04 LTS (x86_64)
+- Debian Stable/Testing
+- Red Hat Enterprise Linux 7
+- CentOS 7
+- Android 8
+- iOS 12
+- macOS 10.12
+- Windows 10
diff --git a/apps/README.md b/apps/README.md
new file mode 100755
index 0000000..3d763f0
--- /dev/null
+++ b/apps/README.md
@@ -0,0 +1,2 @@
+Application examples using hicn stack
+==================
diff --git a/cmake/Modules/BuildMacros.cmake b/cmake/Modules/BuildMacros.cmake
new file mode 100755
index 0000000..14a82fa
--- /dev/null
+++ b/cmake/Modules/BuildMacros.cmake
@@ -0,0 +1,146 @@
+# 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.
+
+##############################
+# Utils for building libraries and executables
+#
+
+macro(build_executable exec)
+ cmake_parse_arguments(ARG
+ "NO_INSTALL"
+ "COMPONENT"
+ "SOURCES;LINK_LIBRARIES;DEPENDS;DEFINITIONS"
+ ${ARGN}
+ )
+
+ add_executable(${exec} ${ARG_SOURCES})
+ if(ARG_LINK_LIBRARIES)
+ target_link_libraries(${exec} ${ARG_LINK_LIBRARIES})
+ endif()
+
+ if(ARG_DEPENDS)
+ add_dependencies(${exec} ${ARG_DEPENDS})
+ endif()
+
+ if(ARG_DEFINITIONS)
+ target_compile_definitions(${exec} PRIVATE ${ARG_DEFINITIONS})
+ endif()
+
+ if(NOT ARG_NO_INSTALL)
+ install(TARGETS ${exec} DESTINATION bin COMPONENT ${ARG_COMPONENT})
+ endif()
+endmacro()
+
+macro(build_library lib)
+ cmake_parse_arguments(ARG
+ "SHARED;STATIC"
+ "COMPONENT"
+ "SOURCES;LINK_LIBRARIES;INSTALL_HEADERS;DEPENDS;INCLUDE_DIRS;DEFINITIONS;INSTALL_ROOT_DIR"
+ ${ARGN}
+ )
+
+ if (ARG_SHARED)
+ list(APPEND TARGET_LIBS
+ ${lib}.shared
+ )
+ add_library(${lib}.shared SHARED ${ARG_SOURCES})
+ endif()
+
+ if(ARG_STATIC)
+ list(APPEND TARGET_LIBS
+ ${lib}
+ )
+ add_library(${lib} STATIC ${ARG_SOURCES})
+ endif()
+
+ foreach(library ${TARGET_LIBS})
+ target_compile_options(${library} PRIVATE -Wall)
+
+ if(HICN_VERSION)
+ set_target_properties(${library}
+ PROPERTIES
+ SOVERSION ${HICN_VERSION}
+ )
+ endif()
+
+ set_target_properties(${library}
+ PROPERTIES
+ OUTPUT_NAME ${lib}
+ )
+
+ # library deps
+ if(ARG_LINK_LIBRARIES)
+ target_link_libraries(${library} ${ARG_LINK_LIBRARIES})
+ endif()
+
+ if(ARG_DEFINITIONS)
+ target_compile_definitions(${library} PRIVATE ${ARG_DEFINITIONS})
+ endif()
+
+ if(ARG_INCLUDE_DIRS)
+ target_include_directories(${library} BEFORE PUBLIC
+ ${ARG_INCLUDE_DIRS}
+ ${PROJECT_BINARY_DIR}
+ )
+ endif()
+
+ # install .so
+ if(NOT ARG_COMPONENT)
+ set(ARG_COMPONENT hicn)
+ endif()
+ install(
+ TARGETS ${library}
+ DESTINATION lib
+ COMPONENT ${ARG_COMPONENT}
+ )
+
+ if(ARG_DEPENDS)
+ add_dependencies(${library} ${ARG_DEPENDS})
+ endif()
+ endforeach()
+
+ # install headers
+ if(ARG_INSTALL_HEADERS)
+
+ if (NOT ARG_INSTALL_ROOT_DIR)
+ set(ARG_INSTALL_ROOT_DIR "hicn")
+ endif()
+
+ foreach(file ${ARG_INSTALL_HEADERS})
+ get_filename_component(_dir ${file} DIRECTORY)
+ get_filename_component(dir ${_dir} NAME)
+ if (${dir} STREQUAL src)
+ set(dir "")
+ endif()
+ install(
+ FILES ${file}
+ DESTINATION include/${ARG_INSTALL_ROOT_DIR}/${dir}
+ COMPONENT ${ARG_COMPONENT}-dev
+ )
+ endforeach()
+ endif()
+endmacro()
+
+add_custom_target(${PROJECT_NAME}_cleanup_profiling_data
+ "find" "." "-name" "*.gcda" "-delete"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Cleanup previous profiling data."
+)
+
+macro(AddTest testFile)
+ add_executable(${ARGV0} ${ARGV0}.cc)
+ target_link_libraries(${ARGV0} ${TARGET_TRANSPORT_STATIC} ${GTEST_LIBRARIES})
+ add_test(${ARGV0} ${ARGV0})
+ set_target_properties(${ARGV0} PROPERTIES FOLDER Test)
+ add_dependencies(${ARGV0} ${PROJECT_NAME}_cleanup_profiling_data)
+endmacro(AddTest) \ No newline at end of file
diff --git a/cmake/Modules/FindAsio.cmake b/cmake/Modules/FindAsio.cmake
new file mode 100755
index 0000000..73888e5
--- /dev/null
+++ b/cmake/Modules/FindAsio.cmake
@@ -0,0 +1,41 @@
+# 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.
+
+########################################
+#
+# Find the hcin libraries and includes
+# This module sets:
+# ASIO_FOUND: True if asio was found
+# ASIO_INCLUDE_DIR: The asio include dir
+#
+
+set(ASIO_SEARCH_PATH_LIST
+ ${ASIO_HOME}
+ $ENV{ASIO_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(ASIO_INCLUDE_DIR asio.hpp
+ HINTS ${ASIO_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the asio includes"
+)
+
+set(ASIO_INCLUDE_DIRS ${ASIO_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Asio
+ REQUIRED_VARS ASIO_INCLUDE_DIRS
+) \ No newline at end of file
diff --git a/cmake/Modules/FindGFlags.cmake b/cmake/Modules/FindGFlags.cmake
new file mode 100755
index 0000000..804bfeb
--- /dev/null
+++ b/cmake/Modules/FindGFlags.cmake
@@ -0,0 +1,36 @@
+# 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.
+
+#
+# Find libgflags
+#
+# LIBGFLAGS_INCLUDE_DIR - where to find gflags/gflags.h, etc.
+# LIBGFLAGS_LIBRARY - List of libraries when using libgflags.
+# LIBGFLAGS_FOUND - True if libgflags found.
+
+
+IF (LIBGFLAGS_INCLUDE_DIR)
+ # Already in cache, be silent
+ SET(LIBGFLAGS_FIND_QUIETLY TRUE)
+ENDIF ()
+
+FIND_PATH(LIBGFLAGS_INCLUDE_DIR gflags/gflags.h)
+
+FIND_LIBRARY(LIBGFLAGS_LIBRARY NAMES gflags gflags_static)
+
+# handle the QUIETLY and REQUIRED arguments and set LIBGFLAGS_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGFLAGS DEFAULT_MSG LIBGFLAGS_LIBRARY LIBGFLAGS_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LIBGFLAGS_LIBRARY LIBGFLAGS_INCLUDE_DIR) \ No newline at end of file
diff --git a/cmake/Modules/FindGlog.cmake b/cmake/Modules/FindGlog.cmake
new file mode 100755
index 0000000..10023a1
--- /dev/null
+++ b/cmake/Modules/FindGlog.cmake
@@ -0,0 +1,36 @@
+# 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.
+
+#
+# Find libglog
+#
+# LIBGLOG_INCLUDE_DIR - where to find glog/logging.h, etc.
+# LIBGLOG_LIBRARY - List of libraries when using libglog.
+# LIBGLOG_FOUND - True if libglog found.
+
+
+IF (LIBGLOG_INCLUDE_DIR)
+ # Already in cache, be silent
+ SET(LIBGLOG_FIND_QUIETLY TRUE)
+ENDIF ()
+
+FIND_PATH(LIBGLOG_INCLUDE_DIR glog/logging.h)
+
+FIND_LIBRARY(LIBGLOG_LIBRARY glog)
+
+# handle the QUIETLY and REQUIRED arguments and set LIBGLOG_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGLOG DEFAULT_MSG LIBGLOG_LIBRARY LIBGLOG_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LIBGLOG_LIBRARY LIBGLOG_INCLUDE_DIR) \ No newline at end of file
diff --git a/cmake/Modules/FindHicnBinaryApi.cmake b/cmake/Modules/FindHicnBinaryApi.cmake
new file mode 100755
index 0000000..86a96ea
--- /dev/null
+++ b/cmake/Modules/FindHicnBinaryApi.cmake
@@ -0,0 +1,31 @@
+# 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.
+
+set(HICN_BINARY_API_SEARCH_PATH_LIST
+ ${HICN_BINARY_API_HOME}
+ $ENV{HICN_BINARY_API_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(HICN_BINARY_API_INCLUDE_DIR vpp_plugins/hicn/hicn_api.h
+ HINTS ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the VPP includes"
+)
+
+set(HICN_BINARY_API_INCLUDE_DIRS ${VPP_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(HicnBinaryApi DEFAULT_MSG VPP_LIBRARIES VPP_INCLUDE_DIRS) \ No newline at end of file
diff --git a/cmake/Modules/FindLibEvent.cmake b/cmake/Modules/FindLibEvent.cmake
new file mode 100755
index 0000000..5e41137
--- /dev/null
+++ b/cmake/Modules/FindLibEvent.cmake
@@ -0,0 +1,55 @@
+# 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.
+
+########################################
+#
+# Find the LibEvent libraries and includes
+# This module sets:
+# LIBEVENT_FOUND: True if LibEvent was found
+# LIBEVENT_LIBRARY: The LibEvent library
+# LIBEVENT_LIBRARIES: The LibEvent library and dependencies
+# LIBEVENT_INCLUDE_DIR: The LibEvent include dir
+#
+# This module will look for the libraries in various locations
+# See the LIBEVENT_SEARCH_PATH_LIST for a full list.
+#
+# The caller can hint at locations using the following variables:
+#
+# LIBEVENT_HOME (passed as -D to cmake)
+# LIBEVENT_HOME (in environment)
+#
+
+set(LIBEVENT_SEARCH_PATH_LIST
+ ${LIBEVENT_HOME}
+ $ENV{DEPENDENCIES}
+ $ENV{LIBEVENT_HOME}
+ /usr/local
+ /opt
+ /usr
+ )
+
+find_path(LIBEVENT_INCLUDE_DIR event2/event.h
+ HINTS ${LIBEVENT_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the LibEvent includes" )
+
+find_library(LIBEVENT_LIBRARY NAMES event
+ HINTS ${LIBEVENT_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the LibEvent libraries" )
+
+set(LIBEVENT_LIBRARIES ${LIBEVENT_LIBRARY})
+set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibEvent DEFAULT_MSG LIBEVENT_LIBRARY LIBEVENT_INCLUDE_DIR)
diff --git a/cmake/Modules/FindLibhicn.cmake b/cmake/Modules/FindLibhicn.cmake
new file mode 100755
index 0000000..7cfaaa5
--- /dev/null
+++ b/cmake/Modules/FindLibhicn.cmake
@@ -0,0 +1,49 @@
+# 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.
+
+########################################
+#
+# Find the hcin libraries and includes
+# This module sets:
+# HICN_FOUND: True if hicn was found
+# HICN_LIBRARY: The hicn library
+# HICN_LIBRARIES: The hicn library and dependencies
+# HCIN_INCLUDE_DIR: The hicn include dir
+#
+
+set(HICN_SEARCH_PATH_LIST
+ ${HICN_HOME}
+ $ENV{HICN_HOME}
+ $ENV{FOUNDATION_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(HICN_INCLUDE_DIR hicn/hicn.h
+ HINTS ${HICN_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the hicn includes"
+)
+
+find_library(HICN_LIBRARY NAMES hicn
+ HINTS ${HICN_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the hicn libraries"
+)
+
+set(HICN_LIBRARIES ${HICN_LIBRARY})
+set(HICN_INCLUDE_DIRS ${HICN_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(hicn DEFAULT_MSG HICN_LIBRARY HICN_INCLUDE_DIR)
diff --git a/cmake/Modules/FindLibmemif.cmake b/cmake/Modules/FindLibmemif.cmake
new file mode 100755
index 0000000..48460ee
--- /dev/null
+++ b/cmake/Modules/FindLibmemif.cmake
@@ -0,0 +1,47 @@
+# 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.
+
+########################################
+#
+# Find the hcin libraries and includes
+# This module sets:
+# LIBMEMIF_FOUND: True if core was found
+# LIBMEMIF_LIBRARY: The core library
+# LIBMEMIF_INCLUDE_DIR: The core include dir
+#
+
+set(LIBMEMIF_SEARCH_PATH_LIST
+ ${LIBMEMIF_HOME}
+ $ENV{LIBMEMIF_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(LIBMEMIF_INCLUDE_DIR memif/libmemif.h
+ HINTS ${LIBMEMIF_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the libmemif includes"
+)
+
+find_library(LIBMEMIF_LIBRARY NAMES memif
+ HINTS ${LIBMEMIF_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the libmemif libraries"
+)
+
+set(LIBMEMIF_LIBRARIES ${LIBMEMIF_LIBRARY})
+set(LIBMEMIF_INCLUDE_DIRS ${LIBMEMIF_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Libmemif DEFAULT_MSG LIBMEMIF_LIBRARY LIBMEMIF_INCLUDE_DIR)
diff --git a/cmake/Modules/FindLibparc.cmake b/cmake/Modules/FindLibparc.cmake
new file mode 100755
index 0000000..c5c99af
--- /dev/null
+++ b/cmake/Modules/FindLibparc.cmake
@@ -0,0 +1,50 @@
+# 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.
+
+########################################
+#
+# Find the Libparc libraries and includes
+# This module sets:
+# LIBPARC_FOUND: True if Libparc was found
+# LIBPARC_LIBRARY: The Libparc library
+# LIBPARC_LIBRARIES: The Libparc library and dependencies
+# LIBPARC_INCLUDE_DIR: The Libparc include dir
+#
+
+set(LIBPARC_SEARCH_PATH_LIST
+ ${LIBPARC_HOME}
+ $ENV{LIBPARC_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(LIBPARC_INCLUDE_DIR parc/libparc_About.h
+ HINTS ${LIBPARC_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the Libparc includes"
+)
+
+find_library(LIBPARC_LIBRARY NAMES parc
+ HINTS ${LIBPARC_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the Libparc libraries"
+)
+
+set(LIBPARC_LIBRARIES ${LIBPARC_LIBRARY})
+set(LIBPARC_INCLUDE_DIRS ${LIBPARC_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Libparc DEFAULT_MSG LIBPARC_LIBRARY LIBPARC_INCLUDE_DIR)
+
+mark_as_advanced(LIBPARC_LIBRARY LIBPARC_INCLUDE_DIR)
diff --git a/cmake/Modules/FindLibtransport.cmake b/cmake/Modules/FindLibtransport.cmake
new file mode 100755
index 0000000..5910a64
--- /dev/null
+++ b/cmake/Modules/FindLibtransport.cmake
@@ -0,0 +1,48 @@
+# 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.
+
+########################################
+#
+# Find the LibTRANSPORT libraries and includes
+# This module sets:
+# LIBTRANSPORT_FOUND: True if Libconsumer-producer was found
+# LIBTRANSPORTR_LIBRARY: The Libconsumer-producer library
+# LIBTRANSPORT_LIBRARIES: The Libconsumer-producer library and dependencies
+# LIBTRANSPORT_INCLUDE_DIR: The Libconsumer-producer include dir
+#
+
+set(LIBTRANSPORT_SEARCH_PATH_LIST
+ ${LIBTRANSPORT_HOME}
+ $ENV{LIBTRANSPORTHOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(LIBTRANSPORT_INCLUDE_DIR hicn/transport/config.h
+ HINTS ${LIBTRANSPORT_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the libtransport includes"
+)
+
+find_library(LIBTRANSPORT_LIBRARY NAMES transport
+ HINTS ${LIBTRANSPORT_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the libtransport libraries"
+)
+
+set(LIBTRANSPORT_LIBRARIES ${LIBTRANSPORT_LIBRARY})
+set(LIBTRANSPORT_INCLUDE_DIRS ${LIBTRANSPORT_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Libtransport DEFAULT_MSG LIBTRANSPORT_LIBRARIES LIBTRANSPORT_INCLUDE_DIRS) \ No newline at end of file
diff --git a/cmake/Modules/FindLongBow.cmake b/cmake/Modules/FindLongBow.cmake
new file mode 100755
index 0000000..4a05d7f
--- /dev/null
+++ b/cmake/Modules/FindLongBow.cmake
@@ -0,0 +1,55 @@
+# 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.
+
+########################################
+#
+# Find the LongBow libraries and includes
+# This module sets:
+# LONGBOW_FOUND: True if LongBow was found
+# LONGBOW_LIBRARY: The LongBow library
+# LONGBOW_LIBRARIES: The LongBow library and dependencies
+# LONGBOW_INCLUDE_DIR: The LongBow include dir
+#
+
+set(LONGBOW_SEARCH_PATH_LIST
+ ${LONGBOW_HOME}
+ $ENV{LONGBOW_HOME}
+ $ENV{PARC_HOME}
+ $ENV{FOUNDATION_HOME}
+ /usr/local/parc
+ /usr/local/ccn
+ /usr/local
+ /opt
+ /usr
+ )
+
+find_path(LONGBOW_INCLUDE_DIR LongBow/longBow_About.h
+ HINTS ${LONGBOW_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the LongBow includes" )
+
+find_library(LONGBOW_LIBRARY NAMES longbow
+ HINTS ${LONGBOW_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the LongBow libraries" )
+
+find_library(LONGBOW_REPORT_LIBRARY NAMES longbow-textplain longbow-ansiterm
+ HINTS ${LONGBOW_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the LongBow report libraries" )
+
+set(LONGBOW_LIBRARIES ${LONGBOW_LIBRARY} ${LONGBOW_REPORT_LIBRARY})
+set(LONGBOW_INCLUDE_DIRS ${LONGBOW_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LongBow DEFAULT_MSG LONGBOW_LIBRARY LONGBOW_INCLUDE_DIR)
diff --git a/cmake/Modules/FindUncrustify.cmake b/cmake/Modules/FindUncrustify.cmake
new file mode 100755
index 0000000..f8f6b00
--- /dev/null
+++ b/cmake/Modules/FindUncrustify.cmake
@@ -0,0 +1,21 @@
+# 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.
+
+# Find uncrustify program
+#
+find_program( UNCRUSTIFY_BIN uncrustify
+ PATHS
+ $ENV{UNCRUSTIFY_HOME}
+ )
+
+message( "-- UNCRUSTIFY found in ${UNCRUSTIFY_BIN}" )
diff --git a/cmake/Modules/FindVpp.cmake b/cmake/Modules/FindVpp.cmake
new file mode 100755
index 0000000..ae11c80
--- /dev/null
+++ b/cmake/Modules/FindVpp.cmake
@@ -0,0 +1,67 @@
+# 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.
+
+set(VPP_SEARCH_PATH_LIST
+ ${VPP_HOME}
+ $ENV{VPP_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(VPP_INCLUDE_DIR vnet/vnet.h
+ HINTS ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the VPP includes"
+)
+
+find_library(VPP_LIBRARY_MEMORYCLIENT
+ NAMES vlibmemoryclient
+ HINTS ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ DOC "Find the Vpp Memoryclient library"
+)
+
+find_library(VPP_LIBRARY_SVM
+ NAMES svm
+ HINTS ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ DOC "Find the Vpp svm library"
+)
+
+find_library(VPP_LIBRARY_INFRA
+ NAMES vppinfra
+ HINTS ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ DOC "Find the Vpp infra library"
+)
+
+find_library(VPP_LIBRARY_VATPLUGIN
+ NAMES vatplugin
+ HINTS ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ DOC "Find the Vpp vatplugin library"
+)
+
+find_library(VPP_LIBRARY_VLIB
+ NAMES vlib
+ HINTS ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ DOC "Find the Vpp vlib library"
+)
+
+set(VPP_LIBRARIES ${VPP_LIBRARY_MEMORYCLIENT} ${VPP_LIBRARY_SVM} ${VPP_LIBRARY_INFRA} ${VPP_LIBRARY_VATPLUGIN} ${VPP_LIBRARY_VLIB})
+set(VPP_INCLUDE_DIRS ${VPP_INCLUDE_DIR} ${VPP_INCLUDE_DIR}/vpp_plugins)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Vpp DEFAULT_MSG VPP_LIBRARIES VPP_INCLUDE_DIRS) \ No newline at end of file
diff --git a/cmake/Modules/IosMacros.cmake b/cmake/Modules/IosMacros.cmake
new file mode 100755
index 0000000..b1e5cc4
--- /dev/null
+++ b/cmake/Modules/IosMacros.cmake
@@ -0,0 +1,24 @@
+# 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.
+
+if(COMPILE_FOR_IOS)
+ include_directories(iOS)
+endif()
+
+macro(find_package_wrapper)
+ if(COMPILE_FOR_IOS)
+ find_host_package(${ARGN})
+ else()
+ find_package(${ARGN})
+ endif()
+endmacro() \ No newline at end of file
diff --git a/cmake/Modules/Packager.cmake b/cmake/Modules/Packager.cmake
new file mode 100755
index 0000000..58530fa
--- /dev/null
+++ b/cmake/Modules/Packager.cmake
@@ -0,0 +1,105 @@
+# 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.
+
+#############
+# RPM/DEB/TGZ Packaging utils
+#
+
+set(CONTACT "hicn-dev@lists.fd.io" CACHE STRING "Contact")
+set(PACKAGE_MAINTAINER "ICN Team" CACHE STRING "Maintainer")
+set(PACKAGE_VENDOR "fd.io" CACHE STRING "Vendor")
+
+macro(add_package name)
+ cmake_parse_arguments(ARG
+ ""
+ "NAME;DESCRIPION;DEPENDENCIES"
+ ""
+ ${ARGN}
+ )
+
+ if (0)
+ # parse /etc/os-release
+ file(READ "/etc/os-release" os_version)
+ string(REPLACE "\n" ";" os_version ${os_version})
+ foreach(_ver ${os_version})
+ string(REPLACE "=" ";" _ver ${_ver})
+ list(GET _ver 0 _name)
+ list(GET _ver 1 _value)
+ set(OS_${_name} ${_value})
+ endforeach()
+
+ # extract version from git
+ execute_process(
+ COMMAND git describe --long --match v*
+ OUTPUT_VARIABLE VER
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ if (NOT VER)
+ set(VER 1.0)
+ endif()
+
+ string(REGEX REPLACE "v(.*)-([0-9]+)-(g[0-9a-f]+)" "\\1;\\2;\\3" VER ${VER})
+ list(GET VER 0 tag)
+ string(REPLACE "-" "~" tag ${tag})
+ list(GET VER 1 commit_num)
+ list(GET VER 2 commit_name)
+
+ #define DEB and RPM version numbers
+ if(${commit_num} EQUAL 0)
+ set(deb_ver "${tag}")
+ set(rpm_ver "${tag}")
+ else()
+ set(deb_ver "${tag}~${commit_num}~${commit_name}")
+ set(rpm_ver "${tag}~${commit_num}_${commit_name}")
+ endif()
+
+ get_cmake_property(components COMPONENTS)
+
+ if(OS_ID_LIKE MATCHES "debian")
+ set(CPACK_GENERATOR "DEB")
+ set(type "DEBIAN")
+ set(CPACK_PACKAGE_VERSION "${deb_ver}")
+ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "VPP Team")
+ set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
+ foreach(lc ${components})
+ string(TOUPPER ${lc} uc)
+ set(CPACK_DEBIAN_${uc}_PACKAGE_NAME "${lc}")
+ endforeach()
+ elseif(OS_ID_LIKE MATCHES "rhel")
+ set(CPACK_GENERATOR "RPM")
+ set(type "RPM")
+ set(CPACK_PACKAGE_VERSION "${rpm_ver}")
+ set(CPACK_RPM_FILE_NAME RPM-DEFAULT)
+ foreach(lc ${components})
+ string(TOUPPER ${lc} uc)
+ if(${lc} MATCHES ".*-dev")
+ set(CPACK_RPM_${uc}_DEBUGINFO_PACKAGE ON)
+ set(lc ${lc}el)
+ endif()
+ set(CPACK_RPM_${uc}_PACKAGE_NAME "${lc}")
+ endforeach()
+ endif()
+
+ if(CPACK_GENERATOR)
+ set(CPACK_PACKAGE_NAME ${ARG_NAME})
+ set(CPACK_STRIP_FILES OFF)
+ set(CPACK_PACKAGE_VENDOR "${ARG_VENDOR}")
+ set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+ set(CPACK_${CPACK_GENERATOR}_COMPONENT_INSTALL ON)
+ set(CPACK_${type}_PACKAGE_DESCRIPTION "${ARG_DESCRIPTION}")
+ set(CPACK_${type}_PACKAGE_RELEASE 1)
+ include(CPack)
+ endif()
+ endif()
+endmacro() \ No newline at end of file
diff --git a/cmake/Modules/detectCacheSize.cmake b/cmake/Modules/detectCacheSize.cmake
new file mode 100755
index 0000000..a8209bb
--- /dev/null
+++ b/cmake/Modules/detectCacheSize.cmake
@@ -0,0 +1,21 @@
+# Detect the cache size
+#
+# XXX: TODO: This is a bug when cross compiling. We are detecting the local
+# Cache Line size and not the target cache line size. We should provide some
+# way to define this
+
+set(LEVEL1_DCACHE_LINESIZE 32)
+
+if( APPLE )
+ execute_process(COMMAND sysctl -n hw.cachelinesize
+ OUTPUT_VARIABLE LEVEL1_DCACHE_LINESIZE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+endif( APPLE )
+
+if( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
+ execute_process(COMMAND getconf LEVEL1_DCACHE_LINESIZE
+ OUTPUT_VARIABLE LEVEL1_DCACHE_LINESIZE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+endif()
+
+message(STATUS "Cache line size: ${LEVEL1_DCACHE_LINESIZE}")
diff --git a/hicn-light/CMakeLists.txt b/hicn-light/CMakeLists.txt
new file mode 100755
index 0000000..289e07e
--- /dev/null
+++ b/hicn-light/CMakeLists.txt
@@ -0,0 +1,74 @@
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+project(hicn-light)
+
+if (NOT CMAKE_BUILD_TYPE)
+ message(STATUS "No build type selected, default to Release")
+ set(CMAKE_BUILD_TYPE "Release")
+endif()
+
+set(CMAKE_MODULE_PATH
+ ${CMAKE_MODULE_PATH}
+ "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules"
+)
+
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+
+include( CTest )
+include( detectCacheSize )
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+if(ANDROID_API)
+ message("############ Detected cross compile for $ENV{CMAKE_SYSTEM_NAME}")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ANDROID_C_FLAGS}")
+ endif()
+
+set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DLIBRTA_DISABLE_VALIDATION -DPARCLibrary_DISABLE_VALIDATION")
+
+include(IosMacros)
+
+find_package_wrapper(Libparc REQUIRED)
+
+if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
+ find_package_wrapper(Libhicn REQUIRED)
+ set(LIBHICN_LIGHT hicn-light)
+ set(HICN_LIGHT_CONTROL hicnLightControl)
+ set(HICN_LIGHT_DAEMON hicnLightDaemon)
+else()
+ set(HICN_LIBRARIES ${LIBHICN_SHARED})
+ set(DEPENDENCIES
+ ${LIBHICN}
+ ${LIBHICN_SHARED}
+ )
+endif()
+
+find_package(Threads REQUIRED)
+
+set(HICN_LIGHT_LINK_LIBRARIES
+ hicn-light
+ ${HICN_LIBRARIES}
+ ${LIBPARC_LIBRARIES}
+ ${CMAKE_THREAD_LIBS_INIT}
+)
+
+# Include dirs -- Order does matter!
+list(APPEND HICN_LIGHT_INCLUDE_DIRS
+ ${HICN_INCLUDE_DIRS}
+ ${LIBPARC_INCLUDE_DIRS}
+)
+
+if (UNIX)
+ list(APPEND HICN_LIGHT_LINK_LIBRARIES
+ m
+ )
+endif()
+
+set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
+ set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -undefined dynamic_lookup")
+ message(STATUS "Set \"-undefined dynamic_lookup\" for shared libraries")
+endif()
+
+add_subdirectory(src) \ No newline at end of file
diff --git a/hicn-light/README.md b/hicn-light/README.md
new file mode 100755
index 0000000..ba7ed77
--- /dev/null
+++ b/hicn-light/README.md
@@ -0,0 +1,302 @@
+hicn-light
+=======
+
+## Introduction ##
+
+hicn-light is a socket based forwarder
+
+## Using hicn-light ##
+
+### Platforms ###
+
+hicn-light has been tested in:
+
+- Ubuntu 16.04 (x86_64)
+- Debian Testing
+- MacOSX 10.12
+
+Other platforms and architectures may work.
+
+### Dependencies ###
+
+Build dependencies:
+
+- c99 ( clang / gcc )
+- CMake 3.4
+
+Basic dependencies:
+
+- OpenSSL
+- pthreads
+- Libevent
+- Libparc
+
+## hicn-light Executables ##
+
+hicn-light is a set of binary executables that are used to run a forwarder instance.
+The forwarder can be run and configured using the commands
+
+- `hicnLightDaemon`
+- `hicnLightControl`
+
+Use the `-h` option to display the help messages
+
+### hicn-light Daemon ###
+
+The command `hicnLightDaemon` runs the hicn-light forwarder. The forwarder can be executed
+with the following options:
+
+```
+hicnLightDaemon [--port port] [--daemon] [--capacity objectStoreSize] [--log facility=level]
+ [--log-file filename] [--config file]
+
+Options:
+
+--port = tcp port for local in-bound connections
+--daemon = start as daemon process
+--capacity = maximum number of content objects to cache. To disable the cache
+ objectStoreSize must be 0.
+ Default vaule for objectStoreSize is 100000
+--log = sets a facility to a given log level. You can have multiple of these.
+ facilities: all, config, core, io, message, processor
+ levels: debug, info, notice, warning, error, critical, alert, off
+ example: hicnLightDaemon --log io=debug --log core=off
+--log-file = file to write log messages to (required in daemon mode)
+--config = configuration filename
+```
+
+The configuration file contains configuration lines as per hicnLightControl (see below for all
+the available commands). If logging level or content store capacity is set in the configuration
+file, it overrides the command_line. When a configuration file is specified, no default listeners
+are setup. Only 'add listener' lines in the configuration file matter.
+
+If no configuration file is specified, hicnLightDaemon will listen on TCP and UDP ports specified
+by the --port flag (or default port). It will listen on both IPv4 and IPv6 if available. The
+default port for hicn-light is 9695. Commands are expected on port 2001.
+
+### hicn-light Control ###
+
+`hicnLightControl` can be used to send command to the hicn-light forwarder and configure it.
+The command can be executed in the following way:
+
+```
+hicnLightControl [commands]
+
+Options:
+ -h = This help screen
+ commands = configuration line to send to hicn-light (use 'help' for list)
+```
+
+#### Available Commands in hicn-light Control ####
+
+This is the full list of available commands in `hicnLightControl`. This commands can be used
+from the command line running `hicnLightControl` as explained before, or listing them in a
+configuration file.
+
+Information about the commands are also available in the `hicnLightControl` help message.
+
+`add listener`: creates a TCP or UDP listener with the specified options on the local forwarder.
+For local connections (application to hicn-light) we expect a TCP listener. The default port for
+the local listener is 9695.
+
+```
+add listener <protocol> <symbolic> <local_adress> <local_port>
+
+ <symbolic> :User defined name for listener, must start with alpha and bealphanum
+ <protocol> :tcp | udp
+ <localAddress> :IPv4 or IPv6 address
+ <local_port> :TCP/UDP port
+
+```
+
+`add listener hicn`: creates a hicn listener with the specified options on the local forwarder.
+
+```
+add listener hicn <symbolic> <local_adress>
+
+ <symbolic> :User defined name for listener, must start with alpha and be alphanum
+ <localAddress> :IPv4 or IPv6 address
+
+```
+
+`add connection`: creates a TCP or UDP connection on the local forwarder with the specified options.
+
+```
+add connection <protocol> <symbolic> <remote_ip> <remote_port> <local_ip> <local_port>
+
+ <protocol> : tcp | udp
+ <symbolic> : symbolic name, e.g. 'conn1' (must be unique, start with alpha)
+ <remote_ip> : the IPv4 or IPv6 of the remote system
+ <remote_port> : the remote TCP/UDP port
+ <local_ip> : local IP address to bind to
+ <local_port> : local TCP/UDP port
+
+```
+`add connection hicn`: creates an hicn connection on the local forwarder with the specified options.
+
+```
+add connection hicn <symbolic> <remote_ip> <local_ip>
+
+ <symbolic> : symbolic name, e.g. 'conn1' (must be unique, start with alpha)
+ <remote_ip> : the IPv4 or IPv6 of the remote system
+ <local_ip> : local IP address to bind to
+
+```
+`list`: lists the connections, routes or listeners available on the local hicn-light forwarder
+```
+list <connections | routes | listeners>
+
+```
+`add route`: adds a route to the specified connection
+
+```
+add route <symbolic | connid> <prefix> <cost>
+
+ <symbolic> :The symbolic name for an exgress (must be unique, start with alpha)
+ <connid>: :The egress connection id (see 'help list connections')
+ <prefix>: :ipAddress/netmask
+ <cost>: :positive integer representing cost
+```
+
+`remove connection`: removes the specified connection. At the moment, this commands is available
+only for UDP connections, TCP is ignored.
+
+```
+remove connection <protocol> <symbolic | connid>
+
+ <protocol> : tcp | upd. This is the protocol used to create the connection.
+ <symbolic> :The symbolic name for an exgress (must be unique, start with alpha)
+ <connid>: :The egress connection id (see 'help list connections')
+
+```
+
+`remove route`: remove the specified prefix for a local connection
+
+```
+remove route <symbolic | connid> <prefix>
+
+ <connid> : the alphanumeric name of a local connection
+ <prefix> : the prefix (ipAddress/netmask) to remove
+```
+
+`cache serve`: enables/disables replies from local content store (if available)
+
+```
+cache serve <on|off>
+```
+`cache store`: enables/disables the storage of incoming data packets in the local content store
+(if available)
+
+```
+cache store <on|off>
+
+```
+`cache clear`: removes all the cached data form the local content store (if available)
+
+```
+cache clear
+
+```
+`set strategy`: sets the forwarding strategy for a give prefix. There are 4 different strategies
+implemented in hicn-light:
+
+- random: each interest is forwarded randomly to one of the available output connections
+- random_per_dash_segment: the output connection is selected randomly for each DASH segment.
+ This can be used only for DASH video streams.
+- loadbalancer: each interest is forwarded toward the output connection with the lowest number
+ of pending interests. The pending interest are the interest sent on a certain connection but
+ not yet satisfied. More information are available in:
+ G. Carofiglio, M. Gallo, L. Muscariello, M. Papalini, S. Wang,
+ "Optimal multipath congestion control and request forwarding in information-centric networks",
+ ICNP 2013.
+- loadbalancer_with_delay: implements the same strategy as loadbalancer but it takes into account
+ also the propagation delay behind each connections.
+
+```
+set strategy <prefix> <strategy>
+
+ <preifx> : the prefix to which apply the forwarding strategy
+ <strategy> : random | random_per_dash_segment | loadbalancer | loadbalancer_with_delay
+```
+`set wldr`: turns on/off WLDR on the specified connection. WLDR (Wireless Loss Detiection and
+ Recovery) is a protocol that can be used to recover losses generated by unreliable wireless
+ connections, such as WIFI. More information on WLDR are available in:
+ G. Carofiglio, L. Muscariello, M. Papalini, N. Rozhnova, X. Zeng,
+ "Leveraging ICN In-network Control for Loss Detection and Recovery in Wireless Mobile networks",
+ ICN 2016. Notice that WLDR is currently available only for UDP connections. In order to work
+ properly, WLDR needs to be activated on both side of the connection.
+
+```
+set wldr <on|off> <symbolic | connid>
+
+ <symbolic> :The symbolic name for an exgress (must be unique, start with alpha)
+ <connid>: :The egress connection id (see 'help list connections')
+
+```
+`add punting`: Add punting rules to the forwarders.
+
+```
+add punting <symbolic> <prefix>
+
+ <symbolic> : listener symbolic name
+ <address> : prefix to add as a punting rule. (example 1234::0/64)
+```
+`mapme enable`: enables/disables mapme
+
+```
+mapme enable <on|off>
+```
+`mapme discovery`: enables/disables mapme discovery
+
+```
+mapme discovery <on|off>
+```
+
+`mapme timescale`: set the timescale value expressed in millisencods
+
+```
+mapme timescale <milliseconds>
+```
+`mapme retx`: set the retrasmission time value expressed in millisecond
+
+```
+mapme retx <milliseconds>
+```
+`quit`: Exits the interactive shell
+
+### hicn-light Configuration File Example ###
+
+This is an example of a simple configuration file for hicn-light. It can be loaded by running
+the command `hicnLightDaemon --config configFile.cfg`, assuming the file name is configFile.cfg
+
+```
+#create a local listener on port 9199. This will be used by the applications to talk
+with the forwarder
+add listener udp local0 127.0.0.1 9199
+
+#create a connection with a remote node
+add connection udp conn0 192.168.0.20 12345 127.0.0.1 9199
+
+#add a route toward the remote node
+add route conn0 192.168.0.20/24 1
+```
+
+
+## License ##
+
+This software is distributed under the following license:
+
+```
+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.
+```
diff --git a/hicn-light/config/hicn-light.service b/hicn-light/config/hicn-light.service
new file mode 100755
index 0000000..0f976fc
--- /dev/null
+++ b/hicn-light/config/hicn-light.service
@@ -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.
+
+[Unit]
+Description=hicn-light is the cisco hicn socket based forwarder.
+#Documentation=man:hicn-light-forwarder
+
+[Service]
+Environment=PORT=9695
+Environment=LOG_FILE=/tmp/hicn_light.log
+Environment=CS_SIZE=1000
+Environment=CONFIG=/etc/hicn/hicn_light.conf
+# This will overrride the default environment
+EnvironmentFile=-/etc/default/source
+ExecStart=/usr/bin/hicnLightDaemon --port ${PORT} --log-file ${LOG_FILE} --capacity ${CS_SIZE} --config ${CONFIG}
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff --git a/hicn-light/src/CMakeLists.txt b/hicn-light/src/CMakeLists.txt
new file mode 100755
index 0000000..939f38a
--- /dev/null
+++ b/hicn-light/src/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Define a few configuration variables that we want accessible in the software
+
+include(BuildMacros)
+configure_file(config.h.in config.h @ONLY)
+
+if(NOT ANDROID_API AND NOT COMPILE_FOR_IOS)
+ add_subdirectory(command_line)
+endif ()
+
+add_subdirectory(config)
+add_subdirectory(content_store)
+add_subdirectory(core)
+add_subdirectory(io)
+add_subdirectory(messenger)
+add_subdirectory(platforms)
+add_subdirectory(processor)
+add_subdirectory(socket)
+add_subdirectory(strategies)
+add_subdirectory(utils)
+
+list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/config.h
+)
+
+set(COMPILER_DEFINITIONS "-DWITH_MAPME -DWITH_MAPME_FIXES")
+
+list(APPEND HICN_LIGHT_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+if (INSTALL_HEADER)
+ set(TO_INSTALL_HEADERS ${HEADER_FILES})
+endif()
+
+build_library(${LIBHICN_LIGHT}
+ STATIC
+ SOURCES ${SOURCE_FILES}
+ INSTALL_HEADERS ${TO_INSTALL_HEADERS}
+ LINK_LIBRARIES ${LIBRARIES}
+ DEPENDS ${DEPENDENCIES}
+ COMPONENT hicn-light
+ INCLUDE_DIRS ${HICN_LIGHT_INCLUDE_DIRS}
+ INSTALL_ROOT_DIR hicn/hicn-light
+ DEFINITIONS ${COMPILER_DEFINITIONS}
+)
diff --git a/hicn-light/src/command_line/CMakeLists.txt b/hicn-light/src/command_line/CMakeLists.txt
new file mode 100755
index 0000000..16c23dc
--- /dev/null
+++ b/hicn-light/src/command_line/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(controller)
+add_subdirectory(daemon)
diff --git a/hicn-light/src/command_line/controller/CMakeLists.txt b/hicn-light/src/command_line/controller/CMakeLists.txt
new file mode 100755
index 0000000..b53e610
--- /dev/null
+++ b/hicn-light/src/command_line/controller/CMakeLists.txt
@@ -0,0 +1,23 @@
+# 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.
+
+list(APPEND CONTROLLER_SRC
+ hicnLightControl_main.c
+)
+
+build_executable(${HICN_LIGHT_CONTROL}
+ SOURCES ${CONTROLLER_SRC}
+ LINK_LIBRARIES ${HICN_LIGHT_LINK_LIBRARIES}
+ DEPENDS hicn-light
+ COMPONENT hicn-light
+)
diff --git a/hicn-light/src/command_line/controller/hicnLightControl_main.c b/hicn-light/src/command_line/controller/hicnLightControl_main.c
new file mode 100755
index 0000000..4641bdd
--- /dev/null
+++ b/hicn-light/src/command_line/controller/hicnLightControl_main.c
@@ -0,0 +1,284 @@
+/*
+ * 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 <src/config.h>
+
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <string.h>
+
+#include <parc/security/parc_IdentityFile.h>
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_ArrayList.h>
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+#include <errno.h>
+#include <src/config/controlRoot.h>
+#include <src/config/controlState.h>
+
+#include <src/utils/commands.h>
+
+size_t commandOutputLen = 0; // preserve the number of structs composing
+ // payload in case on not interactive call.
+
+// REMINDER: when a new_command is added, the following array has to be updated
+// with the sizeof(new_command). It allows to allocate the buffer for receiving
+// the payload of the DAEMON RESPONSE after the header has beed read. Each
+// command identifier (typedef enum command_id) corresponds to a position in the
+// following array.
+static int payloadLengthController[LAST_COMMAND_VALUE] = {
+ sizeof(add_listener_command),
+ sizeof(add_connection_command),
+ sizeof(list_connections_command), // needed when get response from FWD
+ sizeof(add_route_command),
+ sizeof(list_routes_command), // needed when get response from FWD
+ sizeof(remove_connection_command),
+ sizeof(remove_route_command),
+ sizeof(cache_store_command),
+ sizeof(cache_serve_command),
+ 0, // cache clear
+ sizeof(set_strategy_command),
+ sizeof(set_wldr_command),
+ sizeof(add_punting_command),
+ sizeof(list_listeners_command), // needed when get response from FWD
+ sizeof(mapme_activator_command),
+ sizeof(mapme_activator_command),
+ sizeof(mapme_timing_command),
+ sizeof(mapme_timing_command)};
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+typedef struct controller_main_state {
+ ControlState *controlState;
+} ControlMainState;
+
+static void _displayForwarderLogo(void){
+ const char cli_banner [] =
+ "\033[0;31m ____ ___ _ \033[0m __ _ __ _ __ __\n"
+ "\033[0;31m / __// _ \\ (_)___ \033[0m / / (_)____ ___ ____/ /(_)___ _ / / / /_\n"
+ "\033[0;31m / _/ / // /_ / // _ \\ \033[0m / _ \\ / // __// _ \\___/ // // _ `// _ \\/ __/\n"
+ "\033[0;31m/_/ /____/(_)/_/ \\___/ \033[0m/_//_//_/ \\__//_//_/ /_//_/ \\_, //_//_/\\__/\n"
+ " /___/ \n";
+ printf("%s", cli_banner);
+ printf("\n");
+}
+
+static void _displayUsage(char *programName) {
+ printf("Usage: %s -h\n", programName);
+ printf(
+ "hicn-light is the 1.0 source, which runs on each end system and as a "
+ "software source\n");
+ printf(
+ "on intermediate systems. controller is the program to configure the "
+ "source, daemon.\n");
+ printf("\n");
+ printf("Options:\n");
+ printf("-h = This help screen\n");
+ printf(
+ "commands = configuration line to send to hicn-light (use 'help' "
+ "for list)\n");
+ printf("\n");
+}
+
+static int _parseArgs(int argc, char *argv[], char **keystorePath,
+ char **keystorePassword, PARCList *commandList) {
+ static struct option longFormOptions[] = {
+ {"help", no_argument, 0, 'h'},
+ {"keystore", required_argument, 0, 'k'},
+ {"password", required_argument, 0, 'p'},
+ {0, 0, 0, 0}};
+
+ int c;
+
+ while (1) {
+ // getopt_long stores the option index here.
+ int optionIndex = 0;
+
+ c = getopt_long(argc, argv, "hk:p:", longFormOptions, &optionIndex);
+
+ // Detect the end of the options.
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'k':
+ *keystorePath = optarg;
+ break;
+
+ case 'p':
+ *keystorePassword = optarg;
+ break;
+
+ case 'h':
+ default:
+ _displayUsage(argv[0]);
+ return 0;
+ }
+ }
+
+ // Any remaining parameters get put in the command list.
+ if (optind < argc) {
+ while (optind < argc) {
+ parcList_Add(commandList, argv[optind]);
+ optind++;
+ }
+ }
+
+ return 1;
+}
+
+struct iovec *_writeAndReadMessage(ControlState *state, struct iovec *msg) {
+ parcAssertNotNull(msg, "Parameter msg must be non-null");
+ int sockfd = controlState_GetSockfd(state);
+
+ // check if request has a payload
+ if (((header_control_message *)msg[0].iov_base)->length >
+ 0) { // command with payload
+ // write header + payload (compatibility issue: two write needed instead of
+ // the writev)
+ if (write(sockfd, msg[0].iov_base, msg[0].iov_len) < 0 ||
+ write(sockfd, msg[1].iov_base, msg[1].iov_len) < 0) {
+ printf("\nError while sending the Message: cannot write on socket \n");
+ exit(EXIT_FAILURE);
+ }
+ parcMemory_Deallocate(&msg[1].iov_base);
+ } else { // command without payload, e.g. 'list'
+ // write header only
+ if (write(sockfd, msg[0].iov_base, msg[0].iov_len) < 0) {
+ printf("\nError while sending the Message: cannot write on socket \n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ parcMemory_Deallocate(&msg[0].iov_base);
+
+ // ======= RECEIVE =======
+
+ header_control_message *headerResponse =
+ (header_control_message *)parcMemory_AllocateAndClear(
+ sizeof(header_control_message));
+ if (recv(sockfd, headerResponse, sizeof(header_control_message), 0) < 0) {
+ printf("\nError in Receiving the Message \n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (headerResponse->messageType < RESPONSE_LIGHT ||
+ headerResponse->messageType >= LAST_MSG_TYPE_VALUE) {
+ char *checkFinMsg = parcMemory_Reallocate(headerResponse, 32);
+ if (recv(sockfd, checkFinMsg, sizeof(checkFinMsg),
+ MSG_PEEK | MSG_DONTWAIT) == 0) {
+ // if recv returns zero, that means the connection has been closed:
+ close(sockfd);
+ printf("\nConnection terminated by the Daemon. Exiting... \n");
+ exit(EXIT_SUCCESS);
+ } else {
+ printf("\nError: Unrecognized message type received \n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ void *payloadResponse = NULL;
+
+ if ((commandOutputLen = headerResponse->length) > 0) {
+ payloadResponse = parcMemory_AllocateAndClear(
+ payloadLengthController[headerResponse->commandID] *
+ headerResponse->length);
+
+ if (recv(sockfd, payloadResponse,
+ payloadLengthController[headerResponse->commandID] *
+ headerResponse->length,
+ 0) < 0) {
+ printf("\nError in Receiving the Message \n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ struct iovec *response =
+ parcMemory_AllocateAndClear(sizeof(struct iovec) * 2);
+
+ response[0].iov_base = headerResponse;
+ response[0].iov_len = sizeof(header_control_message);
+ response[1].iov_base = payloadResponse;
+ response[1].iov_len = payloadLengthController[headerResponse->commandID] *
+ headerResponse->length;
+
+ return response;
+}
+
+int main(int argc, char *argv[]) {
+ _displayForwarderLogo();
+
+ if (argc == 2 && strcmp("-h", argv[1]) == 0) {
+ _displayUsage(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+
+ PARCList *commands =
+ parcList(parcArrayList_Create(NULL), PARCArrayListAsPARCList);
+
+ if (!_parseArgs(argc, argv, NULL, NULL, commands)) {
+ parcList_Release(&commands);
+ exit(EXIT_FAILURE);
+ }
+
+ ControlMainState mainState;
+ mainState.controlState =
+ controlState_Create(&mainState, _writeAndReadMessage, true);
+
+ controlState_RegisterCommand(mainState.controlState,
+ controlRoot_HelpCreate(mainState.controlState));
+ controlState_RegisterCommand(mainState.controlState,
+ controlRoot_Create(mainState.controlState));
+
+ if (parcList_Size(commands) > 0) {
+ controlState_SetInteractiveFlag(mainState.controlState, false);
+ controlState_DispatchCommand(mainState.controlState, commands);
+ char **commandOutputMain =
+ controlState_GetCommandOutput(mainState.controlState);
+ if (commandOutputMain != NULL && commandOutputLen > 0) {
+ for (size_t j = 0; j < commandOutputLen; j++) {
+ printf("Output %zu: %s \n", j, commandOutputMain[j]);
+ }
+ controlState_ReleaseCommandOutput(mainState.controlState,
+ commandOutputMain, commandOutputLen);
+ }
+ // release
+
+ } else {
+ controlState_Interactive(mainState.controlState);
+ }
+
+ parcList_Release(&commands);
+
+ controlState_Destroy(&mainState.controlState);
+
+ return EXIT_SUCCESS;
+}
diff --git a/hicn-light/src/command_line/daemon/CMakeLists.txt b/hicn-light/src/command_line/daemon/CMakeLists.txt
new file mode 100755
index 0000000..fd6cc93
--- /dev/null
+++ b/hicn-light/src/command_line/daemon/CMakeLists.txt
@@ -0,0 +1,23 @@
+# 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.
+
+list(APPEND DAEMON_SRC
+ hicnLightDaemon_main.c
+)
+
+build_executable(${HICN_LIGHT_DAEMON}
+ SOURCES ${DAEMON_SRC}
+ LINK_LIBRARIES ${HICN_LIGHT_LINK_LIBRARIES}
+ DEPENDS hicn-light
+ COMPONENT hicn-light
+) \ No newline at end of file
diff --git a/hicn-light/src/command_line/daemon/hicnLightDaemon_main.c b/hicn-light/src/command_line/daemon/hicnLightDaemon_main.c
new file mode 100755
index 0000000..f6d5217
--- /dev/null
+++ b/hicn-light/src/command_line/daemon/hicnLightDaemon_main.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <src/config.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <parc/algol/parc_FileOutputStream.h>
+#include <parc/logging/parc_LogLevel.h>
+#include <parc/logging/parc_LogReporterFile.h>
+#include <parc/logging/parc_LogReporterTextStdout.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+static void _displayForwarderLogo(void){
+ const char cli_banner [] =
+ "\033[0;31m ____ ___ _ \033[0m __ _ __ _ __ __\n"
+ "\033[0;31m / __// _ \\ (_)___ \033[0m / / (_)____ ___ ____/ /(_)___ _ / / / /_\n"
+ "\033[0;31m / _/ / // /_ / // _ \\ \033[0m / _ \\ / // __// _ \\___/ // // _ `// _ \\/ __/\n"
+ "\033[0;31m/_/ /____/(_)/_/ \\___/ \033[0m/_//_//_/ \\__//_//_/ /_//_/ \\_, //_//_/\\__/\n"
+ " /___/ \n";
+ printf("%s", cli_banner);
+ printf("\n");
+}
+
+static void _usage(int exitCode) {
+ printf(
+ "Usage: daemon [--port port] [--daemon] [--capacity objectStoreSize] "
+ "[--log facility=level] [--log-file filename] [--config file]\n");
+ printf("\n");
+ printf(
+ "hicn-light run as a daemon is the program to launch the forwarder, "
+ "either as a console program\n");
+ printf(
+ "or a background daemon (detatched from console). Once running, use the "
+ "program controller to\n");
+ printf("configure hicn-light.\n");
+ printf("\n");
+ printf(
+ "The configuration file contains configuration lines as per "
+ "controller\n");
+ printf(
+ "If logging level or content store capacity is set in the configuraiton "
+ "file, it overrides the command_line\n");
+ printf(
+ "When a configuration file is specified, no default listeners on 'port' "
+ "are setup. Only 'add listener' lines\n");
+ printf("in the configuration file matter.\n");
+ printf("\n");
+ printf(
+ "If no configuration file is specified, daemon will listen on TCP and "
+ "UDP ports specified by\n");
+ printf(
+ "the --port flag (or default port). It will listen on both IPv4 and "
+ "IPv6 if available.\n");
+ printf("\n");
+ printf("Options:\n");
+ printf("--port = tcp port for in-bound connections\n");
+ printf("--daemon = start as daemon process\n");
+ printf("--objectStoreSize = maximum number of content objects to cache\n");
+ printf(
+ "--log = sets a facility to a given log level. You can have "
+ "multiple of these.\n");
+ printf(
+ " facilities: all, config, core, io, message, "
+ "processor\n");
+ printf(
+ " levels: debug, info, notice, warning, error, "
+ "critical, alert, off\n");
+ printf(" example: daemon --log io=debug --log core=off\n");
+ printf(
+ "--log-file = file to write log messages to (required in daemon "
+ "mode)\n");
+ printf("--config = configuration filename\n");
+ printf("\n");
+ exit(exitCode);
+}
+
+static void _setLogLevelToLevel(int logLevelArray[LoggerFacility_END],
+ LoggerFacility facility,
+ const char *levelString) {
+ PARCLogLevel level = parcLogLevel_FromString(levelString);
+
+ if (level < PARCLogLevel_All) {
+ // we have a good facility and level
+ logLevelArray[facility] = level;
+ } else {
+ printf("Invalid log level string %s\n", levelString);
+ _usage(EXIT_FAILURE);
+ }
+}
+
+/**
+ * string: "facility=level"
+ * Set the right thing in the logger
+ */
+static void _setLogLevel(int logLevelArray[LoggerFacility_END],
+ const char *string) {
+ char *tofree = parcMemory_StringDuplicate(string, strlen(string));
+ char *p = tofree;
+
+ char *facilityString = strsep(&p, "=");
+ if (facilityString) {
+ char *levelString = p;
+
+ if (strcasecmp(facilityString, "all") == 0) {
+ for (LoggerFacility facility = 0; facility < LoggerFacility_END;
+ facility++) {
+ _setLogLevelToLevel(logLevelArray, facility, levelString);
+ }
+ } else {
+ LoggerFacility facility;
+ for (facility = 0; facility < LoggerFacility_END; facility++) {
+ if (strcasecmp(facilityString, logger_FacilityString(facility)) == 0) {
+ break;
+ }
+ }
+
+ if (facility < LoggerFacility_END) {
+ _setLogLevelToLevel(logLevelArray, facility, levelString);
+ } else {
+ printf("Invalid facility string %s\n", facilityString);
+ _usage(EXIT_FAILURE);
+ }
+ }
+ }
+
+ parcMemory_Deallocate((void **)&tofree);
+}
+
+static void _daemonize(void) {
+ if (getppid() == 1) {
+ // already a daemon
+ return;
+ }
+
+ int forkReturn = fork();
+ parcTrapUnexpectedStateIf(forkReturn < 0, "Fork error");
+
+ if (forkReturn > 0) {
+ // parent exits
+ exit(EXIT_SUCCESS);
+ }
+
+ // Child daemon detaches
+ printf("child continuing, pid = %u\n", getpid());
+
+ // get a new process group independent from old parent
+ setsid();
+
+ /* close all descriptors */
+ for (int i = getdtablesize(); i >= 0; --i) {
+ close(i);
+ }
+
+ // reset errno because it might be seg to EBADF from the close calls above
+ errno = 0;
+
+ // Redirect stdin and stdout and stderr to /dev/null
+ const char *devnull = "/dev/null";
+ int nullfile = open(devnull, O_RDWR);
+ parcAssertTrue(nullfile >= 0, "Error opening file '%s': (%d) %s", devnull,
+ errno, strerror(errno));
+
+ int ret;
+ ret = dup(nullfile);
+ parcAssertTrue(ret == 1, "Error duping fd 1 got %d file: (%d) %s", ret, errno,
+ strerror(errno));
+ ret = dup(nullfile);
+ parcAssertTrue(ret == 2, "Error duping fd 2, got %d file: (%d) %s", ret,
+ errno, strerror(errno));
+
+ // forwarder will capture signals
+}
+
+static Logger *_createLogfile(const char *logfile) {
+ int logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, S_IWUSR | S_IRUSR);
+ if (logfd < 0) {
+ fprintf(stderr, "Error opening %s for writing: (%d) %s\n", logfile, errno,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ chmod(logfile, S_IRWXU);
+
+ PARCFileOutputStream *fos = parcFileOutputStream_Create(logfd);
+ PARCOutputStream *pos = parcFileOutputStream_AsOutputStream(fos);
+ PARCLogReporter *reporter = parcLogReporterFile_Create(pos);
+
+ Logger *logger = logger_Create(reporter, parcClock_Wallclock());
+
+ parcOutputStream_Release(&pos);
+ parcLogReporter_Release(&reporter);
+
+ return logger;
+}
+
+int main(int argc, const char *argv[]) {
+ _displayForwarderLogo();
+
+ uint16_t port = PORT_NUMBER;
+ uint16_t configurationPort = 2001;
+ bool daemon = false;
+ int capacity = -1;
+ const char *configFileName = NULL;
+
+ char *logfile = NULL;
+
+ if (argc == 2 && strcasecmp(argv[1], "-h") == 0) {
+ _usage(EXIT_SUCCESS);
+ }
+
+ int logLevelArray[LoggerFacility_END];
+ for (int i = 0; i < LoggerFacility_END; i++) {
+ logLevelArray[i] = -1;
+ }
+
+ for (int i = 0; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ if (strcmp(argv[i], "--config") == 0) {
+ configFileName = argv[i + 1];
+ i++;
+ } else if (strcmp(argv[i], "--port") == 0) {
+ port = atoi(argv[i + 1]);
+ i++;
+ } else if (strcmp(argv[i], "--daemon") == 0) {
+ daemon = true;
+ } else if (strcmp(argv[i], "--capacity") == 0 ||
+ strcmp(argv[i], "-c") == 0) {
+ capacity = atoi(argv[i + 1]);
+ i++;
+ } else if (strcmp(argv[i], "--log") == 0) {
+ _setLogLevel(logLevelArray, argv[i + 1]);
+ i++;
+ } else if (strcmp(argv[i], "--log-file") == 0) {
+ if (logfile) {
+ // error cannot repeat
+ fprintf(stderr, "Cannot specify --log-file more than once\n");
+ _usage(EXIT_FAILURE);
+ }
+
+ logfile = parcMemory_StringDuplicate(argv[i + 1], strlen(argv[i + 1]));
+ i++;
+ } else {
+ _usage(EXIT_FAILURE);
+ }
+ }
+ }
+
+ // set restrictive umask, in case we create any files
+ umask(027);
+
+ if (daemon && (logfile == NULL)) {
+ fprintf(stderr, "Must specify a logfile when running in daemon mode\n");
+ _usage(EXIT_FAILURE);
+ }
+
+ if (daemon) {
+ // inside this call, parent will EXIT_SUCCESS and child will continue
+ _daemonize();
+ }
+
+ Logger *logger = NULL;
+ if (logfile) {
+ logger = _createLogfile(logfile);
+ parcMemory_Deallocate((void **)&logfile);
+ } else {
+ PARCLogReporter *stdoutReporter = parcLogReporterTextStdout_Create();
+ logger = logger_Create(stdoutReporter, parcClock_Wallclock());
+ parcLogReporter_Release(&stdoutReporter);
+ }
+
+ for (int i = 0; i < LoggerFacility_END; i++) {
+ if (logLevelArray[i] > -1) {
+ logger_SetLogLevel(logger, i, logLevelArray[i]);
+ }
+ }
+
+ // this will update the clock to the tick clock
+ Forwarder *forwarder = forwarder_Create(logger);
+
+ Configuration *configuration = forwarder_GetConfiguration(forwarder);
+
+ if (capacity > -1) {
+ configuration_SetObjectStoreSize(configuration, capacity);
+ }
+
+ if (configFileName) {
+ forwarder_SetupAllListeners(forwarder, port, NULL);
+ forwarder_SetupFromConfigFile(forwarder, configFileName);
+ } else {
+ // NULL to not setup AF_UNIX
+ forwarder_SetupAllListeners(forwarder, port, NULL);
+ }
+
+ Dispatcher *dispatcher = forwarder_GetDispatcher(forwarder);
+
+ logger_Log(logger, LoggerFacility_Core, PARCLogLevel_Alert, "daemon",
+ "hicn-light running port %d configuration-port %d", port,
+ configurationPort);
+
+ dispatcher_Run(dispatcher);
+
+ logger_Log(logger, LoggerFacility_Core, PARCLogLevel_Alert, "daemon",
+ "hicn-light exiting port %d", port);
+
+ forwarder_Destroy(&forwarder);
+
+ sleep(2);
+
+ logger_Release(&logger);
+ return 0;
+}
diff --git a/hicn-light/src/config.h.in b/hicn-light/src/config.h.in
new file mode 100755
index 0000000..16ec1ab
--- /dev/null
+++ b/hicn-light/src/config.h.in
@@ -0,0 +1,5 @@
+/* CPU Cache line size */
+#define LEVEL1_DCACHE_LINESIZE @LEVEL1_DCACHE_LINESIZE@
+
+#define _GNU_SOURCE
+
diff --git a/hicn-light/src/config/CMakeLists.txt b/hicn-light/src/config/CMakeLists.txt
new file mode 100755
index 0000000..5ce680b
--- /dev/null
+++ b/hicn-light/src/config/CMakeLists.txt
@@ -0,0 +1,97 @@
+# 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}/commandOps.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandParser.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandReturn.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/symbolicNameTable.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlState.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRoot.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddConnection.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAdd.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/configurationFile.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/configurationListeners.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddRoute.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddListener.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListConnections.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlList.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListListeners.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListRoutes.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlQuit.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemove.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveConnection.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveRoute.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSet.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlUnset.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetDebug.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlUnsetDebug.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMe.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeEnable.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeDiscovery.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeTimescale.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheServe.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheStore.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheClear.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCache.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetStrategy.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetWldr.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddPunting.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePunting.h
+)
+
+list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandOps.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandParser.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/configurationFile.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/configurationListeners.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlState.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/symbolicNameTable.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAdd.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddConnection.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddRoute.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddListener.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlList.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListConnections.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListListeners.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListRoutes.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlQuit.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemove.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveConnection.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveRoute.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRoot.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSet.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetDebug.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlUnset.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlUnsetDebug.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMe.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeEnable.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeDiscovery.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeTimescale.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeRetx.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheServe.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheStore.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheClear.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCache.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetStrategy.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetWldr.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddPunting.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePunting.c
+)
+
+set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/hicn-light/src/config/commandOps.c b/hicn-light/src/config/commandOps.c
new file mode 100755
index 0000000..027c86e
--- /dev/null
+++ b/hicn-light/src/config/commandOps.c
@@ -0,0 +1,72 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <string.h>
+
+#ifndef __ANDROID__
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#else
+extern int errno;
+#endif
+#endif
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/commandOps.h>
+#include <src/config/commandParser.h>
+
+CommandOps *commandOps_Create(void *closure, const char *command,
+ void (*init)(CommandParser *parser,
+ CommandOps *ops),
+ CommandReturn (*execute)(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args),
+ void (*destroyer)(CommandOps **opsPtr)) {
+ parcAssertNotNull(command, "Parameter command must be non-null");
+ parcAssertNotNull(execute, "Parameter execute must be non-null");
+ CommandOps *ops = parcMemory_AllocateAndClear(sizeof(CommandOps));
+ parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(CommandOps));
+
+ ops->closure = closure;
+ ops->command = parcMemory_StringDuplicate(command, strlen(command) + 1);
+ ops->init = init;
+ ops->execute = execute;
+ ops->destroyer = destroyer;
+ return ops;
+}
+
+void commandOps_Destroy(CommandOps **opsPtr) {
+ parcAssertNotNull(opsPtr, "Parameter opsPtr must be non-null");
+ parcAssertNotNull(*opsPtr,
+ "Parameter opsPtr must dereference to non-null pointer");
+
+ CommandOps *ops = *opsPtr;
+ parcMemory_Deallocate((void **)&(ops->command));
+ // DO NOT call ops->destroyer, we are one!
+ parcMemory_Deallocate((void **)&ops);
+
+ *opsPtr = NULL;
+}
diff --git a/hicn-light/src/config/commandOps.h b/hicn-light/src/config/commandOps.h
new file mode 100755
index 0000000..6428a3e
--- /dev/null
+++ b/hicn-light/src/config/commandOps.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file command_Ops.h
+ * @brief The function structure defining a CLI command
+ *
+ * The function structure that defines a CLI command. Each command will return
+ * one of these which defines how to run the command.
+ *
+ */
+
+#ifndef command_Ops_h
+#define command_Ops_h
+
+#include <parc/algol/parc_List.h>
+
+#include <src/config/commandReturn.h>
+
+// forward reference
+struct command_parser;
+
+struct command_ops;
+typedef struct command_ops CommandOps;
+
+/**
+ * @typedef CommandOps
+ * @abstract Each command implements a CommandOps
+ * @constant closure is a user-specified pointer for any state the user needs
+ * @constant command The text string of the command, must be the spelled out
+ * string, e.g. "help list routes"
+ * @constant init A function to call to initialize the command at program
+ * startup
+ * @constant execute A function to call to execute the command
+ * @constant destroyer A function to call to release the command
+ * @discussion
+ * Typically, the root of the thee has an Init function that then initilizes
+ * the rest of the tree. For example:
+ *
+ * @code
+ * const CommandOps control_Root = {
+ * .closure = NULL,
+ * .command = "", // empty string for root
+ * .init = control_Root_Init,
+ * .execute = control_Root_Execute
+ * .destroyer = NULL
+ * };
+ * @endcode
+ *
+ * The control_Root_Init function will then begin adding the subtree under root.
+ * For example:
+ *
+ * @code
+ * const CommandOps control_Add = {
+ * .closure = NULL,
+ * .command = "add",
+ * .init = control_Add_Init,
+ * .execute = control_Add_Execute,
+ * .destroyer = NULL
+ * };
+ *
+ * static void
+ * control_Root_Init(ControlState *state, CommandOps *ops)
+ * {
+ * controlState_RegisterCommand(state, &control_Add);
+ * }
+ * @endcode
+ */
+struct command_ops {
+ void *closure;
+ char *command;
+ void (*init)(struct command_parser *parser, CommandOps *ops);
+ CommandReturn (*execute)(struct command_parser *parser, CommandOps *ops,
+ PARCList *args);
+ void (*destroyer)(CommandOps **opsPtr);
+};
+
+/**
+ * A helper function to create the pubically defined CommandOps.
+ *
+ * Retruns allocated memory of the command
+ *
+ * @param [in] command The string is copied
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CommandOps *commandOps_Create(
+ void *closure, const char *command,
+ void (*init)(struct command_parser *parser, CommandOps *ops),
+ CommandReturn (*execute)(struct command_parser *parser, CommandOps *ops,
+ PARCList *args),
+ void (*destroyer)(CommandOps **opsPtr));
+
+/**
+ * De-allocates the memory of the CommandOps and the copied command string
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void commandOps_Destroy(CommandOps **opsPtr);
+#endif // command_Ops_h
diff --git a/hicn-light/src/config/commandParser.c b/hicn-light/src/config/commandParser.c
new file mode 100755
index 0000000..84d273c
--- /dev/null
+++ b/hicn-light/src/config/commandParser.c
@@ -0,0 +1,216 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <string.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Time.h>
+#include <parc/algol/parc_TreeRedBlack.h>
+
+#include <src/config/commandParser.h>
+
+#ifndef __ANDROID__
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#else
+extern int errno;
+#endif
+#endif
+
+struct command_parser {
+ // key = command, value = CommandOps
+ PARCTreeRedBlack *commandTree;
+ bool debugFlag;
+};
+
+static int _stringCompare(const void *key1, const void *key2) {
+ return strcasecmp((const char *)key1, (const char *)key2);
+}
+
+CommandParser *commandParser_Create(void) {
+ CommandParser *state = parcMemory_AllocateAndClear(sizeof(CommandParser));
+ parcAssertNotNull(state, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(CommandParser));
+
+ state->commandTree = parcTreeRedBlack_Create(_stringCompare, // key compare
+ NULL, // key free
+ NULL, // key copy
+ NULL, // value equals
+ NULL, // value free
+ NULL // value copy
+ );
+ state->debugFlag = false;
+ return state;
+}
+
+void commandParser_Destroy(CommandParser **parserPtr) {
+ CommandParser *parser = *parserPtr;
+
+ // destroy every element if it has a destroyer
+ PARCArrayList *values = parcTreeRedBlack_Values(parser->commandTree);
+ if (values) {
+ for (int i = 0; i < parcArrayList_Size(values); i++) {
+ CommandOps *ops = parcArrayList_Get(values, i);
+ parcTreeRedBlack_Remove(parser->commandTree, ops->command);
+ if (ops->destroyer) {
+ ops->destroyer(&ops);
+ }
+ }
+ parcArrayList_Destroy(&values);
+ }
+
+ parcTreeRedBlack_Destroy(&parser->commandTree);
+
+ parcMemory_Deallocate((void **)&parser);
+ *parserPtr = NULL;
+}
+
+void commandParser_SetDebug(CommandParser *state, bool debugFlag) {
+ state->debugFlag = debugFlag;
+}
+
+bool commandParser_GetDebug(CommandParser *state) { return state->debugFlag; }
+
+void commandParser_RegisterCommand(CommandParser *state, CommandOps *ops) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ parcAssertNotNull(ops, "Parameter ops must be non-null");
+ parcAssertNotNull(ops->command, "Operation command string must be non-null");
+
+ void *exists = parcTreeRedBlack_Get(state->commandTree, ops->command);
+ parcAssertNull(exists, "Command '%s' already exists in the tree %p\n",
+ ops->command, (void *)exists);
+
+ parcTreeRedBlack_Insert(state->commandTree, (void *)ops->command,
+ (void *)ops);
+
+ // if the command being registered asked for an init function to be called,
+ // call it
+ if (ops->init != NULL) {
+ ops->init(state, ops);
+ }
+}
+
+static PARCList *parseStringIntoTokens(const char *originalString) {
+ PARCList *list =
+ parcList(parcArrayList_Create(parcArrayList_StdlibFreeFunction),
+ PARCArrayListAsPARCList);
+
+ char *token;
+
+ char *tofree =
+ parcMemory_StringDuplicate(originalString, strlen(originalString) + 1);
+ char *string = tofree;
+
+ while ((token = strsep(&string, " \t\n")) != NULL) {
+ if (strlen(token) > 0) {
+ parcList_Add(list, strdup(token));
+ }
+ }
+
+ parcMemory_Deallocate((void **)&tofree);
+
+ return list;
+}
+
+/**
+ * Matches the user arguments to available commands, returning the command or
+ * NULL if not found
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+static CommandOps *commandParser_MatchCommand(CommandParser *state,
+ PARCList *args) {
+ // Find the longest matching prefix command.
+ // Pretty wildly inefficient
+
+ size_t longest_token_count = 0;
+ char *longest_command = NULL;
+
+ PARCArrayList *commands = parcTreeRedBlack_Keys(state->commandTree);
+ for (int i = 0; i < parcArrayList_Size(commands); i++) {
+ char *command = parcArrayList_Get(commands, i);
+ PARCList *command_tokens = parseStringIntoTokens(command);
+
+ // is it a prefix match?
+ if (parcList_Size(args) >= parcList_Size(command_tokens)) {
+ bool possible_match = true;
+ for (int i = 0; i < parcList_Size(command_tokens) && possible_match;
+ i++) {
+ const char *a = parcList_GetAtIndex(command_tokens, i);
+ const char *b = parcList_GetAtIndex(args, i);
+ if (strncasecmp(a, b, strlen(a) + 1) != 0) {
+ possible_match = false;
+ }
+ }
+
+ if (possible_match &&
+ parcList_Size(command_tokens) > longest_token_count) {
+ longest_token_count = parcList_Size(command_tokens);
+ longest_command = command;
+ }
+ }
+
+ parcList_Release(&command_tokens);
+ }
+
+ parcArrayList_Destroy(&commands);
+
+ if (longest_token_count == 0) {
+ return NULL;
+ } else {
+ CommandOps *ops = parcTreeRedBlack_Get(state->commandTree, longest_command);
+ parcAssertNotNull(ops, "Got null operations for command '%s'\n",
+ longest_command);
+ return ops;
+ }
+}
+
+CommandReturn commandParser_DispatchCommand(CommandParser *state,
+ PARCList *args) {
+ CommandOps *ops = commandParser_MatchCommand(state, args);
+
+ if (ops == NULL) {
+ printf("Command not found.\n");
+ return CommandReturn_Failure;
+ } else {
+ return ops->execute(state, ops, args);
+ }
+}
+
+bool commandParser_ContainsCommand(CommandParser *parser, const char *command) {
+ CommandOps *ops = parcTreeRedBlack_Get(parser->commandTree, command);
+ return (ops != NULL);
+}
diff --git a/hicn-light/src/config/commandParser.h b/hicn-light/src/config/commandParser.h
new file mode 100755
index 0000000..78e19e6
--- /dev/null
+++ b/hicn-light/src/config/commandParser.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file command_Parser.h
+ * @brief Creates a dictionary of commands and parses a command_line to match
+ * against them
+ *
+ * A user creates individual CommandParserEntry that map a command_line to a
+ * function to execute. The CommandParser then does a longest-matching prefix
+ * match of a command_line to the dictionary of commands and executes the
+ * appropriate command.
+ *
+ */
+
+#ifndef command_parser_h
+#define command_parser_h
+
+#include <src/config/commandOps.h>
+#include <src/config/commandReturn.h>
+
+struct command_parser;
+typedef struct command_parser CommandParser;
+
+/**
+ * controlState_Create
+ *
+ * Creates the global state for the Control program
+ *
+ * @return non-null A command parser
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CommandParser *commandParser_Create(void);
+
+/**
+ * Destroys the control state, closing all network connections
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void commandParser_Destroy(CommandParser **statePtr);
+
+/**
+ * Registers a CommandOps with the system.
+ *
+ * Each command has its complete command prefix in the "command" field.
+ * RegisterCommand will put these command prefixes in to a tree and then match
+ * what a user types against the longest-matching prefix in the tree. If
+ * there's a match, it will call the "execute" function.
+ *
+ * When the parser is destroyed, each command's destroyer function will be
+ * called.
+ *
+ * @param [in] state An allocated ControlState
+ * @param [in] command The command to register with the system
+ *
+ * Example:
+ * @code
+ * static ControlReturn
+ * control_Root_Execute(CommandParser *parser, CommandOps *ops, PARCList
+ * *args)
+ * {
+ * printf("Root Command\n");
+ * return CommandReturn_Success;
+ * }
+ *
+ * static ControlReturn
+ * control_FooBar_Execute(CommandParser *parser, CommandOps *ops, PARCList
+ * *args)
+ * {
+ * printf("Foo Bar Command\n");
+ * return CommandReturn_Success;
+ * }
+ *
+ * const CommandOps control_Root = {
+ * .closure = NULL,
+ * .command = "", // empty string for root
+ * .init = NULL,
+ * .execute = control_Root_Execute
+ * };
+ *
+ * const CommandOps control_FooBar = {
+ * .closure = NULL,
+ * .command = "foo bar", // empty string for root
+ * .init = NULL,
+ * .execute = control_FooBar_Execute
+ * };
+ *
+ * void startup(void)
+ * {
+ * ControlState *state = controlState_Create("happy", "day");
+ * controlState_RegisterCommand(state, control_FooBar);
+ * controlState_RegisterCommand(state, control_Root);
+ *
+ * // this executes "root"
+ * controlState_DispatchCommand(state, "foo");
+ * controlState_Destroy(&state);
+ * }
+ * @endcode
+ */
+void commandParser_RegisterCommand(CommandParser *state, CommandOps *command);
+
+/**
+ * Performs a longest-matching prefix of the args to the command tree
+ *
+ * The command tree is created with controlState_RegisterCommand.
+ *
+ * @param [in] state The allocated ControlState
+ * @param [in] args Each command_line word parsed to the ordered list
+ *
+ * @return CommandReturn_Success the command was successful
+ * @return CommandReturn_Failure the command failed or was not found
+ * @return CommandReturn_Exit the command indicates that the interactive mode
+ * should exit
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CommandReturn commandParser_DispatchCommand(CommandParser *state,
+ PARCList *args);
+
+/**
+ * Sets the Debug mode, which will print out much more information.
+ *
+ * Prints out much more diagnostic information about what hicn-light controller
+ * is doing. yes, you would make a CommandOps to set and unset this :)
+ *
+ * @param [in] debugFlag true means to print debug info, false means to turn it
+ * off
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void commandParser_SetDebug(CommandParser *state, bool debugFlag);
+
+/**
+ * Returns the debug state of ControlState
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool commandParser_GetDebug(CommandParser *state);
+
+/**
+ * Checks if the command is registered
+ *
+ * Checks if the exact command given is registered. This is not a prefix match.
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return true The command is registered
+ * @return false The command is not registered
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool commandParser_ContainsCommand(CommandParser *parser, const char *command);
+#endif // command_parser_h
diff --git a/hicn-light/src/config/commandReturn.h b/hicn-light/src/config/commandReturn.h
new file mode 100755
index 0000000..16ee93d
--- /dev/null
+++ b/hicn-light/src/config/commandReturn.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file command_Return.h
+ * @brief The return code used by CLI commands
+ *
+ * This return code is used throughout the command parser and command
+ * implementations to indicate success, failure, or if the program should exit.
+ *
+ */
+
+#ifndef command_return_h
+#define command_return_h
+
+/**
+ * @typedef ControlReturn
+ * @abstract A command returns one of (SUCCESS, FAILURE, EXIT)
+ * @constant SUCCESS means the command succeeded
+ * @constant FAILURE indicates failure
+ * @constant EXIT means the command indicated that hicn-light controller should
+ * exit.
+ * @discussion <#Discussion#>
+ */
+typedef enum command_return {
+ CommandReturn_Success, // command returned success
+ CommandReturn_Failure, // command failure
+ CommandReturn_Exit // command indicates program should exit
+} CommandReturn;
+
+#endif // command_return_h
diff --git a/hicn-light/src/config/configuration.c b/hicn-light/src/config/configuration.c
new file mode 100755
index 0000000..cccd606
--- /dev/null
+++ b/hicn-light/src/config/configuration.c
@@ -0,0 +1,1076 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <parc/algol/parc_HashMap.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_String.h>
+
+#include <src/config/configurationListeners.h>
+#include <src/config/symbolicNameTable.h>
+
+#include <src/core/connection.h>
+#include <src/core/connectionTable.h>
+#include <src/core/forwarder.h>
+#include <src/core/system.h>
+#ifdef WITH_MAPME
+#include <src/core/mapMe.h>
+#endif /* WITH_MAPME */
+
+#include <src/io/streamConnection.h>
+
+#include <src/io/hicnTunnel.h>
+#include <src/io/tcpTunnel.h>
+#include <src/io/udpTunnel.h>
+
+#include <parc/algol/parc_Unsigned.h>
+#include <src/io/listener.h> //the listener list
+#include <src/io/listenerSet.h> // needed to print
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+#include <src/utils/address.h>
+
+#define ETHERTYPE 0x0801
+
+struct configuration {
+ Forwarder *forwarder;
+ Logger *logger;
+
+ size_t maximumContentObjectStoreSize;
+
+ // map from prefix (parcString) to strategy (parcString)
+ PARCHashMap *strategy_map;
+
+ // translates between a symblic name and a connection id
+ SymbolicNameTable *symbolicNameTable;
+};
+
+// ========================================================================================
+
+Configuration *configuration_Create(Forwarder *forwarder) {
+ parcAssertNotNull(forwarder, "Parameter hicn-fwd must be non-null");
+ Configuration *config = parcMemory_AllocateAndClear(sizeof(Configuration));
+ parcAssertNotNull(config, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(Configuration));
+ config->forwarder = forwarder;
+ config->logger = logger_Acquire(forwarder_GetLogger(forwarder));
+ config->maximumContentObjectStoreSize = 100000;
+ config->strategy_map = parcHashMap_Create();
+ config->symbolicNameTable = symbolicNameTable_Create();
+
+ return config;
+}
+
+void configuration_Destroy(Configuration **configPtr) {
+ parcAssertNotNull(configPtr, "Parameter must be non-null double poitner");
+ parcAssertNotNull(*configPtr,
+ "Parameter must dereference to non-null pointer");
+
+ Configuration *config = *configPtr;
+ logger_Release(&config->logger);
+ parcHashMap_Release(&(config->strategy_map));
+ symbolicNameTable_Destroy(&config->symbolicNameTable);
+ parcMemory_Deallocate((void **)&config);
+ *configPtr = NULL;
+}
+
+struct iovec *configuration_ProcessRegisterHIcnPrefix(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId) {
+ header_control_message *header = request[0].iov_base;
+ add_route_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+
+ if (strcmp(symbolicOrConnid, "SELF_ROUTE") == 0) {
+ success = forwarder_AddOrUpdateRoute(config->forwarder, control, ingressId);
+ } else if (utils_IsNumber(symbolicOrConnid)) {
+ // case for connid as input
+ unsigned connid = (unsigned)strtold(symbolicOrConnid, NULL);
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+
+ // check if iconnID present in the fwd table
+ if (connectionTable_FindById(table, connid)) {
+ success = forwarder_AddOrUpdateRoute(config->forwarder, control, connid);
+ } else {
+ logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO,
+ PARCLogLevel_Error, __func__,
+ "ConnID not found, check list connections");
+ // failure
+ }
+
+ } else {
+ // case for symbolic as input: check if symbolic name can be resolved
+ unsigned connid =
+ symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid);
+ // connid = UINT_MAX when symbolicName is not found
+ if (connid != UINT32_MAX) {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Debug)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Debug,
+ __func__, "Add route resolve name '%s' to connid %u",
+ symbolicOrConnid, connid);
+ }
+
+ success = forwarder_AddOrUpdateRoute(config->forwarder, control, connid);
+
+ } else {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Warning,
+ __func__,
+ "Add route symbolic name '%s' could not be resolved",
+ symbolicOrConnid);
+ }
+ // failure
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(add_route_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(add_route_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessUnregisterHIcnPrefix(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ remove_route_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+
+ if (utils_IsNumber(symbolicOrConnid)) {
+ // case for connid as input
+ unsigned connid = (unsigned)strtold(symbolicOrConnid, NULL);
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+
+ // check if interface index present in the fwd table
+ if (connectionTable_FindById(table, connid)) {
+ success = forwarder_RemoveRoute(config->forwarder, control, connid);
+ } else {
+ logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO,
+ PARCLogLevel_Error, __func__,
+ "ConnID not found, check list connections");
+ // failure
+ }
+
+ } else {
+ // case for symbolic as input: chech if symbolic name can be resolved
+ unsigned connid =
+ symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid);
+ // connid = UINT_MAX when symbolicName is not found
+ if (connid != UINT32_MAX) {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Debug)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Debug,
+ __func__, "Remove route resolve name '%s' to connid %u",
+ symbolicOrConnid, connid);
+ }
+ success = forwarder_RemoveRoute(config->forwarder, control, connid);
+ } else {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Warning,
+ __func__,
+ "Remove route symbolic name '%s' could not be resolved",
+ symbolicOrConnid);
+ }
+ // failure
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(remove_route_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(remove_route_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessRegistrationList(Configuration *config,
+ struct iovec *request) {
+ FibEntryList *fibList = forwarder_GetFibEntries(config->forwarder);
+
+ size_t payloadSize = fibEntryList_Length(fibList);
+ size_t pointerLocation = 0;
+ struct sockaddr_in tmpAddr;
+ struct sockaddr_in6 tmpAddr6;
+
+ // allocate payload, cast from void* to uint8_t* = bytes granularity
+ uint8_t *payloadResponse =
+ parcMemory_AllocateAndClear(sizeof(list_routes_command) * payloadSize);
+
+ for (size_t i = 0; i < fibEntryList_Length(fibList); i++) {
+ FibEntry *entry = (FibEntry *)fibEntryList_Get(fibList, i);
+ NameBitvector *prefix = name_GetContentName(fibEntry_GetPrefix(entry));
+ const NumberSet *nexthops = fibEntry_GetNexthops(entry);
+
+ if (numberSet_Length(nexthops) > 1) {
+ // payload extended, need reallocate, further entries via nexthops
+ payloadSize = payloadSize + numberSet_Length(nexthops) - 1;
+ payloadResponse = (uint8_t *)parcMemory_Reallocate(
+ payloadResponse, sizeof(list_routes_command) * payloadSize);
+ }
+
+ for (size_t j = 0; j < numberSet_Length(nexthops); j++) {
+ list_routes_command *listRouteCommand =
+ (list_routes_command *)(payloadResponse +
+ (pointerLocation *
+ sizeof(list_routes_command)));
+
+ Address *addressEntry = nameBitvector_ToAddress(prefix);
+ if (addressGetType(addressEntry) == ADDR_INET) {
+ addressGetInet(addressEntry, &tmpAddr);
+ listRouteCommand->addressType = ADDR_INET;
+ listRouteCommand->address.ipv4 = tmpAddr.sin_addr.s_addr;
+ } else if (addressGetType(addressEntry) == ADDR_INET6) {
+ addressGetInet6(addressEntry, &tmpAddr6);
+ listRouteCommand->addressType = ADDR_INET6;
+ listRouteCommand->address.ipv6 = tmpAddr6.sin6_addr;
+ }
+ listRouteCommand->connid = numberSet_GetItem(nexthops, j);
+ listRouteCommand->len = nameBitvector_GetLength(prefix);
+ listRouteCommand->cost = 1; // cost
+
+ pointerLocation++;
+ addressDestroy(&addressEntry);
+ }
+ }
+
+ // send response
+ header_control_message *header = request[0].iov_base;
+ header->messageType = RESPONSE_LIGHT;
+ header->length = payloadSize;
+
+ struct iovec *response =
+ parcMemory_AllocateAndClear(sizeof(struct iovec) * 2);
+
+ response[0].iov_base = header;
+ response[0].iov_len = sizeof(header_control_message);
+ response[1].iov_base = payloadResponse;
+ response[1].iov_len = sizeof(list_routes_command) * payloadSize;
+
+ return response;
+}
+
+static void configuration_SendResponse(Configuration *config, struct iovec *msg,
+ unsigned egressId) {
+ ConnectionTable *connectionTable =
+ forwarder_GetConnectionTable(config->forwarder);
+ const Connection *conn = connectionTable_FindById(connectionTable, egressId);
+ parcAssertNotNull(conn,
+ "Got null connection for control message we just received");
+
+ IoOperations *ops = connection_GetIoOperations(conn);
+ streamState_SendCommandResponse(ops, msg);
+}
+
+struct iovec *configuration_ProcessCreateTunnel(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ add_connection_command *control = request[1].iov_base;
+
+ bool success = false;
+ bool exists = true;
+
+ const char *symbolicName = control->symbolic;
+
+ Address *source = NULL;
+ Address *destination = NULL;
+
+ if (!symbolicNameTable_Exists(config->symbolicNameTable, symbolicName)) {
+ if (control->ipType == ADDR_INET) {
+ source =
+ utils_AddressFromInet(&control->localIp.ipv4, &control->localPort);
+ destination =
+ utils_AddressFromInet(&control->remoteIp.ipv4, &control->remotePort);
+ } else if (control->ipType == ADDR_INET6) {
+ source =
+ utils_AddressFromInet6(&control->localIp.ipv6, &control->localPort);
+ destination =
+ utils_AddressFromInet6(&control->remoteIp.ipv6, &control->remotePort);
+ } else {
+ printf("Invalid IP type.\n"); // will generate a Nack
+ }
+
+ AddressPair *pair = addressPair_Create(source, destination);
+ const Connection *conn = connectionTable_FindByAddressPair(
+ forwarder_GetConnectionTable(config->forwarder), pair);
+
+ addressPair_Release(&pair);
+
+ if (conn == NULL) {
+ // the connection does not exists (even without a name)
+ exists = false;
+ }
+ }
+
+ if (!exists) {
+ IoOperations *ops = NULL;
+ switch (control->connectionType) {
+ case TCP_CONN:
+ // logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ // __func__,
+ // "Unsupported tunnel protocol: TCP");
+ ops = tcpTunnel_Create(config->forwarder, source, destination);
+ break;
+ case UDP_CONN:
+ ops = udpTunnel_Create(config->forwarder, source, destination);
+ break;
+ case GRE_CONN:
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ __func__, "Unsupported tunnel protocol: GRE");
+ break;
+#ifndef __APPLE__
+ case HICN_CONN:
+ ops = hicnTunnel_Create(config->forwarder, source, destination);
+ break;
+#endif /* __APPLE__ */
+ default:
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ __func__, "Unsupported tunnel protocol: %d",
+ control->connectionType);
+ break;
+ }
+
+ if (ops != NULL) {
+ Connection *conn = connection_Create(ops);
+
+ connectionTable_Add(forwarder_GetConnectionTable(config->forwarder),
+ conn);
+ symbolicNameTable_Add(config->symbolicNameTable, symbolicName,
+ connection_GetConnectionId(conn));
+
+ success = true;
+
+ } else {
+ printf("failed, could not create IoOperations");
+ }
+
+ } else {
+ printf("failed, symbolic name or connextion already exist\n");
+ }
+
+ addressDestroy(&source);
+ addressDestroy(&destination);
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(add_connection_command));
+ } else { // NACK
+ response =
+ utils_CreateNack(header, control, sizeof(add_connection_command));
+ }
+
+ return response;
+}
+
+/**
+ * Add an IP-based tunnel.
+ *
+ * The call cal fail if the symbolic name is a duplicate. It could also fail if
+ * there's an problem creating the local side of the tunnel (i.e. the local
+ * socket address is not usable).
+ *
+ * @return true Tunnel added
+ * @return false Tunnel not added (an error)
+ */
+
+struct iovec *configuration_ProcessRemoveTunnel(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ remove_connection_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+
+ if (utils_IsNumber(symbolicOrConnid)) {
+ // case for connid as input
+ unsigned connid = (unsigned)strtold(symbolicOrConnid, NULL);
+
+ // check if interface index present in the fwd table
+ //(it was missing and therefore caused a program crash)
+ if (connectionTable_FindById(table, connid)) {
+ // remove connection from the FIB
+ forwarder_RemoveConnectionIdFromRoutes(config->forwarder, connid);
+ // remove connection
+ connectionTable_RemoveById(table, connid);
+
+ success = true;
+ } else {
+ logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO,
+ PARCLogLevel_Error, __func__,
+ "ConnID not found, check list connections");
+ // failure
+ }
+
+ } else {
+ // case for symbolic as input
+ // chech if symbolic name can be resolved
+ unsigned connid =
+ symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid);
+ // connid = UINT_MAX when symbolicName is not found
+ if (connid != UINT32_MAX) {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Debug)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Debug,
+ __func__, "Remove connection resolve name '%s' to connid %u",
+ symbolicOrConnid, connid);
+ }
+
+ // remove connection from the FIB
+ forwarder_RemoveConnectionIdFromRoutes(config->forwarder, connid);
+ // remove connection
+ connectionTable_RemoveById(table, connid);
+ // remove connection from symbolicNameTable since we have symbolic input
+ symbolicNameTable_Remove(config->symbolicNameTable, symbolicOrConnid);
+ success = true; // to write
+ } else {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ __func__,
+ "Remove connection symbolic name '%s' could not be resolved",
+ symbolicOrConnid);
+ }
+ // failure
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response =
+ utils_CreateAck(header, control, sizeof(remove_connection_command));
+ } else { // NACK
+ response =
+ utils_CreateNack(header, control, sizeof(remove_connection_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessConnectionList(Configuration *config,
+ struct iovec *request) {
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+ ConnectionList *connList = connectionTable_GetEntries(table);
+ struct sockaddr_in tmpAddr;
+ struct sockaddr_in6 tmpAddr6;
+
+ // allocate payload, cast from void* to uint8_t* fot bytes granularity
+ uint8_t *payloadResponse = parcMemory_AllocateAndClear(
+ sizeof(list_connections_command) * connectionList_Length(connList));
+
+ for (size_t i = 0; i < connectionList_Length(connList); i++) {
+ // Don't release original, it is not stored
+ Connection *original = connectionList_Get(connList, i);
+
+ const AddressPair *addressPair = connection_GetAddressPair(original);
+ Address *localAddress = addressCopy(addressPair_GetLocal(addressPair));
+ Address *remoteAddress = addressCopy(addressPair_GetRemote(addressPair));
+
+ // Fill payload by shifting and casting at each 'i' step.
+ list_connections_command *listConnectionsCommand =
+ (list_connections_command *)(payloadResponse +
+ (i * sizeof(list_connections_command)));
+
+ // set structure fields
+ listConnectionsCommand->connid = connection_GetConnectionId(original);
+ listConnectionsCommand->state =
+ connection_IsUp(original) ? IFACE_UP : IFACE_DOWN;
+ listConnectionsCommand->connectionData.connectionType =
+ ioOperations_GetConnectionType(connection_GetIoOperations(original));
+
+ if (addressGetType(localAddress) == ADDR_INET &&
+ addressGetType(remoteAddress) == ADDR_INET) {
+ listConnectionsCommand->connectionData.ipType = ADDR_INET;
+
+ // get local port/address
+ addressGetInet(localAddress, &tmpAddr);
+ listConnectionsCommand->connectionData.localPort = tmpAddr.sin_port;
+ listConnectionsCommand->connectionData.localIp.ipv4 =
+ tmpAddr.sin_addr.s_addr;
+ memset(&tmpAddr, 0, sizeof(tmpAddr));
+ // get remote port/address
+ addressGetInet(remoteAddress, &tmpAddr);
+ listConnectionsCommand->connectionData.remotePort = tmpAddr.sin_port;
+ listConnectionsCommand->connectionData.remoteIp.ipv4 =
+ tmpAddr.sin_addr.s_addr;
+
+ } else if (addressGetType(localAddress) == ADDR_INET6 &&
+ addressGetType(remoteAddress) == ADDR_INET6) {
+ listConnectionsCommand->connectionData.ipType = ADDR_INET6;
+
+ // get local port/address
+ addressGetInet6(localAddress, &tmpAddr6);
+ listConnectionsCommand->connectionData.localPort = tmpAddr6.sin6_port;
+ listConnectionsCommand->connectionData.localIp.ipv6 = tmpAddr6.sin6_addr;
+ memset(&tmpAddr6, 0, sizeof(tmpAddr6));
+ // get remote port/address
+ addressGetInet6(remoteAddress, &tmpAddr6);
+ listConnectionsCommand->connectionData.remotePort = tmpAddr6.sin6_port;
+ listConnectionsCommand->connectionData.remoteIp.ipv6 = tmpAddr6.sin6_addr;
+
+ } // no need further else, control on the addressed already done at the
+ // time of insertion in the connection table
+ addressDestroy(&localAddress);
+ addressDestroy(&remoteAddress);
+ }
+
+ // send response
+ header_control_message *header = request[0].iov_base;
+ header->messageType = RESPONSE_LIGHT;
+ header->length = (uint16_t)connectionList_Length(connList);
+
+ struct iovec *response =
+ parcMemory_AllocateAndClear(sizeof(struct iovec) * 2);
+
+ response[0].iov_base = header;
+ response[0].iov_len = sizeof(header_control_message);
+ response[1].iov_base = payloadResponse;
+ response[1].iov_len =
+ sizeof(list_connections_command) * connectionList_Length(connList);
+
+ return response;
+}
+
+struct iovec *configuration_ProcessListenersList(Configuration *config,
+ struct iovec *request) {
+ ListenerSet *listenerList = forwarder_GetListenerSet(config->forwarder);
+ struct sockaddr_in tmpAddr;
+ struct sockaddr_in6 tmpAddr6;
+
+ // allocate payload, cast from void* to uint8_t* fot bytes granularity
+ uint8_t *payloadResponse = parcMemory_AllocateAndClear(
+ sizeof(list_listeners_command) * listenerSet_Length(listenerList));
+
+ for (size_t i = 0; i < listenerSet_Length(listenerList); i++) {
+ ListenerOps *listenerEntry = listenerSet_Get(listenerList, i);
+
+ // Fill payload by shifting and casting at each 'i' step.
+ list_listeners_command *listListenersCommand =
+ (list_listeners_command *)(payloadResponse +
+ (i * sizeof(list_listeners_command)));
+
+ listListenersCommand->connid =
+ (uint32_t)listenerEntry->getInterfaceIndex(listenerEntry);
+ listListenersCommand->encapType =
+ (uint8_t)listenerEntry->getEncapType(listenerEntry);
+ if (addressGetType((const Address *)listenerEntry->getListenAddress(
+ listenerEntry)) == ADDR_INET) {
+ addressGetInet(
+ (const Address *)listenerEntry->getListenAddress(listenerEntry),
+ &tmpAddr);
+ listListenersCommand->addressType = ADDR_INET;
+ listListenersCommand->address.ipv4 = tmpAddr.sin_addr.s_addr;
+ listListenersCommand->port = tmpAddr.sin_port;
+ } else if (addressGetType((const Address *)listenerEntry->getListenAddress(
+ listenerEntry)) == ADDR_INET6) {
+ addressGetInet6(
+ (const Address *)listenerEntry->getListenAddress(listenerEntry),
+ &tmpAddr6);
+ listListenersCommand->addressType = ADDR_INET6;
+ listListenersCommand->address.ipv6 = tmpAddr6.sin6_addr;
+ listListenersCommand->port = tmpAddr6.sin6_port;
+ }
+ }
+
+ // send response
+ header_control_message *header = request[0].iov_base;
+ header->messageType = RESPONSE_LIGHT;
+ header->length = (uint16_t)listenerSet_Length(listenerList);
+
+ struct iovec *response =
+ parcMemory_AllocateAndClear(sizeof(struct iovec) * 2);
+
+ response[0].iov_base = header;
+ response[0].iov_len = sizeof(header_control_message);
+ response[1].iov_base = payloadResponse;
+ response[1].iov_len =
+ sizeof(list_listeners_command) * listenerSet_Length(listenerList);
+
+ return response;
+}
+
+struct iovec *configuration_ProcessCacheStore(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ ;
+ cache_store_command *control = request[1].iov_base;
+ ;
+
+ bool success = false;
+
+ switch (control->activate) {
+ case ACTIVATE_ON:
+ forwarder_SetChacheStoreFlag(config->forwarder, true);
+ if (forwarder_GetChacheStoreFlag(config->forwarder)) {
+ success = true;
+ }
+ break;
+
+ case ACTIVATE_OFF:
+ forwarder_SetChacheStoreFlag(config->forwarder, false);
+ if (!forwarder_GetChacheStoreFlag(config->forwarder)) {
+ success = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ struct iovec *response;
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(cache_store_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(cache_store_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessCacheServe(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ cache_serve_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ switch (control->activate) {
+ case ACTIVATE_ON:
+ forwarder_SetChacheServeFlag(config->forwarder, true);
+ if (forwarder_GetChacheServeFlag(config->forwarder)) {
+ success = true;
+ }
+ break;
+
+ case ACTIVATE_OFF:
+ forwarder_SetChacheServeFlag(config->forwarder, false);
+ if (!forwarder_GetChacheServeFlag(config->forwarder)) {
+ success = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ struct iovec *response;
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(cache_store_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(cache_store_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessCacheClear(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+
+ forwarder_ClearCache(config->forwarder);
+
+ struct iovec *response = utils_CreateAck(header, NULL, 0);
+ return response;
+}
+
+size_t configuration_GetObjectStoreSize(Configuration *config) {
+ return config->maximumContentObjectStoreSize;
+}
+
+void _configuration_StoreFwdStrategy(Configuration *config, const char *prefix,
+ strategy_type strategy) {
+ PARCString *prefixStr = parcString_Create(prefix);
+ PARCUnsigned *strategyValue = parcUnsigned_Create((unsigned)strategy);
+ parcHashMap_Put(config->strategy_map, prefixStr, strategyValue);
+ parcUnsigned_Release(&strategyValue);
+ parcString_Release(&prefixStr);
+}
+
+struct iovec *configuration_SetWldr(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ set_wldr_command *control = request[1].iov_base;
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+ Connection *conn = NULL;
+ bool success = false;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+
+ if (utils_IsNumber(symbolicOrConnid)) {
+ // case for connid as input: check if connID present in the fwd table
+ conn = (Connection *)connectionTable_FindById(
+ table, (unsigned)strtold(symbolicOrConnid, NULL));
+ if (conn) {
+ success = true;
+ } else {
+ logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO,
+ PARCLogLevel_Error, __func__,
+ "ConnID not found, check list connections"); // failure
+ }
+ } else {
+ // case for symbolic as input: check if symbolic name can be resolved
+ unsigned connid =
+ symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid);
+ if (connid != UINT32_MAX) {
+ conn = (Connection *)connectionTable_FindById(table, connid);
+ if (conn) {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Debug)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Debug,
+ __func__, "Set wldr resolve name '%s' to connid %u",
+ symbolicOrConnid, connid);
+ }
+ success = true;
+ }
+ } else {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ __func__, "Symbolic name '%s' could not be resolved",
+ symbolicOrConnid);
+ } // failure
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) {
+ switch (control->activate) {
+ case ACTIVATE_ON:
+ connection_EnableWldr(conn);
+ response = utils_CreateAck(header, control, sizeof(set_wldr_command));
+ break;
+
+ case ACTIVATE_OFF:
+ connection_DisableWldr(conn);
+ response = utils_CreateAck(header, control, sizeof(set_wldr_command));
+ break;
+
+ default: // received wrong value
+ response = utils_CreateNack(header, control, sizeof(set_wldr_command));
+ break;
+ }
+ } else {
+ response = utils_CreateNack(header, control, sizeof(set_wldr_command));
+ }
+
+ return response;
+}
+
+strategy_type configuration_GetForwardingStrategy(Configuration *config,
+ const char *prefix) {
+ PARCString *prefixStr = parcString_Create(prefix);
+ const unsigned *val = parcHashMap_Get(config->strategy_map, prefixStr);
+ parcString_Release(&prefixStr);
+
+ if (val == NULL) {
+ return LAST_STRATEGY_VALUE;
+ } else {
+ return (strategy_type)*val;
+ }
+}
+
+struct iovec *configuration_SetForwardingStrategy(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ set_strategy_command *control = request[1].iov_base;
+
+ const char *prefix = utils_PrefixLenToString(
+ control->addressType, &control->address, &control->len);
+ strategy_type strategy = control->strategyType;
+ strategy_type existingFwdStrategy =
+ configuration_GetForwardingStrategy(config, prefix);
+
+ if (existingFwdStrategy == LAST_STRATEGY_VALUE ||
+ strategy != existingFwdStrategy) {
+ // means such a new strategy is not present in the hash table or has to be
+ // updated
+ _configuration_StoreFwdStrategy(config, prefix, strategy);
+ Name *hicnPrefix = name_CreateFromAddress(control->addressType,
+ control->address, control->len);
+ forwarder_SetStrategy(config->forwarder, hicnPrefix, strategy);
+ name_Release(&hicnPrefix);
+ }
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(set_strategy_command));
+
+ return response;
+}
+
+void configuration_SetObjectStoreSize(Configuration *config,
+ size_t maximumObjectCount) {
+ config->maximumContentObjectStoreSize = maximumObjectCount;
+
+ forwarder_SetContentObjectStoreSize(config->forwarder,
+ config->maximumContentObjectStoreSize);
+}
+
+Forwarder *configuration_GetForwarder(const Configuration *config) {
+ return config->forwarder;
+}
+
+Logger *configuration_GetLogger(const Configuration *config) {
+ return config->logger;
+}
+
+struct iovec *configuration_MapMeEnable(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ mapme_activator_command *control = request[1].iov_base;
+ const char *stateString[2] = {"on", "off"};
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_Format(composer,
+ "The mapme enable setting received is: %s",
+ stateString[control->activate]);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(mapme_activator_command));
+
+ return response;
+}
+
+struct iovec *configuration_MapMeDiscovery(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ mapme_activator_command *control = request[1].iov_base;
+ const char *stateString[2] = {"on", "off"};
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_Format(composer,
+ "The mapme discovery setting received is: %s",
+ stateString[control->activate]);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(mapme_activator_command));
+
+ return response;
+}
+
+struct iovec *configuration_MapMeTimescale(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ mapme_timing_command *control = request[1].iov_base;
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_Format(composer,
+ "The mapme timescale value received is: %u",
+ control->timePeriod);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(mapme_timing_command));
+
+ return response;
+}
+
+struct iovec *configuration_MapMeRetx(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ mapme_timing_command *control = request[1].iov_base;
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_Format(
+ composer, "The mapme retransmission time value received is: %u",
+ control->timePeriod);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(mapme_timing_command));
+
+ return response;
+}
+
+// ===========================
+// Main functions that deal with receiving commands, executing them, and sending
+// ACK/NACK
+
+struct iovec *configuration_DispatchCommand(Configuration *config,
+ command_id command,
+ struct iovec *control,
+ unsigned ingressId) {
+ struct iovec *response = NULL;
+
+ switch (command) {
+ case ADD_LISTENER:
+ response = configurationListeners_Add(config, control, ingressId);
+ break;
+
+ case ADD_CONNECTION:
+ response = configuration_ProcessCreateTunnel(config, control);
+ break;
+
+ case LIST_CONNECTIONS:
+ response = configuration_ProcessConnectionList(config, control);
+ break;
+
+ case ADD_ROUTE:
+ response =
+ configuration_ProcessRegisterHIcnPrefix(config, control, ingressId);
+ break;
+
+ case LIST_ROUTES:
+ response = configuration_ProcessRegistrationList(config, control);
+ break;
+
+ case REMOVE_CONNECTION:
+ response = configuration_ProcessRemoveTunnel(config, control);
+ break;
+
+ case REMOVE_ROUTE:
+ response = configuration_ProcessUnregisterHIcnPrefix(config, control);
+ break;
+
+ case CACHE_STORE:
+ response = configuration_ProcessCacheStore(config, control);
+ break;
+
+ case CACHE_SERVE:
+ response = configuration_ProcessCacheServe(config, control);
+ break;
+
+ case CACHE_CLEAR:
+ response = configuration_ProcessCacheClear(config, control);
+ break;
+
+ case SET_STRATEGY:
+ response = configuration_SetForwardingStrategy(config, control);
+ break;
+
+ case SET_WLDR:
+ response = configuration_SetWldr(config, control);
+ break;
+
+ case ADD_PUNTING:
+ response = configurationListeners_AddPunting(config, control, ingressId);
+ break;
+
+ case LIST_LISTENERS:
+ response = configuration_ProcessListenersList(config, control);
+ break;
+
+ case MAPME_ENABLE:
+ response = configuration_MapMeEnable(config, control);
+ break;
+
+ case MAPME_DISCOVERY:
+ response = configuration_MapMeDiscovery(config, control);
+ break;
+
+ case MAPME_TIMESCALE:
+ response = configuration_MapMeTimescale(config, control);
+ break;
+
+ case MAPME_RETX:
+ response = configuration_MapMeRetx(config, control);
+ break;
+
+ default:
+ break;
+ }
+
+ return response;
+}
+
+void configuration_ReceiveCommand(Configuration *config, command_id command,
+ struct iovec *request, unsigned ingressId) {
+ parcAssertNotNull(config, "Parameter config must be non-null");
+ parcAssertNotNull(request, "Parameter request must be non-null");
+ struct iovec *response =
+ configuration_DispatchCommand(config, command, request, ingressId);
+ configuration_SendResponse(config, response, ingressId);
+
+ switch (command) {
+ case LIST_CONNECTIONS:
+ case LIST_ROUTES: // case LIST_INTERFACES: case ETC...:
+ parcMemory_Deallocate(
+ &response[1]
+ .iov_base); // deallocate payload only if generated at fwd side
+ break;
+ default:
+ break;
+ }
+
+ // deallocate received request. It coincides with response[0].iov_base memory
+ // parcMemory_Deallocate(&request); //deallocate header and payload (if
+ // same sent by controller)
+ parcMemory_Deallocate(&response); // deallocate iovec pointer
+}
diff --git a/hicn-light/src/config/configuration.h b/hicn-light/src/config/configuration.h
new file mode 100755
index 0000000..2bf66c0
--- /dev/null
+++ b/hicn-light/src/config/configuration.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file configuration.h
+ * @brief hicn-light configuration, such as in-band commands or CLI
+ *
+ * Manages all user configuration of the system, such as from the CLI or web
+ * interface It remembers the user commands and will be able to write out a
+ * config file.
+ *
+ */
+
+#ifndef configuration_h
+#define configuration_h
+
+#include <src/utils/commands.h>
+#include <src/core/logger.h>
+
+struct configuration;
+typedef struct configuration Configuration;
+
+struct forwarder;
+typedef struct forwarder Forwarder;
+
+/**
+ * <#One Line Description#>
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+Configuration *configuration_Create(Forwarder *forwarder);
+
+/**
+ * <#One Line Description#>
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void configuration_Destroy(Configuration **configPtr);
+
+void configuration_SetupAllListeners(Configuration *config, uint16_t port,
+ const char *localPath);
+
+void configuration_ReceiveCommand(Configuration *config, command_id command,
+ struct iovec *request, unsigned ingressId);
+
+/**
+ * Returns the configured size of the content store
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+size_t configuration_GetObjectStoreSize(Configuration *config);
+
+/**
+ * Sets the size of the content store (in objects, not bytes)
+ *
+ * Must be set before starting the forwarder
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void configuration_SetObjectStoreSize(Configuration *config,
+ size_t maximumContentObjectCount);
+
+strategy_type configuration_GetForwardingStrategy(Configuration *config,
+ const char *prefix);
+
+/**
+ * Returns the Forwarder that owns the Configuration
+ *
+ * Returns the hicn-light Forwarder. Used primarily by associated classes in
+ * the configuration group.
+ *
+ * @param [in] config An allocated Configuration
+ *
+ * @return non-null The owning Forwarder
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+Forwarder *configuration_GetForwarder(const Configuration *config);
+
+/**
+ * Returns the logger used by the Configuration subsystem
+ *
+ * Returns the logger specified when the Configuration was created.
+ *
+ * @param [in] config An allocated Configuration
+ *
+ * @retval non-null The logger
+ * @retval null An error
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+Logger *configuration_GetLogger(const Configuration *config);
+
+struct iovec *configuration_DispatchCommand(Configuration *config,
+ command_id command,
+ struct iovec *control,
+ unsigned ingressId);
+
+#endif // configuration_h
diff --git a/hicn-light/src/config/configurationFile.c b/hicn-light/src/config/configurationFile.c
new file mode 100755
index 0000000..eab8f93
--- /dev/null
+++ b/hicn-light/src/config/configurationFile.c
@@ -0,0 +1,300 @@
+/*
+ * 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 <ctype.h>
+#include <errno.h>
+#include <src/config.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <parc/algol/parc_ArrayList.h>
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Object.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/configuration.h>
+#include <src/config/configurationFile.h>
+#include <src/config/controlRoot.h>
+#include <src/config/controlState.h>
+
+struct configuration_file {
+ Forwarder *forwarder;
+ const char *filename;
+ FILE *fh;
+
+ size_t linesRead;
+
+ // our custom state machine.
+ ControlState *controlState;
+};
+
+/*
+ * Called by a command to dispatch the correct command
+ */
+struct iovec *_writeRead(ControlState *state, struct iovec *msg) {
+ ConfigurationFile *configFile =
+ (ConfigurationFile *)controlState_GetUserdata(state);
+
+ parcAssertNotNull(msg, "Parameter msg must be non-null");
+ struct iovec *response = configuration_DispatchCommand(
+ forwarder_GetConfiguration(configFile->forwarder),
+ ((header_control_message *)msg[0].iov_base)->commandID, msg, 0);
+
+ return response;
+}
+
+/**
+ * Removes leading whitespace (space + tab).
+ *
+ * If the string is all whitespace, the return value will point to the
+ * terminating '\0'.
+ *
+ * @param [in] str A null-terminated c-string
+ *
+ * @retval non-null A pointer in to string of the first non-whitespace
+ *
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+static char *_stripLeadingWhitespace(char *str) {
+ while (isspace(*str)) {
+ str++;
+ }
+ return str;
+}
+
+/**
+ * Removes trailing whitespace
+ *
+ * Inserts a NULL after the last non-whitespace character, modiyfing the input
+ * string.
+ *
+ * @param [in] str A null-terminated c-string
+ *
+ * @return non-null A pointer to the input string
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+static char *_stripTrailingWhitespace(char *str) {
+ char *p = str + strlen(str) - 1;
+ while (p > str && isspace(*p)) {
+ p--;
+ }
+
+ // cap it. If no whitespace, p+1 == str + strlen(str), so will overwrite the
+ // current null. If all whitespace p+1 == str+1. For an empty string, p+1 =
+ // str.
+ *(p + 1) = 0;
+
+ // this does not catch the case where the entire string is whitespace
+ if (p == str && isspace(*p)) {
+ *p = 0;
+ }
+
+ return str;
+}
+
+/**
+ * Removed leading and trailing whitespace
+ *
+ * Modifies the input string (may add a NULL at the end). Will return
+ * a pointer to the first non-whitespace character or the terminating NULL.
+ *
+ * @param [in] str A null-terminated c-string
+ *
+ * @return non-null A pointer in to the input string
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+static char *_trim(char *str) {
+ return _stripTrailingWhitespace(_stripLeadingWhitespace(str));
+}
+
+/**
+ * Parse a string in to a PARCList with one word per element
+ *
+ * The string passed will be modified by inserting NULLs after each token.
+ *
+ * @param [in] str A c-string (will be modified)
+ *
+ * @retval non-null A PARCList where each item is a single word
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+static PARCList *_parseArgs(char *str) {
+ PARCList *list =
+ parcList(parcArrayList_Create(NULL), PARCArrayListAsPARCList);
+
+ const char delimiters[] = " \t";
+
+ char *token;
+ while ((token = strsep(&str, delimiters)) != NULL) {
+ parcList_Add(list, token);
+ }
+
+ return list;
+}
+
+// =============================================================
+
+static void _destroy(ConfigurationFile **configFilePtr) {
+ ConfigurationFile *configFile = *configFilePtr;
+ parcMemory_Deallocate((void **)&configFile->filename);
+
+ if (configFile->fh != NULL) {
+ fclose(configFile->fh);
+ }
+
+ controlState_Destroy(&configFile->controlState);
+}
+
+parcObject_ExtendPARCObject(ConfigurationFile, _destroy, NULL, NULL, NULL, NULL,
+ NULL, NULL);
+
+parcObject_ImplementRelease(configurationFile, ConfigurationFile);
+
+ConfigurationFile *configurationFile_Create(Forwarder *forwarder,
+ const char *filename) {
+ parcAssertNotNull(forwarder, "Parameter hicn-fwd must be non-null");
+ parcAssertNotNull(filename, "Parameter filename must be non-null");
+
+ ConfigurationFile *configFile = parcObject_CreateInstance(ConfigurationFile);
+
+ if (configFile) {
+ configFile->linesRead = 0;
+ configFile->forwarder = forwarder;
+ configFile->filename =
+ parcMemory_StringDuplicate(filename, strlen(filename));
+ parcAssertNotNull(configFile->filename, "Could not copy string '%s'",
+ filename);
+
+ // setup the control state for the command parser: last parameter NULL
+ // because
+ // writeRead still not implemented from configuration file.
+ configFile->controlState =
+ controlState_Create(configFile, _writeRead, false);
+
+ // we do not register Help commands
+ controlState_RegisterCommand(configFile->controlState,
+ controlRoot_Create(configFile->controlState));
+
+ // open the file and make sure we can read it
+ configFile->fh = fopen(configFile->filename, "r");
+
+ if (configFile->fh) {
+ if (logger_IsLoggable(forwarder_GetLogger(forwarder),
+ LoggerFacility_Config, PARCLogLevel_Debug)) {
+ logger_Log(forwarder_GetLogger(forwarder), LoggerFacility_Config,
+ PARCLogLevel_Debug, __func__, "Open config file %s",
+ configFile->filename);
+ }
+ } else {
+ if (logger_IsLoggable(forwarder_GetLogger(forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error)) {
+ logger_Log(forwarder_GetLogger(forwarder), LoggerFacility_Config,
+ PARCLogLevel_Error, __func__,
+ "Could not open config file %s: (%d) %s",
+ configFile->filename, errno, strerror(errno));
+ }
+
+ // failure cleanup the object -- this nulls it so final return null be
+ // NULL
+ configurationFile_Release(&configFile);
+ }
+ }
+ return configFile;
+}
+
+bool configurationFile_Process(ConfigurationFile *configFile) {
+ parcAssertNotNull(configFile, "Parameter configFile must be non-null");
+
+ // default to a "true" return value and only set to false if we encounter an
+ // error.
+ bool success = true;
+
+#define BUFFERLEN 2048
+ char buffer[BUFFERLEN];
+
+ configFile->linesRead = 0;
+
+ // always clear errors and fseek to start of file in case we get called
+ // multiple times.
+ clearerr(configFile->fh);
+ rewind(configFile->fh);
+
+ while (success && fgets(buffer, BUFFERLEN, configFile->fh) != NULL) {
+ configFile->linesRead++;
+
+ char *stripedBuffer = _trim(buffer);
+ if (strlen(stripedBuffer) > 0) {
+ if (stripedBuffer[0] != '#') {
+ // not empty and not a comment
+
+ // _parseArgs will modify the string
+ char *copy =
+ parcMemory_StringDuplicate(stripedBuffer, strlen(stripedBuffer));
+ PARCList *args = _parseArgs(copy);
+ CommandReturn result =
+ controlState_DispatchCommand(configFile->controlState, args);
+
+ // we ignore EXIT from the configuration file
+ if (result == CommandReturn_Failure) {
+ if (logger_IsLoggable(forwarder_GetLogger(configFile->forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error)) {
+ logger_Log(forwarder_GetLogger(configFile->forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error, __func__,
+ "Error on input file %s line %d: %s",
+ configFile->filename, configFile->linesRead,
+ stripedBuffer);
+ }
+ success = false;
+ }
+ parcList_Release(&args);
+ parcMemory_Deallocate((void **)&copy);
+ }
+ }
+ }
+
+ if (ferror(configFile->fh)) {
+ if (logger_IsLoggable(forwarder_GetLogger(configFile->forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error)) {
+ logger_Log(forwarder_GetLogger(configFile->forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error, __func__,
+ "Error on input file %s line %d: (%d) %s",
+ configFile->filename, configFile->linesRead, errno,
+ strerror(errno));
+ }
+ success = false;
+ }
+
+ return success;
+}
diff --git a/hicn-light/src/config/configurationFile.h b/hicn-light/src/config/configurationFile.h
new file mode 100755
index 0000000..5454819
--- /dev/null
+++ b/hicn-light/src/config/configurationFile.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file configurationFile.h
+ * @brief Accepts a filename and provides a means to read it into Configuration
+ *
+ * Reads a configuration file and converts the lines in to configuration
+ * commands for use in Configuration.
+ *
+ * Accepts '#' lines as comments. Skips blank and whitespace-only lines.
+ *
+ */
+
+#ifndef configurationFile_h
+#define configurationFile_h
+
+#include <src/core/forwarder.h>
+
+struct configuration_file;
+typedef struct configuration_file ConfigurationFile;
+
+/**
+ * Creates a ConfigurationFile to prepare to process the file
+ *
+ * Prepares the object and opens the file. Makes sure we can read the file.
+ * Does not read the file or process any commands from the file.
+ *
+ * @param [in] hicn-light An allocated Forwarder to configure with the file
+ * @param [in] filename The file to use
+ *
+ * @retval non-null An allocated ConfigurationFile that is readable
+ * @retval null An error
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+ConfigurationFile *configurationFile_Create(Forwarder *forwarder,
+ const char *filename);
+
+/**
+ * Reads the configuration file line-by-line and issues commands to
+ * Configuration
+ *
+ * Reads the file line by line. Skips '#' and blank lines.
+ *
+ * Will stop on the first error. Lines already processed will not be un-done.
+ *
+ * @param [in] configFile An allocated ConfigurationFile
+ *
+ * @retval true The entire files was processed without error.
+ * @retval false There was an error in the file.
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool configurationFile_Process(ConfigurationFile *configFile);
+
+// void configurationFile_ProcessForwardingStrategies(Configuration * config,
+// ConfigurationFile * configFile);
+
+/**
+ * Closes the underlying file and releases memory
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [in,out] configFilePtr An allocated ConfigurationFile that will be
+ * NULL'd as output
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void configurationFile_Release(ConfigurationFile **configFilePtr);
+
+#endif /* defined(configurationFile_h) */
diff --git a/hicn-light/src/config/configurationListeners.c b/hicn-light/src/config/configurationListeners.c
new file mode 100755
index 0000000..be30e2a
--- /dev/null
+++ b/hicn-light/src/config/configurationListeners.c
@@ -0,0 +1,535 @@
+/*
+ * 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 <arpa/inet.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/core/system.h>
+#include <src/utils/interfaceSet.h>
+#include <src/utils/punting.h>
+
+#include <src/config/configurationListeners.h>
+#include <src/io/hicnListener.h>
+#include <src/io/tcpListener.h>
+#include <src/io/udpListener.h>
+
+#include <src/utils/addressList.h>
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static bool _setupHIcnListenerOnInet4(Forwarder *forwarder,
+ const char *symbolic, Address *address) {
+ bool success = false;
+#ifndef __APPLE__
+ ListenerOps *ops =
+ hicnListener_CreateInet(forwarder, (char *)symbolic, address);
+ if (ops != NULL) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add HIcn listener %s to ListenerSet",
+ symbolic);
+ }
+#endif /* __APPLE__ */
+ return success;
+}
+
+static bool _setupHIcnListenerOnInet6(Forwarder *forwarder,
+ const char *symbolic, Address *address) {
+ bool success = false;
+#ifndef __APPLE__
+ ListenerOps *ops =
+ hicnListener_CreateInet6(forwarder, (char *)symbolic, address);
+ if (ops != NULL) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add HIcn listener %s to ListenerSet",
+ symbolic);
+ }
+#endif /* __APPLE__ */
+ return success;
+}
+
+bool configurationListeners_Remove(const Configuration *config) {
+ Logger *logger = configuration_GetLogger(config);
+ if (logger_IsLoggable(logger, LoggerFacility_Config, PARCLogLevel_Warning)) {
+ logger_Log(logger, LoggerFacility_Config, PARCLogLevel_Warning, __func__,
+ "Removing a listener not supported: ingress %u control %s");
+ }
+
+ return false;
+}
+
+bool _AddPuntingInet(const Configuration *config, Punting *punting,
+ unsigned ingressId) {
+#ifndef __APPLE__
+ struct sockaddr *addr = parcNetwork_SockAddress("0.0.0.0", 1234);
+ if (addr == NULL) {
+ printf("Error creating address\n");
+ return false;
+ }
+
+ Address *fakeAddr = addressCreateFromInet((struct sockaddr_in *)addr);
+
+ ListenerOps *listenerOps = listenerSet_Find(
+ forwarder_GetListenerSet(configuration_GetForwarder(config)), ENCAP_HICN,
+ fakeAddr);
+ addressDestroy(&fakeAddr);
+
+ if (listenerOps == NULL) {
+ printf("the main listener (IPV4) does not exists\n");
+ return false;
+ }
+
+ struct sockaddr_in puntingAddr;
+
+ Address *address = puntingGetAddress(punting);
+ if (address == NULL) return false;
+
+ bool res = addressGetInet(address, &puntingAddr);
+ if (!res) {
+ printf("unable to read the punting address\n");
+ return false;
+ }
+
+ char prefix[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, &(puntingAddr.sin_addr), prefix, INET_ADDRSTRLEN);
+
+ char len[5];
+ sprintf(len, "%d", puntingPrefixLen(punting));
+
+ char *prefixStr =
+ malloc(strlen(prefix) + strlen(len) + 2); //+1 for the zero-terminator
+ if (prefixStr == NULL) {
+ printf("error while create the prefix string\n");
+ return false;
+ }
+ strcpy(prefixStr, prefix);
+ strcat(prefixStr, "/");
+ strcat(prefixStr, len);
+
+ res = hicnListener_Punting(listenerOps, prefixStr);
+ if (!res) {
+ printf("error while adding the punting rule\n");
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool _AddPuntingInet6(const Configuration *config, Punting *punting,
+ unsigned ingressId) {
+#ifndef __APPLE__
+ struct sockaddr *addr = parcNetwork_SockAddress("0::0", 1234);
+ if (addr == NULL) {
+ printf("Error creating address\n");
+ return false;
+ }
+
+ Address *fakeAddr = addressCreateFromInet6((struct sockaddr_in6 *)addr);
+
+ // comments:
+ // EncapType: I use the HIcn encap since the puting is available only for HIcn
+ // listeners LocalAddress: The only listern for which we need punting rules is
+ // the main one, which has no address
+ // so I create a fake empty address. This need to be consistent
+ // with the address set at creation time
+
+ ListenerOps *listenerOps = listenerSet_Find(
+ forwarder_GetListenerSet(configuration_GetForwarder(config)), ENCAP_HICN,
+ fakeAddr);
+ addressDestroy(&fakeAddr);
+
+ if (listenerOps == NULL) {
+ printf("the main listener does not exists\n");
+ return false;
+ }
+
+ struct sockaddr_in6 puntingAddr;
+ bool res = addressGetInet6(puntingGetAddress(punting), &puntingAddr);
+ if (!res) {
+ printf("unable to read the punting address\n");
+ return false;
+ }
+
+ char prefix[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET6, &(puntingAddr.sin6_addr), prefix, INET6_ADDRSTRLEN);
+
+ char len[5];
+ sprintf(len, "%d", puntingPrefixLen(punting));
+
+ char *prefixStr =
+ malloc(strlen(prefix) + strlen(len) + 2); //+1 for the zero-terminator
+ if (prefixStr == NULL) {
+ printf("error while create the prefix string\n");
+ return false;
+ }
+ strcpy(prefixStr, prefix);
+ strcat(prefixStr, "/");
+ strcat(prefixStr, len);
+
+ res = hicnListener_Punting(listenerOps, prefixStr);
+ if (!res) {
+ printf("error while adding the punting rule\n");
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+//============= LIGHT COMMAN ===============
+
+static bool _addEther(Configuration *config, add_listener_command *control,
+ unsigned ingressId) {
+ // Not implemented
+ return false;
+}
+
+static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
+ uint16_t *port) {
+ bool success = false;
+
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = *port;
+ addr.sin_addr.s_addr = *addr4;
+
+ ListenerOps *ops = tcpListener_CreateInet(forwarder, addr);
+ if (ops) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add TCP listener on %s to ListenerSet",
+ addressToString(ops->getListenAddress(ops)));
+ }
+ return success;
+}
+
+static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
+ uint16_t *port) {
+ bool success = false;
+
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = *port;
+ addr.sin_addr.s_addr = *addr4;
+
+ ListenerOps *ops = udpListener_CreateInet(forwarder, addr);
+ if (ops) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add UDP listener on %s to ListenerSet",
+ addressToString(ops->getListenAddress(ops)));
+ }
+ return success;
+}
+
+static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder,
+ ipv6_addr_t *addr6, uint16_t *port,
+ uint32_t scopeId) {
+ bool success = false;
+
+ struct sockaddr_in6 addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = *port;
+ addr.sin6_addr = *addr6;
+ addr.sin6_scope_id = scopeId;
+
+ ListenerOps *ops = tcpListener_CreateInet6(forwarder, addr);
+ if (ops) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add TCP6 listener on %s to ListenerSet",
+ addressToString(ops->getListenAddress(ops)));
+ }
+ return success;
+}
+
+static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder,
+ ipv6_addr_t *addr6, uint16_t *port) {
+ bool success = false;
+
+ struct sockaddr_in6 addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = *port;
+ addr.sin6_addr = *addr6;
+ addr.sin6_scope_id = 0;
+
+ ListenerOps *ops = udpListener_CreateInet6(forwarder, addr);
+ if (ops) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add UDP6 listener on %s to ListenerSet",
+ addressToString(ops->getListenAddress(ops)));
+ }
+ return success;
+}
+
+bool _addHicn(Configuration *config, add_listener_command *control,
+ unsigned ingressId) {
+ bool success = false;
+ const char *symbolic = control->symbolic;
+ Address *localAddress = NULL;
+
+ switch (control->addressType) {
+ case ADDR_INET: {
+ localAddress =
+ utils_AddressFromInet(&control->address.ipv4, &control->port);
+ success = _setupHIcnListenerOnInet4(configuration_GetForwarder(config),
+ symbolic, localAddress);
+ break;
+ }
+
+ case ADDR_INET6: {
+ localAddress =
+ utils_AddressFromInet6(&control->address.ipv6, &control->port);
+ success = _setupHIcnListenerOnInet6(configuration_GetForwarder(config),
+ symbolic, localAddress);
+ break;
+ }
+
+ default:
+ if (logger_IsLoggable(configuration_GetLogger(config),
+ LoggerFacility_Config, PARCLogLevel_Warning)) {
+ logger_Log(configuration_GetLogger(config), LoggerFacility_Config,
+ PARCLogLevel_Warning, __func__,
+ "Unsupported address type for HICN (ingress id %u): "
+ "must be either IPV4 or IPV6",
+ ingressId);
+ }
+ break;
+ }
+
+ if (success == true && localAddress != NULL) {
+ if (logger_IsLoggable(configuration_GetLogger(config),
+ LoggerFacility_Config, PARCLogLevel_Info)) {
+ logger_Log(configuration_GetLogger(config), LoggerFacility_Config,
+ PARCLogLevel_Info, __func__,
+ "Setup hicn listener on address %s",
+ addressToString(localAddress));
+ }
+ }
+
+ addressDestroy(&localAddress);
+
+ return success;
+}
+
+bool _addIP(Configuration *config, add_listener_command *control,
+ unsigned ingressId) {
+ bool success = false;
+
+ switch (control->addressType) {
+ case ADDR_INET: {
+ if (control->connectionType == UDP_CONN) {
+ success =
+ _setupUdpListenerOnInet(configuration_GetForwarder(config),
+ &control->address.ipv4, &control->port);
+ } else if (control->connectionType == TCP_CONN) {
+ success =
+ _setupTcpListenerOnInet(configuration_GetForwarder(config),
+ &control->address.ipv4, &control->port);
+ }
+ break;
+ }
+
+ case ADDR_INET6: {
+ if (control->connectionType == UDP_CONN) {
+ success = _setupUdpListenerOnInet6Light(
+ configuration_GetForwarder(config), &control->address.ipv6,
+ &control->port);
+ } else if (control->connectionType == TCP_CONN) {
+ success = _setupTcpListenerOnInet6Light(
+ configuration_GetForwarder(config), &control->address.ipv6,
+ &control->port, 0);
+ }
+ break;
+ }
+
+ default:
+ if (logger_IsLoggable(configuration_GetLogger(config),
+ LoggerFacility_Config, PARCLogLevel_Warning)) {
+ char *addrStr = utils_CommandAddressToString(
+ control->addressType, &control->address, &control->port);
+ logger_Log(
+ configuration_GetLogger(config), LoggerFacility_Config,
+ PARCLogLevel_Warning, __func__,
+ "Unsupported address type for IP encapsulation ingress id %u: %s",
+ ingressId, addrStr);
+ parcMemory_Deallocate((void **)&addrStr);
+ }
+ break;
+ }
+
+ if (success) {
+ if (logger_IsLoggable(configuration_GetLogger(config),
+ LoggerFacility_Config, PARCLogLevel_Info)) {
+ char *addrStr = utils_CommandAddressToString(
+ control->addressType, &control->address, &control->port);
+ logger_Log(configuration_GetLogger(config), LoggerFacility_Config,
+ PARCLogLevel_Info, __func__, "Setup listener on address %s",
+ addrStr);
+ parcMemory_Deallocate((void **)&addrStr);
+ }
+ }
+
+ return success;
+}
+
+struct iovec *configurationListeners_Add(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId) {
+ header_control_message *header = request[0].iov_base;
+ add_listener_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ if (control->listenerMode == ETHER_MODE) {
+ parcTrapNotImplemented("Add Ethernet Listener is not supported");
+ success = _addEther(config, control, ingressId);
+ // it is a failure
+ } else if (control->listenerMode == IP_MODE) {
+ success = _addIP(config, control, ingressId);
+ } else if (control->listenerMode == HICN_MODE) {
+ success = _addHicn(config, control, ingressId);
+ } else {
+ Logger *logger = configuration_GetLogger(config);
+ if (logger_IsLoggable(logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(logger, LoggerFacility_Config, PARCLogLevel_Warning, __func__,
+ "Unsupported encapsulation mode (ingress id %u)", ingressId);
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(add_listener_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(add_listener_command));
+ }
+
+ return response;
+}
+
+struct iovec *configurationListeners_AddPunting(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId) {
+ header_control_message *header = request[0].iov_base;
+ add_punting_command *control = request[1].iov_base;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+ uint32_t len = control->len;
+ in_port_t port = htons(1234);
+ bool success = false;
+
+ if (control->addressType == ADDR_INET) {
+ Address *address = utils_AddressFromInet(&control->address.ipv4, &port);
+ Punting *punting = puntingCreate(symbolicOrConnid, address, len);
+ success = _AddPuntingInet(config, punting, ingressId);
+ addressDestroy(&address);
+ } else if (control->addressType == ADDR_INET6) {
+ Address *address = utils_AddressFromInet6(&control->address.ipv6, &port);
+ Punting *punting = puntingCreate(symbolicOrConnid, address, len);
+ success = _AddPuntingInet6(config, punting, ingressId);
+ addressDestroy(&address);
+ } else {
+ printf("Invalid IP type.\n"); // will generate a Nack
+ return utils_CreateNack(header, control, sizeof(add_punting_command));
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(add_punting_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(add_punting_command));
+ }
+
+ return response;
+}
+
+//=========================== INITIAL LISTENERS ====================
+
+static void _setupListenersOnAddress(Forwarder *forwarder,
+ const Address *address, uint16_t port,
+ const char *interfaceName) {
+ address_type type = addressGetType(address);
+ switch (type) {
+ case ADDR_INET: {
+ struct sockaddr_in tmp;
+ addressGetInet(address, &tmp);
+ _setupTcpListenerOnInet(forwarder, &tmp.sin_addr.s_addr, &port);
+ break;
+ }
+
+ case ADDR_INET6: {
+ struct sockaddr_in6 tmp;
+ addressGetInet6(address, &tmp);
+ _setupTcpListenerOnInet6Light(forwarder, &tmp.sin6_addr, &port,
+ tmp.sin6_scope_id);
+ break;
+ }
+
+ case ADDR_LINK:
+ // not used
+ break;
+
+ default:
+ // dont' know how to handle this, so no listeners
+ break;
+ }
+}
+
+void configurationListeners_SetupAll(const Configuration *config, uint16_t port,
+ const char *localPath) {
+ Forwarder *forwarder = configuration_GetForwarder(config);
+ InterfaceSet *set = system_Interfaces(forwarder);
+
+ size_t interfaceSetLen = interfaceSetLength(set);
+ for (size_t i = 0; i < interfaceSetLen; i++) {
+ Interface *iface = interfaceSetGetByOrdinalIndex(set, i);
+
+ const AddressList *addresses = interfaceGetAddresses(iface);
+ size_t addressListLen = addressListLength(addresses);
+
+ for (size_t j = 0; j < addressListLen; j++) {
+ const Address *address = addressListGetItem(addresses, j);
+
+ // Do not start on link address
+ if (addressGetType(address) != ADDR_LINK) {
+ _setupListenersOnAddress(forwarder, address, htons(port),
+ interfaceGetName(iface));
+ }
+ }
+ }
+
+ // if (localPath != NULL) {
+ // _setupLocalListener(forwarder, localPath);
+ //}
+
+ interfaceSetDestroy(&set);
+}
diff --git a/hicn-light/src/config/configurationListeners.h b/hicn-light/src/config/configurationListeners.h
new file mode 100755
index 0000000..7332b0c
--- /dev/null
+++ b/hicn-light/src/config/configurationListeners.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file configurationListeners.h
+ * @brief Configuration routines related to Listeners
+ *
+ * Adding and removing listeners.
+ *
+ */
+
+#ifndef configurationListeners_h
+#define configurationListeners_h
+
+#include <src/config/configuration.h>
+#include <src/core/forwarder.h>
+
+#include <src/utils/address.h>
+
+/**
+ * Setup udp, tcp, and local listeners
+ *
+ * Will bind to all available IP protocols on the given port.
+ * Does not add Ethernet listeners.
+ *
+ * @param port is the UPD and TCP port to use
+ * @param localPath is the AF_UNIX path to use, if NULL no AF_UNIX listener is
+ * setup
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void configurationListeners_SetupAll(const Configuration *config, uint16_t port,
+ const char *localPath);
+
+bool configurationListeners_Remove(const Configuration *config);
+
+// light functions
+
+struct iovec *configurationListeners_Add(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId);
+
+struct iovec *configurationListeners_AddPunting(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId);
+
+#endif /* defined(configurationListeners_h) */
diff --git a/hicn-light/src/config/controlAdd.c b/hicn-light/src/config/controlAdd.c
new file mode 100755
index 0000000..72f8e97
--- /dev/null
+++ b/hicn-light/src/config/controlAdd.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <src/config.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlAdd.h>
+#include <src/config/controlAddConnection.h>
+#include <src/config/controlAddListener.h>
+#include <src/config/controlAddPunting.h>
+#include <src/config/controlAddRoute.h>
+
+// ===================================================
+
+static void _controlAdd_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlAdd_Execute(CommandParser *parser, CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAdd_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+// ===================================================
+
+static const char *command_add = "add";
+static const char *help_command_add = "help add";
+
+CommandOps *webControlAdd_Create(ControlState *state) {
+ return commandOps_Create(state, command_add, _controlAdd_Init,
+ _controlAdd_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAdd_CreateHelp(ControlState *state) {
+ return commandOps_Create(state, help_command_add, NULL,
+ _controlAdd_HelpExecute, commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandReturn _controlAdd_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ CommandOps *ops_add_connection = controlAddConnection_Create(NULL);
+ CommandOps *ops_add_route = controlAddRoute_Create(NULL);
+ CommandOps *ops_add_punting = controlAddPunting_Create(NULL);
+ CommandOps *ops_add_listener = controlAddListener_Create(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_add_connection->command);
+ printf(" %s\n", ops_add_route->command);
+ printf(" %s\n", ops_add_punting->command);
+ printf(" %s\n", ops_add_listener->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_add_connection);
+ commandOps_Destroy(&ops_add_route);
+ commandOps_Destroy(&ops_add_punting);
+ commandOps_Destroy(&ops_add_listener);
+ return CommandReturn_Success;
+}
+
+static void _controlAdd_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlAddListener_HelpCreate(state));
+ controlState_RegisterCommand(state, controlAddListener_Create(state));
+ controlState_RegisterCommand(state, controlAddConnection_HelpCreate(state));
+ controlState_RegisterCommand(state, controlAddRoute_HelpCreate(state));
+ controlState_RegisterCommand(state, controlAddConnection_Create(state));
+ controlState_RegisterCommand(state, controlAddRoute_Create(state));
+ controlState_RegisterCommand(state, controlAddPunting_Create(state));
+ controlState_RegisterCommand(state, controlAddPunting_HelpCreate(state));
+}
+
+static CommandReturn _controlAdd_Execute(CommandParser *parser, CommandOps *ops,
+ PARCList *args) {
+ return _controlAdd_HelpExecute(parser, ops, args);
+}
diff --git a/hicn-light/src/config/controlAdd.h b/hicn-light/src/config/controlAdd.h
new file mode 100755
index 0000000..e1955f2
--- /dev/null
+++ b/hicn-light/src/config/controlAdd.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_Add.h
+ * @brief Command-line "add" node
+ *
+ * Implements the "add" node of the CLI tree
+ *
+ *
+ */
+
+#ifndef control_Add_h
+#define control_Add_h
+
+#include <src/config/controlState.h>
+
+CommandOps *webControlAdd_Create(ControlState *state);
+CommandOps *controlAdd_CreateHelp(ControlState *state);
+#endif // control_Add_h
diff --git a/hicn-light/src/config/controlAddConnection.c b/hicn-light/src/config/controlAddConnection.c
new file mode 100755
index 0000000..a0a966d
--- /dev/null
+++ b/hicn-light/src/config/controlAddConnection.c
@@ -0,0 +1,390 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <parc/assert/parc_Assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/config/controlAddConnection.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+// ===================================================
+
+static void _controlAddConnection_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlAddConnection_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddConnection_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static CommandReturn _controlAddConnection_HIcnHelpExecute(
+ CommandParser *parser, CommandOps *ops, PARCList *args);
+static CommandReturn _controlAddConnection_HIcnExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static CommandReturn _controlAddConnection_UdpHelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddConnection_UdpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static CommandReturn _controlAddConnection_TcpHelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddConnection_TcpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static const char *_commandAddConnection = "add connection";
+static const char *_commandAddConnectionHIcn = "add connection hicn";
+static const char *_commandAddConnectionUdp = "add connection udp";
+static const char *_commandAddConnectionTcp = "add connection tcp";
+static const char *_commandAddConnectionHelp = "help add connection";
+static const char *_commandAddConnectionHIcnHelp = "help add connection hicn";
+static const char *_commandAddConnectionUdpHelp = "help add connection udp";
+static const char *_commandAddConnectionTcpHelp = "help add connection tcp";
+
+// ===================================================
+
+CommandOps *controlAddConnection_Create(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnection,
+ _controlAddConnection_Init,
+ _controlAddConnection_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAddConnection_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionHelp, NULL,
+ _controlAddConnection_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandOps *_controlAddConnection_HIcnCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionHIcn, NULL,
+ _controlAddConnection_HIcnExecute,
+ commandOps_Destroy);
+}
+
+static CommandOps *_controlAddConnection_UdpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionUdp, NULL,
+ _controlAddConnection_UdpExecute,
+ commandOps_Destroy);
+}
+
+static CommandOps *_controlAddConnection_TcpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionTcp, NULL,
+ _controlAddConnection_TcpExecute,
+ commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandOps *_controlAddConnection_HIcnHelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionHIcnHelp, NULL,
+ _controlAddConnection_HIcnHelpExecute,
+ commandOps_Destroy);
+}
+
+static CommandOps *_controlAddConnection_UdpHelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionUdpHelp, NULL,
+ _controlAddConnection_UdpHelpExecute,
+ commandOps_Destroy);
+}
+
+static CommandOps *_controlAddConnection_TcpHelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionTcpHelp, NULL,
+ _controlAddConnection_TcpHelpExecute,
+ commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandReturn _controlAddConnection_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("Available commands:\n");
+ printf(" %s\n", _commandAddConnectionHIcn);
+ printf(" %s\n", _commandAddConnectionUdp);
+ printf(" %s\n", _commandAddConnectionTcp);
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static void _controlAddConnection_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state,
+ _controlAddConnection_HIcnHelpCreate(state));
+ controlState_RegisterCommand(state,
+ _controlAddConnection_UdpHelpCreate(state));
+ controlState_RegisterCommand(state,
+ _controlAddConnection_TcpHelpCreate(state));
+
+ controlState_RegisterCommand(state, _controlAddConnection_HIcnCreate(state));
+ controlState_RegisterCommand(state, _controlAddConnection_UdpCreate(state));
+ controlState_RegisterCommand(state, _controlAddConnection_TcpCreate(state));
+}
+
+static CommandReturn _controlAddConnection_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ return _controlAddConnection_HelpExecute(parser, ops, args);
+}
+
+// ===================================================
+// functions general to all connection types
+
+/**
+ * Create a tunnel in the forwarder based on the addresses
+ *
+ * Caller retains ownership of memory.
+ * The symbolic name will be used to refer to this connection. It must be unqiue
+ * otherwise the forwarder will reject this commend.
+ *
+ * @param [in] parser An allocated CommandParser
+ * @param [in] ops Allocated CommandOps (needed to extract ControlState)
+ * @param [in] localAddress the local IP and port. The port may be the wildcard
+ * value.
+ * @param [in] remoteAddress The remote IP and port (both must be specified)
+ * @param [in] tunnelType The tunneling protocol
+ * @param [in] symbolic The symbolic name for the connection (must be unique)
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * {
+ * struct sockaddr_in *anyAddress = parcNetwork_SockInet4AddressAny();
+ * struct sockaddr_in *remote =
+ * parcNetwork_SockInet4Address("192.168.1.2", 9695);
+ *
+ * Address *localAddress = addressCreateFromInet(anyAddress);
+ * Address *remoteAddress = addressCreateFromInet(remote);
+ *
+ * control_CreateTunnel(state, localAddress, remoteAddress, IPTUN_TCP,
+ * "conn7");
+ *
+ * addressDestroy(&localAddress);
+ * addressDestroy(&remoteAddress);
+ * parcMemory_Deallocate((void **)&remote);
+ * parcMemory_Deallocate((void **)&anyAddress);
+ * }
+ * @endcode
+ */
+
+static CommandReturn _controlAddConnection_CreateTunnel(
+ CommandParser *parser, CommandOps *ops, const char *local_ip,
+ const char *local_port, const char *remote_ip, const char *remote_port,
+ connection_type tunnelType, const char *symbolic) {
+ ControlState *state = ops->closure;
+ // a request like this always has an interface index of 0 [FIELD REMOVED]
+ // unsigned int interfaceIndex = 0;
+
+ // allocate command payload
+ add_connection_command *addConnectionCommand =
+ parcMemory_AllocateAndClear(sizeof(add_connection_command));
+
+ // check and set IP addresses
+ if (inet_pton(AF_INET, remote_ip, &addConnectionCommand->remoteIp.ipv4) ==
+ 1 &&
+ inet_pton(AF_INET, local_ip, &addConnectionCommand->localIp.ipv4) == 1) {
+ addConnectionCommand->ipType = ADDR_INET;
+
+ } else if (inet_pton(AF_INET6, remote_ip,
+ &addConnectionCommand->remoteIp.ipv6) == 1 &&
+ inet_pton(AF_INET6, local_ip,
+ &addConnectionCommand->localIp.ipv6) == 1) {
+ addConnectionCommand->ipType = ADDR_INET6;
+
+ } else {
+ printf("Error: local address %s not same type as remote address %s\n",
+ local_ip, remote_ip);
+ parcMemory_Deallocate(&addConnectionCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ addConnectionCommand->connectionType = tunnelType;
+ strcpy(addConnectionCommand->symbolic, symbolic);
+ addConnectionCommand->remotePort = htons((uint16_t)atoi(remote_port));
+ addConnectionCommand->localPort = htons((uint16_t)atoi(local_port));
+
+ // send message and receive response
+ struct iovec *response =
+ utils_SendRequest(state, ADD_CONNECTION, addConnectionCommand,
+ sizeof(add_connection_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_IpHelp(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args,
+ const char *protocol) {
+ printf("add connection hicn <symbolic> <remote_ip> <local_ip>\n");
+ printf(
+ "add connection udp <symbolic> <remote_ip> <port> <local_ip> <port>\n");
+ printf(
+ " <symbolic> : symbolic name, e.g. 'conn1' (must be "
+ "unique, start with alpha)\n");
+ printf(
+ " <remote_ip> : the IPv4 or IPv6 or hostname of the remote system\n");
+ printf(" <local_ip> : optional local IP address to bind to\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_HIcnHelpExecute(
+ CommandParser *parser, CommandOps *ops, PARCList *args) {
+ _controlAddConnection_IpHelp(parser, ops, args, "hicn");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_HIcnExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ static const int _indexSymbolic = 3;
+ static const int _indexRemAddr = 4;
+ static const int _indexLocAddr = 5;
+
+ if (parcList_Size(args) != 6) {
+ _controlAddConnection_HIcnHelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ char *symbolic = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolic)) {
+ printf(
+ "Invalid symbolic name. Must begin with alpha and contain only "
+ "alphanum.\n");
+ return CommandReturn_Failure;
+ }
+
+ char *remote_ip = parcList_GetAtIndex(args, _indexRemAddr);
+ char *local_ip = parcList_GetAtIndex(args, _indexLocAddr);
+ char *port = "1234"; // this is a random port number that will be ignored
+
+ return _controlAddConnection_CreateTunnel(
+ parser, ops, local_ip, port, remote_ip, port, HICN_CONN, symbolic);
+}
+
+static CommandReturn _controlAddConnection_UdpHelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ _controlAddConnection_IpHelp(parser, ops, args, "udp");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_UdpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ static const int _indexSymbolic = 3;
+ static const int _indexRemAddr = 4;
+ static const int _indexRemPort = 5;
+ static const int _indexLocAddr = 6;
+ static const int _indexLocPort = 7;
+
+ if (parcList_Size(args) != 8) {
+ _controlAddConnection_UdpHelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ char *symbolic = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolic)) {
+ printf(
+ "Invalid symbolic name. Must begin with alpha and contain only "
+ "alphanum.\n");
+ return CommandReturn_Failure;
+ }
+
+ char *remote_ip = parcList_GetAtIndex(args, _indexRemAddr);
+ char *local_ip = parcList_GetAtIndex(args, _indexLocAddr);
+
+ char *remote_port = parcList_GetAtIndex(args, _indexRemPort);
+ char *local_port = parcList_GetAtIndex(args, _indexLocPort);
+
+ return _controlAddConnection_CreateTunnel(parser, ops, local_ip, local_port,
+ remote_ip, remote_port, UDP_CONN,
+ symbolic);
+}
+
+static CommandReturn _controlAddConnection_TcpHelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ _controlAddConnection_IpHelp(parser, ops, args, "tcp");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_TcpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ static const int _indexSymbolic = 3;
+ static const int _indexRemAddr = 4;
+ static const int _indexRemPort = 5;
+ static const int _indexLocAddr = 6;
+ static const int _indexLocPort = 7;
+
+ if (parcList_Size(args) != 8) {
+ _controlAddConnection_UdpHelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ char *symbolic = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolic)) {
+ printf(
+ "Invalid symbolic name. Must begin with alpha and contain only "
+ "alphanum.\n");
+ return CommandReturn_Failure;
+ }
+
+ char *remote_ip = parcList_GetAtIndex(args, _indexRemAddr);
+ char *local_ip = parcList_GetAtIndex(args, _indexLocAddr);
+
+ char *remote_port = parcList_GetAtIndex(args, _indexRemPort);
+ char *local_port = parcList_GetAtIndex(args, _indexLocPort);
+
+ return _controlAddConnection_CreateTunnel(parser, ops, local_ip, local_port,
+ remote_ip, remote_port, TCP_CONN,
+ symbolic);
+}
diff --git a/hicn-light/src/config/controlAddConnection.h b/hicn-light/src/config/controlAddConnection.h
new file mode 100755
index 0000000..7883069
--- /dev/null
+++ b/hicn-light/src/config/controlAddConnection.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_AddConnection.h
+ * @brief Command-line "add connection" node
+ *
+ * Implements the "add connection" node of the CLI tree
+ *
+ *
+ */
+
+#ifndef controlAddConnection_h
+#define controlAddConnection_h
+
+#include <src/config/controlState.h>
+CommandOps *controlAddConnection_Create(ControlState *state);
+CommandOps *controlAddConnection_HelpCreate(ControlState *state);
+#endif // controlAddConnection_h
diff --git a/hicn-light/src/config/controlAddListener.c b/hicn-light/src/config/controlAddListener.c
new file mode 100755
index 0000000..8f687c3
--- /dev/null
+++ b/hicn-light/src/config/controlAddListener.c
@@ -0,0 +1,178 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/config/controlAddListener.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlAddListener_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddListener_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *command_add_listener = "add listener";
+static const char *command_help_add_listener = "help add listener";
+
+CommandOps *controlAddListener_Create(ControlState *state) {
+ return commandOps_Create(state, command_add_listener, NULL,
+ _controlAddListener_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAddListener_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, command_help_add_listener, NULL,
+ _controlAddListener_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static const int _indexProtocol = 2;
+static const int _indexSymbolic = 3;
+static const int _indexAddress = 4;
+static const int _indexPort = 5;
+
+static CommandReturn _controlAddListener_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("commands:\n");
+ printf(" add listener hicn <symbolic> <localAddress> \n");
+ printf(" add listener udp <symbolic> <localAddress> <port> \n");
+ printf(" add listener tcp <symbolic> <localAddress> <port> \n");
+ printf("\n");
+ printf(
+ " symbolic: User defined name for listener, must start with "
+ "alpha and be alphanum\n");
+ printf(" protocol: hicn | udp\n");
+ printf(
+ " localAddress: IPv4 or IPv6 address (or prefix protocol = hicn) "
+ "assigend to the local interface\n");
+ printf(" port: Udp port\n");
+ printf("\n");
+ printf("Notes:\n");
+ printf(" The symblic name must be unique or the source will reject it.\n");
+ printf(
+ " If protocol = hinc: the address 0::0 indicates the main listern, "
+ "for which we can set punting rules.\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _CreateListener(CommandParser *parser, CommandOps *ops,
+ const char *symbolic, const char *addr,
+ const char *port, listener_mode mode,
+ connection_type type) {
+ ControlState *state = ops->closure;
+
+ // allocate command payload
+ add_listener_command *addListenerCommand =
+ parcMemory_AllocateAndClear(sizeof(add_listener_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &addListenerCommand->address.ipv4) == 1) {
+ addListenerCommand->addressType = ADDR_INET;
+
+ } else if (inet_pton(AF_INET6, addr, &addListenerCommand->address.ipv6) ==
+ 1) {
+ addListenerCommand->addressType = ADDR_INET6;
+
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&addListenerCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ addListenerCommand->listenerMode = mode;
+ addListenerCommand->connectionType = type;
+ addListenerCommand->port = htons((uint16_t)atoi(port));
+ strcpy(addListenerCommand->symbolic, symbolic);
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, ADD_LISTENER, addListenerCommand, sizeof(add_listener_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddListener_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 5 && parcList_Size(args) != 6) {
+ _controlAddListener_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ CommandReturn result = CommandReturn_Failure;
+
+ const char *symbolic = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolic)) {
+ printf(
+ "Error: symbolic name must begin with an alpha and be alphanum "
+ "after\n");
+ return result;
+ }
+
+ const char *host = parcList_GetAtIndex(args, _indexAddress);
+ const char *protocol = parcList_GetAtIndex(args, _indexProtocol);
+
+ if ((strcasecmp("hicn", protocol) == 0)) {
+ const char *port =
+ "1234"; // this is a random port number that will be ignored
+
+ // here we discard the prefix len if it exists, since we don't use it in
+ // code but we let libhicn to find the right ip address.
+ return _CreateListener(parser, ops, symbolic, host, port, HICN_MODE,
+ HICN_CONN);
+ }
+
+ const char *port = parcList_GetAtIndex(args, _indexPort);
+
+ if ((strcasecmp("udp", protocol) == 0)) {
+ return _CreateListener(parser, ops, symbolic, host, port, IP_MODE,
+ UDP_CONN);
+ } else if ((strcasecmp("tcp", protocol) == 0)) {
+ return _CreateListener(parser, ops, symbolic, host, port, IP_MODE,
+ TCP_CONN);
+ } else {
+ _controlAddListener_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ if (result == CommandReturn_Failure) printf("creation failed\n");
+
+ return result;
+}
diff --git a/hicn-light/src/config/controlAddListener.h b/hicn-light/src/config/controlAddListener.h
new file mode 100755
index 0000000..d3fc55a
--- /dev/null
+++ b/hicn-light/src/config/controlAddListener.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_AddListener.h
+ * @brief Add a listener to an interface
+ *
+ * <#Detailed Description#>
+ *
+ */
+
+#ifndef Control_AddListener_h
+#define Control_AddListener_h
+
+#include <src/config/controlState.h>
+CommandOps *controlAddListener_Create(ControlState *state);
+CommandOps *controlAddListener_HelpCreate(ControlState *state);
+#endif // Control_AddListener_h
diff --git a/hicn-light/src/config/controlAddPunting.c b/hicn-light/src/config/controlAddPunting.c
new file mode 100755
index 0000000..bd87e51
--- /dev/null
+++ b/hicn-light/src/config/controlAddPunting.c
@@ -0,0 +1,154 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+#include <src/utils/punting.h>
+
+#include <src/config/controlAddPunting.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlAddPunting_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddPunting_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandAddPunting = "add punting";
+static const char *_commandAddPuntingHelp = "help add punting";
+
+static const int _indexSymbolic = 2;
+static const int _indexPrefix = 3;
+
+CommandOps *controlAddPunting_Create(ControlState *state) {
+ return commandOps_Create(state, _commandAddPunting, NULL,
+ _controlAddPunting_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAddPunting_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddPuntingHelp, NULL,
+ _controlAddPunting_HelpExecute, commandOps_Destroy);
+}
+
+// =====================================================
+
+static CommandReturn _controlAddPunting_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("add punting <symbolic> <prefix>\n");
+ printf(" <symbolic> : listener symbolic name\n");
+ printf(
+ " <address> : prefix to add as a punting rule. (example "
+ "1234::0/64)\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddPunting_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 4) {
+ _controlAddPunting_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\n"
+ "symbolic name must begin with an alpha followed by alphanum;\nconnid "
+ "must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ const char *prefixStr = parcList_GetAtIndex(args, _indexPrefix);
+ char addr[strlen(prefixStr) + 1];
+
+ // separate address and len
+ char *slash;
+ uint32_t len = 0;
+ strcpy(addr, prefixStr);
+ slash = strrchr(addr, '/');
+ if (slash != NULL) {
+ len = atoi(slash + 1);
+ *slash = '\0';
+ }
+
+ if (len == 0) {
+ printf("ERROR: a prefix can not be of length 0\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ add_punting_command *addPuntingCommand =
+ parcMemory_AllocateAndClear(sizeof(add_punting_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &addPuntingCommand->address.ipv4) == 1) {
+ if (len > 32) {
+ printf("ERROR: exceeded INET mask length, max=32\n");
+ parcMemory_Deallocate(&addPuntingCommand);
+ return CommandReturn_Failure;
+ }
+ addPuntingCommand->addressType = ADDR_INET;
+ } else if (inet_pton(AF_INET6, addr, &addPuntingCommand->address.ipv6) == 1) {
+ if (len > 128) {
+ printf("ERROR: exceeded INET6 mask length, max=128\n");
+ parcMemory_Deallocate(&addPuntingCommand);
+ return CommandReturn_Failure;
+ }
+ addPuntingCommand->addressType = ADDR_INET6;
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&addPuntingCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ addPuntingCommand->len = len;
+ strcpy(addPuntingCommand->symbolicOrConnid, symbolicOrConnid);
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, ADD_PUNTING, addPuntingCommand, sizeof(add_punting_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlAddPunting.h b/hicn-light/src/config/controlAddPunting.h
new file mode 100755
index 0000000..e4d4aac
--- /dev/null
+++ b/hicn-light/src/config/controlAddPunting.h
@@ -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.
+ */
+
+#ifndef controlAddPunting_h
+#define controlAddPunting_h
+
+#include <src/config/controlState.h>
+CommandOps *controlAddPunting_Create(ControlState *state);
+CommandOps *controlAddPunting_HelpCreate(ControlState *state);
+#endif
diff --git a/hicn-light/src/config/controlAddRoute.c b/hicn-light/src/config/controlAddRoute.c
new file mode 100755
index 0000000..c5ddab5
--- /dev/null
+++ b/hicn-light/src/config/controlAddRoute.c
@@ -0,0 +1,157 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/config/controlAddRoute.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlAddRoute_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlAddRoute_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandAddRoute = "add route";
+static const char *_commandAddRouteHelp = "help add route";
+
+CommandOps *controlAddRoute_Create(ControlState *state) {
+ return commandOps_Create(state, _commandAddRoute, NULL,
+ _controlAddRoute_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAddRoute_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddRouteHelp, NULL,
+ _controlAddRoute_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlAddRoute_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("commands:\n");
+ printf(" add route <symbolic | connid> <prefix> <cost>\n");
+ printf("\n");
+ printf(" symbolic: The symbolic name for an exgress\n");
+ printf(
+ " connid: The egress connection id (see 'help list connections')\n");
+ printf(
+ " prefix: The hicn name as IPv4 or IPv6 address (e.g 1234::0/64)\n");
+ printf(" cost: positive integer representing cost\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddRoute_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 5) {
+ _controlAddRoute_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, 2);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an "
+ "alpha followed by alphanum;\nconnid must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ unsigned cost = atoi(parcList_GetAtIndex(args, 4));
+
+ if (cost == 0) {
+ printf("ERROR: cost must be positive integer, got %u from '%s'\n", cost,
+ (char *)parcList_GetAtIndex(args, 4));
+ return CommandReturn_Failure;
+ }
+
+ const char *prefixStr = parcList_GetAtIndex(args, 3);
+ char addr[strlen(prefixStr) + 1];
+
+ // separate address and len
+ char *slash;
+ uint32_t len = 0;
+ strcpy(addr, prefixStr);
+ slash = strrchr(addr, '/');
+ if (slash != NULL) {
+ len = atoi(slash + 1);
+ *slash = '\0';
+ }
+
+ if (len == 0) {
+ printf("ERROR: a prefix can not be of length 0\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ add_route_command *addRouteCommand =
+ parcMemory_AllocateAndClear(sizeof(add_route_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &addRouteCommand->address.ipv4) == 1) {
+ if (len > 32) {
+ printf("ERROR: exceeded INET mask length, max=32\n");
+ parcMemory_Deallocate(&addRouteCommand);
+ return CommandReturn_Failure;
+ }
+ addRouteCommand->addressType = ADDR_INET;
+ } else if (inet_pton(AF_INET6, addr, &addRouteCommand->address.ipv6) == 1) {
+ if (len > 128) {
+ printf("ERROR: exceeded INET6 mask length, max=128\n");
+ parcMemory_Deallocate(&addRouteCommand);
+ return CommandReturn_Failure;
+ }
+ addRouteCommand->addressType = ADDR_INET6;
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&addRouteCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ addRouteCommand->len = len;
+ addRouteCommand->cost = (uint16_t)cost;
+ strcpy(addRouteCommand->symbolicOrConnid, symbolicOrConnid);
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, ADD_ROUTE, addRouteCommand,
+ sizeof(add_route_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlAddRoute.h b/hicn-light/src/config/controlAddRoute.h
new file mode 100755
index 0000000..be0ad13
--- /dev/null
+++ b/hicn-light/src/config/controlAddRoute.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_AddRoute.h
+ * @brief Add a static route
+ *
+ * Implements the "add route" node of the CLI tree
+ *
+ */
+
+#ifndef Control_AddRoute_h
+#define Control_AddRoute_h
+
+#include <src/config/controlState.h>
+CommandOps *controlAddRoute_Create(ControlState *state);
+CommandOps *controlAddRoute_HelpCreate(ControlState *state);
+#endif // Control_AddRoute_h
diff --git a/hicn-light/src/config/controlCache.c b/hicn-light/src/config/controlCache.c
new file mode 100755
index 0000000..d7afbfe
--- /dev/null
+++ b/hicn-light/src/config/controlCache.c
@@ -0,0 +1,91 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlCache.h>
+#include <src/config/controlCacheClear.h>
+#include <src/config/controlCacheServe.h>
+#include <src/config/controlCacheStore.h>
+
+static void _controlCache_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlCache_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlCache_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandCache = "cache";
+static const char *_commandCacheHelp = "help cache";
+
+CommandOps *controlCache_Create(ControlState *state) {
+ return commandOps_Create(state, _commandCache, _controlCache_Init,
+ _controlCache_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlCache_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandCacheHelp, NULL,
+ _controlCache_HelpExecute, commandOps_Destroy);
+}
+
+// =====================================================
+
+static CommandReturn _controlCache_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ CommandOps *ops_cache_serve = controlCacheServe_HelpCreate(NULL);
+ CommandOps *ops_cache_store = controlCacheStore_HelpCreate(NULL);
+ CommandOps *ops_cache_clear = controlCacheClear_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_cache_serve->command);
+ printf(" %s\n", ops_cache_store->command);
+ printf(" %s\n", ops_cache_clear->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_cache_serve);
+ commandOps_Destroy(&ops_cache_store);
+ commandOps_Destroy(&ops_cache_clear);
+
+ return CommandReturn_Success;
+}
+
+static void _controlCache_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlCacheServe_HelpCreate(state));
+ controlState_RegisterCommand(state, controlCacheStore_HelpCreate(state));
+ controlState_RegisterCommand(state, controlCacheClear_HelpCreate(state));
+ controlState_RegisterCommand(state, controlCacheServe_Create(state));
+ controlState_RegisterCommand(state, controlCacheStore_Create(state));
+ controlState_RegisterCommand(state, controlCacheClear_Create(state));
+}
+
+static CommandReturn _controlCache_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlCache_HelpExecute(parser, ops, args);
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlCache.h b/hicn-light/src/config/controlCache.h
new file mode 100755
index 0000000..a3614fc
--- /dev/null
+++ b/hicn-light/src/config/controlCache.h
@@ -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.
+ */
+
+#ifndef controlCache_h
+#define controlCache_h
+
+#include <src/config/controlState.h>
+CommandOps *controlCache_Create(ControlState *state);
+CommandOps *controlCache_HelpCreate(ControlState *state);
+#endif // controlCache_h
diff --git a/hicn-light/src/config/controlCacheClear.c b/hicn-light/src/config/controlCacheClear.c
new file mode 100755
index 0000000..c5a4e9f
--- /dev/null
+++ b/hicn-light/src/config/controlCacheClear.c
@@ -0,0 +1,84 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlCacheClear.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlCacheClear_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlCacheClear_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandCacheClear = "cache clear";
+static const char *_commandCacheClearHelp = "help cache clear";
+
+// ====================================================
+
+CommandOps *controlCacheClear_Create(ControlState *state) {
+ return commandOps_Create(state, _commandCacheClear, NULL,
+ _controlCacheClear_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlCacheClear_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandCacheClearHelp, NULL,
+ _controlCacheClear_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlCacheClear_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("cache clear\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlCacheClear_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlCacheClear_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, CACHE_CLEAR, NULL, 0);
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlCacheClear.h b/hicn-light/src/config/controlCacheClear.h
new file mode 100755
index 0000000..348ddba
--- /dev/null
+++ b/hicn-light/src/config/controlCacheClear.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file controlCacheClear.h
+ * @brief Clear the cache
+ *
+ * Removes all the cached data form the local content store (if available)
+ *
+ */
+
+#ifndef Control_CacheClear_h
+#define Control_CacheClear_h
+
+#include <src/config/controlState.h>
+CommandOps *controlCacheClear_Create(ControlState *state);
+CommandOps *controlCacheClear_HelpCreate(ControlState *state);
+#endif // Control_CacheClear_h
diff --git a/hicn-light/src/config/controlCacheServe.c b/hicn-light/src/config/controlCacheServe.c
new file mode 100755
index 0000000..85d5980
--- /dev/null
+++ b/hicn-light/src/config/controlCacheServe.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlCacheServe.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlCacheServe_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlCacheServe_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandCacheServe = "cache serve";
+static const char *_commandCacheServeHelp = "help cache serve";
+
+// ====================================================
+
+CommandOps *controlCacheServe_Create(ControlState *state) {
+ return commandOps_Create(state, _commandCacheServe, NULL,
+ _controlCacheServe_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlCacheServe_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandCacheServeHelp, NULL,
+ _controlCacheServe_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlCacheServe_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("cache serve [on|off]\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlCacheServe_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlCacheServe_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlCacheServe_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ cache_serve_command *cacheServeCommand =
+ parcMemory_AllocateAndClear(sizeof(cache_serve_command));
+ if (active) {
+ cacheServeCommand->activate = ACTIVATE_ON;
+ } else {
+ cacheServeCommand->activate = ACTIVATE_OFF;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, CACHE_SERVE, cacheServeCommand, sizeof(cache_serve_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlCacheServe.h b/hicn-light/src/config/controlCacheServe.h
new file mode 100755
index 0000000..4bcec51
--- /dev/null
+++ b/hicn-light/src/config/controlCacheServe.h
@@ -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.
+ */
+
+#ifndef Control_CacheServe_h
+#define Control_CacheServe_h
+
+#include <src/config/controlState.h>
+CommandOps *controlCacheServe_Create(ControlState *state);
+CommandOps *controlCacheServe_HelpCreate(ControlState *state);
+#endif // Control_CacheServe_h
diff --git a/hicn-light/src/config/controlCacheStore.c b/hicn-light/src/config/controlCacheStore.c
new file mode 100755
index 0000000..3bbb343
--- /dev/null
+++ b/hicn-light/src/config/controlCacheStore.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlCacheStore.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlCacheStore_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlCacheStore_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandCacheStore = "cache store";
+static const char *_commandCacheStoreHelp = "help cache store";
+
+// ====================================================
+
+CommandOps *controlCacheStore_Create(ControlState *state) {
+ return commandOps_Create(state, _commandCacheStore, NULL,
+ _controlCacheStore_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlCacheStore_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandCacheStoreHelp, NULL,
+ _controlCacheStore_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlCacheStore_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("cache store [on|off]\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlCacheStore_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlCacheStore_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlCacheStore_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ cache_store_command *cacheStoreCommand =
+ parcMemory_AllocateAndClear(sizeof(cache_store_command));
+ if (active) {
+ cacheStoreCommand->activate = ACTIVATE_ON;
+ } else {
+ cacheStoreCommand->activate = ACTIVATE_OFF;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, CACHE_STORE, cacheStoreCommand, sizeof(cache_store_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlCacheStore.h b/hicn-light/src/config/controlCacheStore.h
new file mode 100755
index 0000000..ef5aca5
--- /dev/null
+++ b/hicn-light/src/config/controlCacheStore.h
@@ -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.
+ */
+
+#ifndef Control_CacheStore_h
+#define Control_CacheStore_h
+
+#include <src/config/controlState.h>
+CommandOps *controlCacheStore_Create(ControlState *state);
+CommandOps *controlCacheStore_HelpCreate(ControlState *state);
+#endif // Control_CacheStore_h
diff --git a/hicn-light/src/config/controlList.c b/hicn-light/src/config/controlList.c
new file mode 100755
index 0000000..8afaa60
--- /dev/null
+++ b/hicn-light/src/config/controlList.c
@@ -0,0 +1,97 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlList.h>
+#include <src/config/controlListConnections.h>
+//#include <src/config/controlListInterfaces.h>
+#include <src/config/controlListListeners.h>
+#include <src/config/controlListRoutes.h>
+
+static void _controlList_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlList_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlList_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandList = "list";
+static const char *_commandListHelp = "help list";
+
+CommandOps *controlList_Create(ControlState *state) {
+ return commandOps_Create(state, _commandList, _controlList_Init,
+ _controlList_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlList_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListHelp, NULL,
+ _controlList_HelpExecute, commandOps_Destroy);
+}
+
+// =====================================================
+
+static CommandReturn _controlList_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ CommandOps *ops_list_connections = controlListConnections_HelpCreate(NULL);
+ // CommandOps *ops_list_interfaces = controlListInterfaces_HelpCreate(NULL);
+ CommandOps *ops_list_routes = controlListRoutes_HelpCreate(NULL);
+ CommandOps *ops_list_listeners = controlListListeners_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_list_connections->command);
+ // printf(" %s\n", ops_list_interfaces->command);
+ printf(" %s\n", ops_list_routes->command);
+ printf(" %s\n", ops_list_listeners->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_list_connections);
+ // commandOps_Destroy(&ops_list_interfaces);
+ commandOps_Destroy(&ops_list_routes);
+ commandOps_Destroy(&ops_list_listeners);
+
+ return CommandReturn_Success;
+}
+
+static void _controlList_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlListConnections_HelpCreate(state));
+ // controlState_RegisterCommand(state,
+ // controlListInterfaces_HelpCreate(state));
+ controlState_RegisterCommand(state, controlListListeners_HelpCreate(state));
+ controlState_RegisterCommand(state, controlListRoutes_HelpCreate(state));
+ controlState_RegisterCommand(state, controlListConnections_Create(state));
+ // controlState_RegisterCommand(state, controlListInterfaces_Create(state));
+ controlState_RegisterCommand(state, controlListRoutes_Create(state));
+ controlState_RegisterCommand(state, controlListListeners_Create(state));
+}
+
+static CommandReturn _controlList_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlList_HelpExecute(parser, ops, args);
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlList.h b/hicn-light/src/config/controlList.h
new file mode 100755
index 0000000..5319733
--- /dev/null
+++ b/hicn-light/src/config/controlList.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_List.h
+ * @brief Root node for the "list" commands
+ *
+ * Implements the "list" node of the CLI tree.
+ *
+ */
+
+#ifndef controlList_h
+#define controlList_h
+
+#include <src/config/controlState.h>
+CommandOps *controlList_Create(ControlState *state);
+CommandOps *controlList_HelpCreate(ControlState *state);
+#endif // controlList_h
diff --git a/hicn-light/src/config/controlListConnections.c b/hicn-light/src/config/controlListConnections.c
new file mode 100755
index 0000000..474ddc4
--- /dev/null
+++ b/hicn-light/src/config/controlListConnections.c
@@ -0,0 +1,160 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlListConnections.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlListConnections_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlListConnections_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandListConnections = "list connections";
+static const char *_commandListConnectionsHelp = "help list connections";
+const char *connTypeString[6] = {"GRE", "TCP", "UDP", "MCAST", "L2", "HICN"};
+const char *stateString[3] = {"UP", "DOWN", "UNKNOWN"};
+
+CommandOps *controlListConnections_Create(ControlState *state) {
+ return commandOps_Create(state, _commandListConnections, NULL,
+ _controlListConnections_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlListConnections_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListConnectionsHelp, NULL,
+ _controlListConnections_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlListConnections_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("list connections: displays a 1-line summary of each connection\n");
+ printf("\n");
+ printf("The columns are:\n");
+ printf(" connection id : an integer index for the connection\n");
+ printf(" state : UP or DOWN\n");
+ printf(
+ " local address : the local network address associated with the "
+ "connection\n");
+ printf(
+ " remote address: the remote network address associated with the "
+ "connection\n");
+ printf(
+ " protocol : the network protocol (tcp, udp, gre, mcast, "
+ "ether)\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlListConnections_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlListConnections_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, LIST_CONNECTIONS, NULL, 0);
+ if (!response) { // get NULL pointer = FAILURE
+ return CommandReturn_Failure;
+ }
+
+ // Process/Print message
+ header_control_message *receivedHeader =
+ (header_control_message *)response[0].iov_base;
+ uint8_t *receivedPayload = (uint8_t *)response[1].iov_base;
+
+ char *sourceString = NULL;
+ char *destinationString = NULL;
+
+ // Allocate output to pass to the main function if the call is not interactive
+ char **commandOutputMain = NULL;
+ if (!controlState_IsInteractive(state) && receivedHeader->length > 0) {
+ commandOutputMain =
+ parcMemory_Allocate(sizeof(char *) * receivedHeader->length);
+ for (size_t j = 0; j < receivedHeader->length; j++) {
+ commandOutputMain[j] = parcMemory_Allocate(sizeof(char) * 128);
+ }
+ }
+
+ // Process/Print payload
+ for (int i = 0; i < receivedHeader->length; i++) {
+ list_connections_command *listConnectionsCommand =
+ (list_connections_command *)(receivedPayload +
+ (i * sizeof(list_connections_command)));
+
+ sourceString = utils_CommandAddressToString(
+ listConnectionsCommand->connectionData.ipType,
+ &listConnectionsCommand->connectionData.localIp,
+ &listConnectionsCommand->connectionData.localPort);
+
+ destinationString = utils_CommandAddressToString(
+ listConnectionsCommand->connectionData.ipType,
+ &listConnectionsCommand->connectionData.remoteIp,
+ &listConnectionsCommand->connectionData.remotePort);
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+
+ parcBufferComposer_Format(
+ composer, "%5d %4s %s %s %s", listConnectionsCommand->connid,
+ stateString[listConnectionsCommand->state], sourceString,
+ destinationString,
+ connTypeString[listConnectionsCommand->connectionData.connectionType]);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+
+ if (!controlState_IsInteractive(state)) {
+ strcpy(commandOutputMain[i], result);
+ }
+
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+ }
+
+ controlState_SetCommandOutput(state, commandOutputMain);
+
+ // DEALLOCATE
+ parcMemory_Deallocate((void **)&sourceString);
+ parcMemory_Deallocate((void **)&destinationString);
+ parcMemory_Deallocate(&receivedHeader); // free response[0].iov_base
+ parcMemory_Deallocate(&receivedPayload); // free response[1].iov_base
+ parcMemory_Deallocate(&response); // free iovec pointer
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlListConnections.h b/hicn-light/src/config/controlListConnections.h
new file mode 100755
index 0000000..17422c9
--- /dev/null
+++ b/hicn-light/src/config/controlListConnections.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_ListConnections.h
+ * @brief List the current connections of hicn-light
+ *
+ * Implements the "list connections" node of the CLI tree
+ *
+ */
+
+#ifndef Control_ListConnections_h
+#define Control_ListConnections_h
+
+#include <src/config/controlState.h>
+CommandOps *controlListConnections_Create(ControlState *state);
+CommandOps *controlListConnections_HelpCreate(ControlState *state);
+#endif // Control_ListConnections_h
diff --git a/hicn-light/src/config/controlListInterfaces.c b/hicn-light/src/config/controlListInterfaces.c
new file mode 100755
index 0000000..20338b5
--- /dev/null
+++ b/hicn-light/src/config/controlListInterfaces.c
@@ -0,0 +1,76 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlListInterfaces.h>
+
+static CommandReturn _controlListInterfaces_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlListInterfaces_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandListInterfaces = "list interfaces";
+static const char *_commandListInterfacesHelp = "help list interfaces";
+
+// ====================================================
+
+CommandOps *controlListInterfaces_Create(ControlState *state) {
+ return commandOps_Create(state, _commandListInterfaces, NULL,
+ _controlListInterfaces_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlListInterfaces_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListInterfacesHelp, NULL,
+ _controlListInterfaces_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlListInterfaces_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("list interfaces\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlListInterfaces_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlListInterfaces_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ //========================== NOT IMPLEMENTED
+ //===========================
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlListInterfaces.h b/hicn-light/src/config/controlListInterfaces.h
new file mode 100755
index 0000000..0c0ca95
--- /dev/null
+++ b/hicn-light/src/config/controlListInterfaces.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_ListInterfaces.h
+ * @brief List the icn-light interfaces
+ *
+ * Implements the "list interfaces" and "help list interfaces" nodes of the
+ * command tree
+ *
+ */
+
+#ifndef Control_ListInterfaces_h
+#define Control_ListInterfaces_h
+
+#include <src/config/controlState.h>
+CommandOps *controlListInterfaces_Create(ControlState *state);
+CommandOps *controlListInterfaces_HelpCreate(ControlState *state);
+#endif // Control_ListInterfaces_h
diff --git a/hicn-light/src/config/controlListListeners.c b/hicn-light/src/config/controlListListeners.c
new file mode 100755
index 0000000..a149051
--- /dev/null
+++ b/hicn-light/src/config/controlListListeners.c
@@ -0,0 +1,141 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+
+#include <src/config/controlListListeners.h>
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlListListeners_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlListListeners_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandListListeners = "list listeners";
+static const char *_commandListListenersHelp = "help list listeners";
+static const char *listenerType[5] = {"TCP", "UDP", "ETHER", "LOCAL", "HICN"};
+
+// ====================================================
+
+CommandOps *controlListListeners_Create(ControlState *state) {
+ return commandOps_Create(state, _commandListListeners, NULL,
+ _controlListListeners_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlListListeners_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListListenersHelp, NULL,
+ _controlListListeners_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlListListeners_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("list listeners\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlListListeners_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlListListeners_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, LIST_LISTENERS, NULL, 0);
+ if (!response) { // get NULL pointer = FAILURE
+ return CommandReturn_Failure;
+ }
+
+ // Process/Print message
+ header_control_message *receivedHeader =
+ (header_control_message *)response[0].iov_base;
+ uint8_t *receivedPayload = (uint8_t *)response[1].iov_base;
+
+ // Allocate output to pass to the main function if the call is not interactive
+ char **commandOutputMain = NULL;
+ if (!controlState_IsInteractive(state) && receivedHeader->length > 0) {
+ commandOutputMain =
+ parcMemory_Allocate(sizeof(char *) * receivedHeader->length);
+ for (size_t j = 0; j < receivedHeader->length; j++) {
+ commandOutputMain[j] = parcMemory_Allocate(sizeof(char) * 128);
+ }
+ }
+
+ char *addrString = NULL;
+ if (receivedHeader->length > 0) {
+ printf("%6.6s %50.70s %s\n", "iface", "address", "type");
+ } else {
+ printf(" --- No entry in the list \n");
+ }
+
+ for (int i = 0; i < receivedHeader->length; i++) {
+ list_listeners_command *listListenersCommand =
+ (list_listeners_command *)(receivedPayload +
+ (i * sizeof(list_listeners_command)));
+
+ addrString = utils_CommandAddressToString(listListenersCommand->addressType,
+ &listListenersCommand->address,
+ &listListenersCommand->port);
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+
+ parcBufferComposer_Format(composer, "%6u %50.70s %3s",
+ listListenersCommand->connid, addrString,
+ listenerType[listListenersCommand->encapType]);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+
+ if (!controlState_IsInteractive(state)) {
+ strcpy(commandOutputMain[i], result);
+ }
+
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+ }
+
+ controlState_SetCommandOutput(state, commandOutputMain);
+
+ // DEALLOCATE
+ parcMemory_Deallocate((void **)&addrString);
+ parcMemory_Deallocate(&receivedHeader); // free response[0].iov_base
+ parcMemory_Deallocate(&receivedPayload); // free response[1].iov_base
+ parcMemory_Deallocate(&response); // free iovec pointer
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlListListeners.h b/hicn-light/src/config/controlListListeners.h
new file mode 100755
index 0000000..1f34eea
--- /dev/null
+++ b/hicn-light/src/config/controlListListeners.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_ListListeners.h
+ * @brief List the icn-light listeners
+ *
+ * Implements the "list listeners" and "help list listeners" nodes of the
+ * command tree
+ *
+ */
+
+#ifndef Control_ListListeners_h
+#define Control_ListListeners_h
+
+#include <src/config/controlState.h>
+CommandOps *controlListListeners_Create(ControlState *state);
+CommandOps *controlListListeners_HelpCreate(ControlState *state);
+#endif // Control_ListListeners_h
diff --git a/hicn-light/src/config/controlListRoutes.c b/hicn-light/src/config/controlListRoutes.c
new file mode 100755
index 0000000..4a21b5e
--- /dev/null
+++ b/hicn-light/src/config/controlListRoutes.c
@@ -0,0 +1,154 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Time.h>
+
+#include <src/config/controlListRoutes.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlListRoutes_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlListRoutes_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandListRoutes = "list routes";
+static const char *_commandListRoutesHelp = "help list routes";
+
+// ====================================================
+
+CommandOps *controlListRoutes_Create(ControlState *state) {
+ return commandOps_Create(state, _commandListRoutes, NULL,
+ _controlListRoutes_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlListRoutes_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListRoutesHelp, NULL,
+ _controlListRoutes_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlListRoutes_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("command: list routes\n");
+ printf("\n");
+ printf(
+ "This command will fetch the prefix routing table. For each route, it "
+ "will list:\n");
+ printf(" iface: interface\n");
+ printf(
+ " protocol: the routing protocol, such as STATIC, CONNECTED, etc.\n");
+ printf(
+ " type: LMP or EXACT (longest matching prefix or exact match)\n");
+ printf(" cost: The route cost, lower being preferred\n");
+ printf(" next: List of next hops by interface id\n");
+ printf(" prefix: name prefix\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlListRoutes_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlListRoutes_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, LIST_ROUTES, NULL, 0);
+ if (!response) { // get NULL pointer = FAILURE
+ return CommandReturn_Failure;
+ }
+
+ // Process/Print message
+ header_control_message *receivedHeader =
+ (header_control_message *)response[0].iov_base;
+ uint8_t *receivedPayload = (uint8_t *)response[1].iov_base;
+
+ // Allocate output to pass to the main function if the call is not interactive
+ char **commandOutputMain = NULL;
+ if (!controlState_IsInteractive(state) && receivedHeader->length > 0) {
+ commandOutputMain =
+ parcMemory_Allocate(sizeof(char *) * receivedHeader->length);
+ for (size_t j = 0; j < receivedHeader->length; j++) {
+ commandOutputMain[j] = parcMemory_Allocate(sizeof(char) * 128);
+ }
+ }
+
+ char *addrString = NULL;
+ in_port_t port = htons(1234); // this is a random port number that is ignored
+
+ if (receivedHeader->length > 0) {
+ printf("%6.6s %8.8s %70.70s %s\n", "iface", "cost", "prefix", "len");
+ } else {
+ printf(" --- No entry in the list \n");
+ }
+
+ for (int i = 0; i < receivedHeader->length; i++) {
+ list_routes_command *listRoutesCommand =
+ (list_routes_command *)(receivedPayload +
+ (i * sizeof(list_routes_command)));
+
+ addrString = utils_CommandAddressToString(
+ listRoutesCommand->addressType, &listRoutesCommand->address, &port);
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+
+ parcBufferComposer_Format(
+ composer, "%6u %8u %70.70s %3d", listRoutesCommand->connid,
+ listRoutesCommand->cost, addrString, listRoutesCommand->len);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+
+ if (!controlState_IsInteractive(state)) {
+ strcpy(commandOutputMain[i], result);
+ }
+
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+ }
+
+ controlState_SetCommandOutput(state, commandOutputMain);
+
+ // DEALLOCATE
+ parcMemory_Deallocate((void **)&addrString);
+ parcMemory_Deallocate(&receivedHeader); // free response[0].iov_base
+ parcMemory_Deallocate(&receivedPayload); // free response[1].iov_base
+ parcMemory_Deallocate(&response); // free iovec pointer
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlListRoutes.h b/hicn-light/src/config/controlListRoutes.h
new file mode 100755
index 0000000..018c88a
--- /dev/null
+++ b/hicn-light/src/config/controlListRoutes.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.
+ */
+
+/**
+ * @file control_ListRoutes.h
+ * @brief List the icn-light routes
+ *
+ * Implements the "list routes" and "help list routes" nodes of the command tree
+ *
+ */
+#ifndef Control_ListRoutes_h
+#define Control_ListRoutes_h
+
+#include <src/config/controlState.h>
+CommandOps *controlListRoutes_Create(ControlState *state);
+CommandOps *controlListRoutes_HelpCreate(ControlState *state);
+#endif // Control_ListRoutes_h
diff --git a/hicn-light/src/config/controlMapMe.c b/hicn-light/src/config/controlMapMe.c
new file mode 100755
index 0000000..2253f52
--- /dev/null
+++ b/hicn-light/src/config/controlMapMe.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+
+#include <src/config/controlMapMe.h>
+#include <src/config/controlMapMeDiscovery.h>
+#include <src/config/controlMapMeEnable.h>
+#include <src/config/controlMapMeRetx.h>
+#include <src/config/controlMapMeTimescale.h>
+
+static void _controlMapMe_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlMapMe_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlMapMe_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandMapMe = "mapme";
+static const char *_commandMapMeHelp = "help mapme";
+
+CommandOps *controlMapMe_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMe, _controlMapMe_Init,
+ _controlMapMe_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMe_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeHelp, NULL,
+ _controlMapMe_HelpExecute, commandOps_Destroy);
+}
+
+// =====================================================
+
+static CommandReturn _controlMapMe_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ CommandOps *ops_mapme_enable = controlMapMeEnable_HelpCreate(NULL);
+ CommandOps *ops_mapme_discovery = controlMapMeDiscovery_HelpCreate(NULL);
+ CommandOps *ops_mapme_timescale = controlMapMeTimescale_HelpCreate(NULL);
+ CommandOps *ops_mapme_retx = controlMapMeRetx_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_mapme_enable->command);
+ printf(" %s\n", ops_mapme_discovery->command);
+ printf(" %s\n", ops_mapme_timescale->command);
+ printf(" %s\n", ops_mapme_retx->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_mapme_enable);
+ commandOps_Destroy(&ops_mapme_discovery);
+ commandOps_Destroy(&ops_mapme_timescale);
+ commandOps_Destroy(&ops_mapme_retx);
+
+ return CommandReturn_Success;
+}
+
+static void _controlMapMe_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlMapMeEnable_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMeDiscovery_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMeTimescale_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMeRetx_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMeEnable_Create(state));
+ controlState_RegisterCommand(state, controlMapMeDiscovery_Create(state));
+ controlState_RegisterCommand(state, controlMapMeTimescale_Create(state));
+ controlState_RegisterCommand(state, controlMapMeRetx_Create(state));
+}
+
+static CommandReturn _controlMapMe_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlMapMe_HelpExecute(parser, ops, args);
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlMapMe.h b/hicn-light/src/config/controlMapMe.h
new file mode 100755
index 0000000..d9cfdb8
--- /dev/null
+++ b/hicn-light/src/config/controlMapMe.h
@@ -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.
+ */
+
+#ifndef controlMapMe_h
+#define controlMapMe_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMe_Create(ControlState *state);
+CommandOps *controlMapMe_HelpCreate(ControlState *state);
+#endif // controlMapMe_h
diff --git a/hicn-light/src/config/controlMapMeDiscovery.c b/hicn-light/src/config/controlMapMeDiscovery.c
new file mode 100755
index 0000000..f8f4bf0
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeDiscovery.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/controlMapMeDiscovery.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlMapMeDiscovery_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlMapMeDiscovery_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandMapMeDiscovery = "mapme discovery";
+static const char *_commandMapMeDiscoveryHelp = "help mapme discovery";
+
+// ====================================================
+
+CommandOps *controlMapMeDiscovery_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeDiscovery, NULL,
+ _controlMapMeDiscovery_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMeDiscovery_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeDiscoveryHelp, NULL,
+ _controlMapMeDiscovery_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlMapMeDiscovery_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("mapme discovery [on|off]\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlMapMeDiscovery_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlMapMeDiscovery_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlMapMeDiscovery_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ mapme_activator_command *mapmeDiscoveryCommand =
+ parcMemory_AllocateAndClear(sizeof(mapme_activator_command));
+ if (active) {
+ mapmeDiscoveryCommand->activate = ACTIVATE_ON;
+ } else {
+ mapmeDiscoveryCommand->activate = ACTIVATE_OFF;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response =
+ utils_SendRequest(state, MAPME_DISCOVERY, mapmeDiscoveryCommand,
+ sizeof(mapme_activator_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlMapMeDiscovery.h b/hicn-light/src/config/controlMapMeDiscovery.h
new file mode 100755
index 0000000..c492fa0
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeDiscovery.h
@@ -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.
+ */
+
+#ifndef Control_MapMeDiscovery_h
+#define Control_MapMeDiscovery_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMeDiscovery_Create(ControlState *state);
+CommandOps *controlMapMeDiscovery_HelpCreate(ControlState *state);
+#endif // Control_MapMeDiscovery_h
diff --git a/hicn-light/src/config/controlMapMeEnable.c b/hicn-light/src/config/controlMapMeEnable.c
new file mode 100755
index 0000000..db77450
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeEnable.c
@@ -0,0 +1,101 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/controlMapMeEnable.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlMapMeEnable_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlMapMeEnable_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandMapMeEnable = "mapme enable";
+static const char *_commandMapMeEnableHelp = "help mapme enable";
+
+// ====================================================
+
+CommandOps *controlMapMeEnable_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeEnable, NULL,
+ _controlMapMeEnable_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMeEnable_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeEnableHelp, NULL,
+ _controlMapMeEnable_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlMapMeEnable_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("mapme enable [on|off]\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlMapMeEnable_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlMapMeEnable_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlMapMeEnable_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ mapme_activator_command *mapmeEnableCommand =
+ parcMemory_AllocateAndClear(sizeof(mapme_activator_command));
+ if (active) {
+ mapmeEnableCommand->activate = ACTIVATE_ON;
+ } else {
+ mapmeEnableCommand->activate = ACTIVATE_OFF;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, MAPME_ENABLE, mapmeEnableCommand, sizeof(mapme_activator_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlMapMeEnable.h b/hicn-light/src/config/controlMapMeEnable.h
new file mode 100755
index 0000000..f7ca620
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeEnable.h
@@ -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.
+ */
+
+#ifndef Control_MapMeEnable_h
+#define Control_MapMeEnable_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMeEnable_Create(ControlState *state);
+CommandOps *controlMapMeEnable_HelpCreate(ControlState *state);
+#endif // Control_MapMeEnable_h
diff --git a/hicn-light/src/config/controlMapMeRetx.c b/hicn-light/src/config/controlMapMeRetx.c
new file mode 100755
index 0000000..bb16b88
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeRetx.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/controlMapMeRetx.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlMapMeRetx_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlMapMeRetx_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandMapMeRetx = "mapme retx";
+static const char *_commandMapMeRetxHelp = "help mapme retx";
+
+// ====================================================
+
+CommandOps *controlMapMeRetx_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeRetx, NULL,
+ _controlMapMeRetx_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMeRetx_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeRetxHelp, NULL,
+ _controlMapMeRetx_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlMapMeRetx_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("mapme retx <milliseconds>n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlMapMeRetx_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlMapMeRetx_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *rtx = parcList_GetAtIndex(args, 2);
+ if (!utils_IsNumber(rtx)) {
+ printf(
+ "ERROR: retransmission value (expressed in ms) must be a positive "
+ "integer \n");
+ return CommandReturn_Failure;
+ }
+
+ mapme_timing_command *mapmeRetxCommand =
+ parcMemory_AllocateAndClear(sizeof(mapme_timing_command));
+ mapmeRetxCommand->timePeriod = (unsigned)strtold(rtx, NULL);
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, MAPME_RETX, mapmeRetxCommand, sizeof(mapme_timing_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlMapMeRetx.h b/hicn-light/src/config/controlMapMeRetx.h
new file mode 100755
index 0000000..611bd36
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeRetx.h
@@ -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.
+ */
+
+#ifndef Control_MapMeRetx_h
+#define Control_MapMeRetx_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMeRetx_Create(ControlState *state);
+CommandOps *controlMapMeRetx_HelpCreate(ControlState *state);
+#endif // Control_MapMeRetx_h
diff --git a/hicn-light/src/config/controlMapMeTimescale.c b/hicn-light/src/config/controlMapMeTimescale.c
new file mode 100755
index 0000000..9303b4b
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeTimescale.c
@@ -0,0 +1,97 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/controlMapMeTimescale.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlMapMeTimescale_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlMapMeTimescale_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandMapMeTimescale = "mapme timescale";
+static const char *_commandMapMeTimescaleHelp = "help mapme timescale";
+
+// ====================================================
+
+CommandOps *controlMapMeTimescale_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeTimescale, NULL,
+ _controlMapMeTimescale_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMeTimescale_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeTimescaleHelp, NULL,
+ _controlMapMeTimescale_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlMapMeTimescale_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("mapme timescale <milliseconds>n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlMapMeTimescale_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlMapMeTimescale_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *ts = parcList_GetAtIndex(args, 2);
+ if (!utils_IsNumber(ts)) {
+ printf(
+ "ERROR: timescale value (expressed in ms) must be a positive integer "
+ "\n");
+ return CommandReturn_Failure;
+ }
+
+ mapme_timing_command *mapmeTimescaleCommand =
+ parcMemory_AllocateAndClear(sizeof(mapme_timing_command));
+ mapmeTimescaleCommand->timePeriod = (unsigned)strtold(ts, NULL);
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response =
+ utils_SendRequest(state, MAPME_TIMESCALE, mapmeTimescaleCommand,
+ sizeof(mapme_timing_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlMapMeTimescale.h b/hicn-light/src/config/controlMapMeTimescale.h
new file mode 100755
index 0000000..d4b3836
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeTimescale.h
@@ -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.
+ */
+
+#ifndef Control_MapMeTimescale_h
+#define Control_MapMeTimescale_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMeTimescale_Create(ControlState *state);
+CommandOps *controlMapMeTimescale_HelpCreate(ControlState *state);
+#endif // Control_MapMeTimescale_h
diff --git a/hicn-light/src/config/controlQuit.c b/hicn-light/src/config/controlQuit.c
new file mode 100755
index 0000000..635fe27
--- /dev/null
+++ b/hicn-light/src/config/controlQuit.c
@@ -0,0 +1,63 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_Security.h>
+
+#include <src/config/controlQuit.h>
+
+static CommandReturn _controlQuit_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlQuit_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandQuit = "quit";
+static const char *_commandQuitHelp = "help quit";
+
+// ====================================================
+
+CommandOps *controlQuit_Create(ControlState *state) {
+ return commandOps_Create(state, _commandQuit, NULL, _controlQuit_Execute,
+ commandOps_Destroy);
+}
+
+CommandOps *controlQuit_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandQuitHelp, NULL,
+ _controlQuit_HelpExecute, commandOps_Destroy);
+}
+
+// ==============================================
+
+static CommandReturn _controlQuit_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ printf("Exits the interactive control program\n\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlQuit_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ printf("exiting interactive shell\n");
+ return CommandReturn_Exit;
+}
diff --git a/hicn-light/src/config/controlQuit.h b/hicn-light/src/config/controlQuit.h
new file mode 100755
index 0000000..e2ba354
--- /dev/null
+++ b/hicn-light/src/config/controlQuit.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.
+ */
+
+/**
+ * @file control_Quit.h
+ * @brief The quit command
+ *
+ * Implements the "quit" and "help quit" nodes of the command tree
+ *
+ */
+#ifndef Control_Quit_h
+#define Control_Quit_h
+
+#include <src/config/controlState.h>
+CommandOps *controlQuit_Create(ControlState *state);
+CommandOps *controlQuit_HelpCreate(ControlState *state);
+#endif // Control_Quit_h
diff --git a/hicn-light/src/config/controlRemove.c b/hicn-light/src/config/controlRemove.c
new file mode 100755
index 0000000..ede075a
--- /dev/null
+++ b/hicn-light/src/config/controlRemove.c
@@ -0,0 +1,92 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlRemove.h>
+#include <src/config/controlRemoveConnection.h>
+#include <src/config/controlRemovePunting.h>
+#include <src/config/controlRemoveRoute.h>
+
+static void _controlRemove_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlRemove_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlRemove_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandRemove = "remove";
+static const char *_commandRemoveHelp = "help remove";
+
+// ====================================================
+
+CommandOps *controlRemove_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRemove, _controlRemove_Init,
+ _controlRemove_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlRemove_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveHelp, NULL,
+ _controlRemove_HelpExecute, commandOps_Destroy);
+}
+
+// ==============================================
+
+static CommandReturn _controlRemove_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ CommandOps *ops_remove_connection = controlRemoveConnection_Create(NULL);
+ CommandOps *ops_remove_route = controlRemoveRoute_Create(NULL);
+ CommandOps *ops_remove_punting = controlRemovePunting_Create(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_remove_connection->command);
+ printf(" %s\n", ops_remove_route->command);
+ printf(" %s\n", ops_remove_punting->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_remove_connection);
+ commandOps_Destroy(&ops_remove_route);
+ commandOps_Destroy(&ops_remove_punting);
+ return CommandReturn_Success;
+}
+
+static void _controlRemove_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state,
+ controlRemoveConnection_HelpCreate(state));
+ controlState_RegisterCommand(state, controlRemoveRoute_HelpCreate(state));
+ controlState_RegisterCommand(state, controlRemoveConnection_Create(state));
+ controlState_RegisterCommand(state, controlRemoveRoute_Create(state));
+ controlState_RegisterCommand(state, controlRemovePunting_Create(state));
+ controlState_RegisterCommand(state, controlRemovePunting_HelpCreate(state));
+}
+
+static CommandReturn _controlRemove_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlRemove_HelpExecute(parser, ops, args);
+}
diff --git a/hicn-light/src/config/controlRemove.h b/hicn-light/src/config/controlRemove.h
new file mode 100755
index 0000000..d75ecfe
--- /dev/null
+++ b/hicn-light/src/config/controlRemove.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.
+ */
+
+/**
+ * @file control_Remove.h
+ * @brief Implements the remove node of the CLI tree
+ *
+ * Implements the "remove" and "help remove" nodes of the command tree
+ *
+ */
+#ifndef controlRemove_h
+#define controlRemove_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRemove_Create(ControlState *state);
+CommandOps *controlRemove_HelpCreate(ControlState *state);
+#endif // controlRemove_h
diff --git a/hicn-light/src/config/controlRemoveConnection.c b/hicn-light/src/config/controlRemoveConnection.c
new file mode 100755
index 0000000..93365ad
--- /dev/null
+++ b/hicn-light/src/config/controlRemoveConnection.c
@@ -0,0 +1,115 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+#include <src/utils/address.h>
+
+#include <src/config/controlRemoveConnection.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlRemoveConnection_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlRemoveConnection_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static const char *_commandRemoveConnection = "remove connection";
+static const char *_commandRemoveConnectionHelp = "help remove connection";
+
+// ====================================================
+
+CommandOps *controlRemoveConnection_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveConnection, NULL,
+ _controlRemoveConnection_Execute,
+ commandOps_Destroy);
+}
+
+CommandOps *controlRemoveConnection_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveConnectionHelp, NULL,
+ _controlRemoveConnection_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlRemoveConnection_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("command:\n");
+ printf(" remove connection <symbolic|id>\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlRemoveConnection_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 3) {
+ _controlRemoveConnection_HelpExecute(parser, ops, args);
+ return false;
+ }
+
+ if ((strcmp(parcList_GetAtIndex(args, 0), "remove") != 0) ||
+ (strcmp(parcList_GetAtIndex(args, 1), "connection") != 0)) {
+ _controlRemoveConnection_HelpExecute(parser, ops, args);
+ return false;
+ }
+
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, 2);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an "
+ "alpha followed by alphanum;\nconnid must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ remove_connection_command *removeConnectionCommand =
+ parcMemory_AllocateAndClear(sizeof(remove_connection_command));
+ // fill payload
+ strcpy(removeConnectionCommand->symbolicOrConnid, symbolicOrConnid);
+
+ // send message and receive response
+ struct iovec *response =
+ utils_SendRequest(state, REMOVE_CONNECTION, removeConnectionCommand,
+ sizeof(remove_connection_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlRemoveConnection.h b/hicn-light/src/config/controlRemoveConnection.h
new file mode 100755
index 0000000..1dd1af2
--- /dev/null
+++ b/hicn-light/src/config/controlRemoveConnection.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_RemoveConnection.h
+ * @brief Remove a connection from the connection table
+ *
+ * Implements the "remove connection" and "help remove connection" nodes of the
+ * CLI tree
+ *
+ */
+
+#ifndef Control_RemoveConnection_h
+#define Control_RemoveConnection_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRemoveConnection_Create(ControlState *state);
+CommandOps *controlRemoveConnection_HelpCreate(ControlState *state);
+#endif // Control_RemoveConnection_h
diff --git a/hicn-light/src/config/controlRemovePunting.c b/hicn-light/src/config/controlRemovePunting.c
new file mode 100755
index 0000000..cf4c4fb
--- /dev/null
+++ b/hicn-light/src/config/controlRemovePunting.c
@@ -0,0 +1,76 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+#include <src/utils/address.h>
+
+#include <src/config/controlRemovePunting.h>
+
+static CommandReturn _controlRemovePunting_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlRemovePunting_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static const char *_commandRemovePunting = "remove punting";
+static const char *_commandRemovePuntingHelp = "help punting connection";
+
+// ====================================================
+
+CommandOps *controlRemovePunting_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRemovePunting, NULL,
+ _controlRemovePunting_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlRemovePunting_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRemovePuntingHelp, NULL,
+ _controlRemovePunting_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+// ====================================================
+
+static CommandReturn _controlRemovePunting_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("remove punting <symbolic> <prefix>\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlRemovePunting_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("command not implemented\n");
+ return _controlRemovePunting_HelpExecute(parser, ops, args);
+}
+
+// ==================================================
diff --git a/hicn-light/src/config/controlRemovePunting.h b/hicn-light/src/config/controlRemovePunting.h
new file mode 100755
index 0000000..89b1343
--- /dev/null
+++ b/hicn-light/src/config/controlRemovePunting.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.
+ */
+
+/**
+ * @file control_RemovePunting.h
+ *
+ */
+
+#ifndef Control_RemovePunting_h
+#define Control_RemovePunting_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRemovePunting_Create(ControlState *state);
+CommandOps *controlRemovePunting_HelpCreate(ControlState *state);
+#endif // Control_RemovePunting_h
diff --git a/hicn-light/src/config/controlRemoveRoute.c b/hicn-light/src/config/controlRemoveRoute.c
new file mode 100755
index 0000000..b9b4ed1
--- /dev/null
+++ b/hicn-light/src/config/controlRemoveRoute.c
@@ -0,0 +1,150 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/utils/address.h>
+
+#include <src/config/controlRemoveRoute.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlRemoveRoute_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlRemoveRoute_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static const char *_commandRemoveRoute = "remove route";
+static const char *_commandRemoveRouteHelp = "help remove route";
+
+// ====================================================
+
+CommandOps *controlRemoveRoute_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveRoute, NULL,
+ _controlRemoveRoute_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlRemoveRoute_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveRouteHelp, NULL,
+ _controlRemoveRoute_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlRemoveRoute_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("commands:\n");
+ printf(" remove route <symbolic | connid> <prefix>\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlRemoveRoute_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 4) {
+ _controlRemoveRoute_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, 2);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an "
+ "alpha followed by alphanum;\nconnid must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ const char *prefixStr = parcList_GetAtIndex(args, 3);
+ char addr[strlen(prefixStr) + 1];
+
+ // separate address and len
+ char *slash;
+ uint32_t len = 0;
+ strcpy(addr, prefixStr);
+ slash = strrchr(addr, '/');
+ if (slash != NULL) {
+ len = atoi(slash + 1);
+ *slash = '\0';
+ }
+
+ if (len == 0) {
+ printf("ERROR: a prefix can not be of length 0\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ remove_route_command *removeRouteCommand =
+ parcMemory_AllocateAndClear(sizeof(remove_route_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &removeRouteCommand->address.ipv4) == 1) {
+ if (len > 32) {
+ printf("ERROR: exceeded INET mask length, max=32\n");
+ parcMemory_Deallocate(&removeRouteCommand);
+ return CommandReturn_Failure;
+ }
+ removeRouteCommand->addressType = ADDR_INET;
+ } else if (inet_pton(AF_INET6, addr, &removeRouteCommand->address.ipv6) ==
+ 1) {
+ if (len > 128) {
+ printf("ERROR: exceeded INET6 mask length, max=128\n");
+ parcMemory_Deallocate(&removeRouteCommand);
+ return CommandReturn_Failure;
+ }
+ removeRouteCommand->addressType = ADDR_INET6;
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&removeRouteCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ removeRouteCommand->len = len;
+ strcpy(removeRouteCommand->symbolicOrConnid, symbolicOrConnid);
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, REMOVE_ROUTE, removeRouteCommand, sizeof(remove_route_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlRemoveRoute.h b/hicn-light/src/config/controlRemoveRoute.h
new file mode 100755
index 0000000..a3c0ee4
--- /dev/null
+++ b/hicn-light/src/config/controlRemoveRoute.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_RemoveRoute.h
+ * @brief Remove a route from the FIB
+ *
+ * Implements the "remove route" and "help remove route" nodes of the command
+ * tree
+ *
+ */
+
+#ifndef Control_RemoveRoute_h
+#define Control_RemoveRoute_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRemoveRoute_Create(ControlState *state);
+CommandOps *controlRemoveRoute_HelpCreate(ControlState *state);
+#endif // Control_RemoveRoute_h
diff --git a/hicn-light/src/config/controlRoot.c b/hicn-light/src/config/controlRoot.c
new file mode 100755
index 0000000..5d6c5f9
--- /dev/null
+++ b/hicn-light/src/config/controlRoot.c
@@ -0,0 +1,134 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <src/config/controlAdd.h>
+#include <src/config/controlCache.h>
+#include <src/config/controlList.h>
+#include <src/config/controlMapMe.h>
+#include <src/config/controlQuit.h>
+#include <src/config/controlRemove.h>
+#include <src/config/controlRoot.h>
+#include <src/config/controlSet.h>
+#include <src/config/controlUnset.h>
+
+static void _controlRoot_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlRoot_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlRoot_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandRoot = "";
+static const char *_commandRootHelp = "help";
+
+// ====================================================
+
+CommandOps *controlRoot_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRoot, _controlRoot_Init,
+ _controlRoot_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlRoot_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRootHelp, NULL,
+ _controlRoot_HelpExecute, commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandReturn _controlRoot_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ printf("Command-line execution:\n");
+ printf(
+ " controller [--keystore <keystorepath>] [--password <password>] "
+ "command\n");
+ printf("\n");
+ printf("Interactive execution:\n");
+ printf(" controller [--keystore <keystorepath>] [--password <password>]\n");
+ printf("\n");
+ printf(
+ "If the keystore is not specified, the default path is used. Keystore "
+ "must exist prior to running program.\n");
+ printf("If the password is not specified, the user will be prompted.\n");
+ printf("\n");
+
+ CommandOps *ops_help_add = controlAdd_CreateHelp(NULL);
+ CommandOps *ops_help_list = controlList_HelpCreate(NULL);
+ CommandOps *ops_help_quit = controlQuit_HelpCreate(NULL);
+ CommandOps *ops_help_remove = controlRemove_HelpCreate(NULL);
+ CommandOps *ops_help_set = controlSet_HelpCreate(NULL);
+ CommandOps *ops_help_unset = controlUnset_HelpCreate(NULL);
+ CommandOps *ops_help_cache = controlCache_HelpCreate(NULL);
+ CommandOps *ops_help_mapme = controlMapMe_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_help_add->command);
+ printf(" %s\n", ops_help_list->command);
+ printf(" %s\n", ops_help_quit->command);
+ printf(" %s\n", ops_help_remove->command);
+ printf(" %s\n", ops_help_set->command);
+ printf(" %s\n", ops_help_unset->command);
+ printf(" %s\n", ops_help_cache->command);
+ printf(" %s\n", ops_help_mapme->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_help_add);
+ commandOps_Destroy(&ops_help_list);
+ commandOps_Destroy(&ops_help_quit);
+ commandOps_Destroy(&ops_help_remove);
+ commandOps_Destroy(&ops_help_set);
+ commandOps_Destroy(&ops_help_unset);
+ commandOps_Destroy(&ops_help_cache);
+ commandOps_Destroy(&ops_help_mapme);
+
+ return CommandReturn_Success;
+}
+
+static void _controlRoot_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+
+ controlState_RegisterCommand(state, controlAdd_CreateHelp(state));
+ controlState_RegisterCommand(state, controlList_HelpCreate(state));
+ controlState_RegisterCommand(state, controlQuit_HelpCreate(state));
+ controlState_RegisterCommand(state, controlRemove_HelpCreate(state));
+ controlState_RegisterCommand(state, controlSet_HelpCreate(state));
+ controlState_RegisterCommand(state, controlUnset_HelpCreate(state));
+ controlState_RegisterCommand(state, controlCache_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMe_HelpCreate(state));
+
+ controlState_RegisterCommand(state, webControlAdd_Create(state));
+ controlState_RegisterCommand(state, controlList_Create(state));
+ controlState_RegisterCommand(state, controlQuit_Create(state));
+ controlState_RegisterCommand(state, controlRemove_Create(state));
+ controlState_RegisterCommand(state, controlSet_Create(state));
+ controlState_RegisterCommand(state, controlUnset_Create(state));
+ controlState_RegisterCommand(state, controlCache_Create(state));
+ controlState_RegisterCommand(state, controlMapMe_Create(state));
+}
+
+static CommandReturn _controlRoot_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return CommandReturn_Success;
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlRoot.h b/hicn-light/src/config/controlRoot.h
new file mode 100755
index 0000000..a62126e
--- /dev/null
+++ b/hicn-light/src/config/controlRoot.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_Root.h
+ * @brief Root of the command tree
+ *
+ * Implements the root of the command tree. This is the one module that
+ * needs to be seeded to the control state to build the whole tree.
+ *
+ */
+
+#ifndef Control_Root_h
+#define Control_Root_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRoot_Create(ControlState *state);
+CommandOps *controlRoot_HelpCreate(ControlState *state);
+#endif // Control_Root_h
diff --git a/hicn-light/src/config/controlSet.c b/hicn-light/src/config/controlSet.c
new file mode 100755
index 0000000..c6fd9aa
--- /dev/null
+++ b/hicn-light/src/config/controlSet.c
@@ -0,0 +1,88 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_Security.h>
+
+#include <src/config/controlSet.h>
+#include <src/config/controlSetDebug.h>
+#include <src/config/controlSetStrategy.h>
+#include <src/config/controlSetWldr.h>
+
+static void _controlSet_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlSet_Execute(CommandParser *parser, CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlSet_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandSet = "set";
+static const char *_commandSetHelp = "help set";
+
+// ===========================================================
+
+CommandOps *controlSet_Create(ControlState *state) {
+ return commandOps_Create(state, _commandSet, _controlSet_Init,
+ _controlSet_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlSet_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandSetHelp, NULL,
+ _controlSet_HelpExecute, commandOps_Destroy);
+}
+
+// ===========================================================
+
+static void _controlSet_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlSetDebug_Create(state));
+ controlState_RegisterCommand(state, controlSetDebug_HelpCreate(state));
+ controlState_RegisterCommand(state, controlSetStrategy_Create(state));
+ controlState_RegisterCommand(state, controlSetStrategy_HelpCreate(state));
+ controlState_RegisterCommand(state, controlSetWldr_Create(state));
+ controlState_RegisterCommand(state, controlSetWldr_HelpCreate(state));
+}
+
+static CommandReturn _controlSet_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ CommandOps *ops_help_set_debug = controlSetDebug_HelpCreate(NULL);
+ CommandOps *ops_help_set_strategy = controlSetStrategy_HelpCreate(NULL);
+ CommandOps *ops_help_set_wldr = controlSetWldr_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_help_set_debug->command);
+ printf(" %s\n", ops_help_set_strategy->command);
+ printf(" %s\n", ops_help_set_wldr->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_help_set_debug);
+ commandOps_Destroy(&ops_help_set_strategy);
+ commandOps_Destroy(&ops_help_set_wldr);
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlSet_Execute(CommandParser *parser, CommandOps *ops,
+ PARCList *args) {
+ return _controlSet_HelpExecute(parser, ops, args);
+}
diff --git a/hicn-light/src/config/controlSet.h b/hicn-light/src/config/controlSet.h
new file mode 100755
index 0000000..4289aad
--- /dev/null
+++ b/hicn-light/src/config/controlSet.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.
+ */
+
+/**
+ * @file control_Set.h
+ * @brief Implements the set node of the CLI tree
+ *
+ * Implements the "set" and "help set" nodes of the command tree
+ *
+ */
+#ifndef Control_Set_h
+#define Control_Set_h
+
+#include <src/config/controlState.h>
+CommandOps *controlSet_Create(ControlState *state);
+CommandOps *controlSet_HelpCreate(ControlState *state);
+#endif // Control_Set_h
diff --git a/hicn-light/src/config/controlSetDebug.c b/hicn-light/src/config/controlSetDebug.c
new file mode 100755
index 0000000..ca43242
--- /dev/null
+++ b/hicn-light/src/config/controlSetDebug.c
@@ -0,0 +1,74 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlSetDebug.h>
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+static CommandReturn _controlSetDebug_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlSetDebug_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandSetDebug = "set debug";
+static const char *_commandSetDebugHelp = "help set debug";
+
+// ====================================================
+
+CommandOps *controlSetDebug_Create(ControlState *state) {
+ return commandOps_Create(state, _commandSetDebug, NULL,
+ _controlSetDebug_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlSetDebug_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandSetDebugHelp, NULL,
+ _controlSetDebug_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlSetDebug_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("set debug: will enable the debug flag for more verbose output\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlSetDebug_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlSetDebug_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+ controlState_SetDebug(state, true);
+ printf("Debug flag set\n\n");
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlSetDebug.h b/hicn-light/src/config/controlSetDebug.h
new file mode 100755
index 0000000..5335ebc
--- /dev/null
+++ b/hicn-light/src/config/controlSetDebug.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_SetDebug.h
+ * @brief Sets the debug flag for more verbose output
+ *
+ * Implements the "set debug" and "help set debug" nodes of the command tree
+ *
+ */
+
+#ifndef Control_SetDebug_h
+#define Control_SetDebug_h
+
+#include <src/config/controlState.h>
+CommandOps *controlSetDebug_Create(ControlState *state);
+CommandOps *controlSetDebug_HelpCreate(ControlState *state);
+#endif // Control_SetDebug_h
diff --git a/hicn-light/src/config/controlSetStrategy.c b/hicn-light/src/config/controlSetStrategy.c
new file mode 100755
index 0000000..7b7c117
--- /dev/null
+++ b/hicn-light/src/config/controlSetStrategy.c
@@ -0,0 +1,183 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/config/controlSetDebug.h>
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlSetStrategy_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlSetStrategy_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandSetStrategy = "set strategy";
+static const char *_commandSetStrategyHelp = "help set strategy";
+
+static const char *_commandSetStrategyOptions[LAST_STRATEGY_VALUE] = {
+ "loadbalancer",
+ "random",
+ "random_per_dash_segment",
+ "loadbalancer_with_delay",
+ "loadbalancer_by_rate",
+ "loadbalancer_best_route"};
+
+// ====================================================
+
+CommandOps *controlSetStrategy_Create(ControlState *state) {
+ return commandOps_Create(state, _commandSetStrategy, NULL,
+ _controlSetStrategy_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlSetStrategy_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandSetStrategyHelp, NULL,
+ _controlSetStrategy_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+strategy_type _validStrategy(const char *strategy) {
+ strategy_type validStrategy = LAST_STRATEGY_VALUE;
+
+ for (int i = 0; i < LAST_STRATEGY_VALUE; i++) {
+ if (strcmp(_commandSetStrategyOptions[i], strategy) == 0) {
+ validStrategy = i;
+ break;
+ }
+ }
+ return validStrategy;
+}
+
+static CommandReturn _controlSetStrategy_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("set strategy <prefix> <strategy>\n");
+ printf("prefix: ipv4/ipv6 address (ex: 1234::/64)\n");
+ printf("strategy: strategy identifier\n");
+ printf("available strategies:\n");
+ printf(" random\n");
+ printf(" loadbalancer\n");
+ printf(" random_per_dash_segment\n");
+ printf(" loadbalancer_with_delay\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlSetStrategy_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 4) {
+ _controlSetStrategy_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ if (((strcmp(parcList_GetAtIndex(args, 0), "set") != 0) ||
+ (strcmp(parcList_GetAtIndex(args, 1), "strategy") != 0))) {
+ _controlSetStrategy_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *prefixStr = parcList_GetAtIndex(args, 2);
+ char addr[strlen(prefixStr) + 1];
+ // separate address and len
+ char *slash;
+ uint32_t len = UINT32_MAX;
+ strcpy(addr, prefixStr);
+ slash = strrchr(addr, '/');
+ if (slash != NULL) {
+ len = atoi(slash + 1);
+ *slash = '\0';
+ }
+ if (len == 0) {
+ printf("ERROR: a prefix can not be of length 0\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ set_strategy_command *setStrategyCommand =
+ parcMemory_AllocateAndClear(sizeof(set_strategy_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &setStrategyCommand->address.ipv4) == 1) {
+ if (len == UINT32_MAX) {
+ printf("Netmask not specified: set to 32 by default\n");
+ len = 32;
+ } else if (len > 32) {
+ printf("ERROR: exceeded INET mask length, max=32\n");
+ parcMemory_Deallocate(&setStrategyCommand);
+ return CommandReturn_Failure;
+ }
+ setStrategyCommand->addressType = ADDR_INET;
+ } else if (inet_pton(AF_INET6, addr, &setStrategyCommand->address.ipv6) ==
+ 1) {
+ if (len == UINT32_MAX) {
+ printf("Netmask not specified: set to 128 by default\n");
+ len = 128;
+ } else if (len > 128) {
+ printf("ERROR: exceeded INET6 mask length, max=128\n");
+ parcMemory_Deallocate(&setStrategyCommand);
+ return CommandReturn_Failure;
+ }
+ setStrategyCommand->addressType = ADDR_INET6;
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&setStrategyCommand);
+ return CommandReturn_Failure;
+ }
+
+ const char *strategyStr = parcList_GetAtIndex(args, 3);
+ // check valid strategy
+ strategy_type strategy;
+ if ((strategy = _validStrategy(strategyStr)) == LAST_STRATEGY_VALUE) {
+ printf("Error: invalid strategy \n");
+ parcMemory_Deallocate(&setStrategyCommand);
+ _controlSetStrategy_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ setStrategyCommand->len = len;
+ setStrategyCommand->strategyType = strategy;
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, SET_STRATEGY, setStrategyCommand, sizeof(set_strategy_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlSetStrategy.h b/hicn-light/src/config/controlSetStrategy.h
new file mode 100755
index 0000000..53ce891
--- /dev/null
+++ b/hicn-light/src/config/controlSetStrategy.h
@@ -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.
+ */
+
+#ifndef Control_SetStrategy_h
+#define Control_SetStrategy_h
+
+#include <src/config/controlState.h>
+CommandOps *controlSetStrategy_Create(ControlState *state);
+CommandOps *controlSetStrategy_HelpCreate(ControlState *state);
+#endif // Control_SetStrategy_h
diff --git a/hicn-light/src/config/controlSetWldr.c b/hicn-light/src/config/controlSetWldr.c
new file mode 100755
index 0000000..9da4040
--- /dev/null
+++ b/hicn-light/src/config/controlSetWldr.c
@@ -0,0 +1,122 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlSetDebug.h>
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlSetWldr_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlSetWldr_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandSetWldr = "set wldr";
+static const char *_commandSetWldrHelp = "help set wldr";
+
+// ====================================================
+
+CommandOps *controlSetWldr_Create(ControlState *state) {
+ return commandOps_Create(state, _commandSetWldr, NULL,
+ _controlSetWldr_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlSetWldr_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandSetWldrHelp, NULL,
+ _controlSetWldr_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlSetWldr_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("set wldr <on|off> <connection_id>\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlSetWldr_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 4) {
+ _controlSetWldr_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ if (((strcmp(parcList_GetAtIndex(args, 0), "set") != 0) ||
+ (strcmp(parcList_GetAtIndex(args, 1), "wldr") != 0))) {
+ _controlSetWldr_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlSetWldr_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ // check if valid connid
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, 3);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an "
+ "alpha followed by alphanum;\nconnid must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ set_wldr_command *setWldrCommand =
+ parcMemory_AllocateAndClear(sizeof(set_wldr_command));
+ strcpy(setWldrCommand->symbolicOrConnid, symbolicOrConnid);
+ if (active) {
+ setWldrCommand->activate = ACTIVATE_ON;
+ } else {
+ setWldrCommand->activate = ACTIVATE_OFF;
+ }
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, SET_WLDR, setWldrCommand,
+ sizeof(set_wldr_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlSetWldr.h b/hicn-light/src/config/controlSetWldr.h
new file mode 100755
index 0000000..59c0b0f
--- /dev/null
+++ b/hicn-light/src/config/controlSetWldr.h
@@ -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.
+ */
+
+#ifndef Control_SetWldr_h
+#define Control_SetWldr_h
+
+#include <src/config/controlState.h>
+CommandOps *controlSetWldr_Create(ControlState *state);
+CommandOps *controlSetWldr_HelpCreate(ControlState *state);
+#endif // Control_SetWldr_h
diff --git a/hicn-light/src/config/controlState.c b/hicn-light/src/config/controlState.c
new file mode 100755
index 0000000..d8260e8
--- /dev/null
+++ b/hicn-light/src/config/controlState.c
@@ -0,0 +1,237 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <string.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+#include <parc/algol/parc_Time.h>
+#include <parc/algol/parc_TreeRedBlack.h>
+
+#include <src/config/commandParser.h>
+#include <src/config/controlRoot.h>
+#include <src/config/controlState.h>
+
+#include <src/utils/commands.h>
+
+#define SRV_IP "127.0.0.1"
+#define PORT 9695
+
+struct controller_state {
+ CommandParser *parser;
+ bool debugFlag;
+
+ void *userdata;
+ struct iovec *(*writeRead)(ControlState *state, struct iovec *msg);
+ int sockfd;
+ char **commandOutput;
+ bool isInteractive;
+};
+
+int controlState_connectToFwdDeamon() {
+ int sockfd;
+ struct sockaddr_in servaddr;
+
+ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ printf("\nSocket Creation Failed \n");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&servaddr, 0, sizeof(servaddr));
+
+ // Filling server information
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons(PORT);
+ servaddr.sin_addr.s_addr = INADDR_ANY;
+
+ // Establish connection
+ if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
+ printf("\nConnection Failed: hicn-light Daemon is not running \n");
+ exit(EXIT_FAILURE);
+ }
+
+ return sockfd;
+}
+
+ControlState *controlState_Create(
+ void *userdata,
+ struct iovec *(*writeRead)(ControlState *state, struct iovec *msg),
+ bool openControllerConnetion) {
+ ControlState *state = parcMemory_AllocateAndClear(sizeof(ControlState));
+ parcAssertNotNull(state, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(ControlState));
+ state->parser = commandParser_Create();
+
+ state->userdata = userdata;
+ state->writeRead = writeRead;
+ state->debugFlag = false;
+ state->commandOutput = NULL;
+ state->isInteractive = true;
+
+ if (openControllerConnetion) {
+ state->sockfd = controlState_connectToFwdDeamon();
+ } else {
+ state->sockfd = 2; // stderr
+ }
+
+ return state;
+}
+
+void controlState_Destroy(ControlState **statePtr) {
+ parcAssertNotNull(statePtr, "Parameter statePtr must be non-null");
+ parcAssertNotNull(*statePtr,
+ "Parameter statePtr must dereference t non-null");
+ ControlState *state = *statePtr;
+ // printf("sockid destroyed: %d\n", state->sockfd);
+ // close the connection with the fwd deamon
+ shutdown(state->sockfd, 2);
+
+ commandParser_Destroy(&state->parser);
+ parcMemory_Deallocate((void **)&state);
+ *statePtr = NULL;
+}
+
+void controlState_SetDebug(ControlState *state, bool debugFlag) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ state->debugFlag = debugFlag;
+ commandParser_SetDebug(state->parser, debugFlag);
+}
+
+bool controlState_GetDebug(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ return state->debugFlag;
+}
+
+void controlState_RegisterCommand(ControlState *state, CommandOps *ops) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ commandParser_RegisterCommand(state->parser, ops);
+}
+
+struct iovec *controlState_WriteRead(ControlState *state, struct iovec *msg) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ parcAssertNotNull(msg, "Parameter msg must be non-null");
+
+ return state->writeRead(state, msg);
+}
+
+static PARCList *_controlState_ParseStringIntoTokens(
+ const char *originalString) {
+ PARCList *list =
+ parcList(parcArrayList_Create(parcArrayList_StdlibFreeFunction),
+ PARCArrayListAsPARCList);
+
+ char *token;
+
+ char *tofree =
+ parcMemory_StringDuplicate(originalString, strlen(originalString) + 1);
+ char *string = tofree;
+
+ while ((token = strsep(&string, " \t\n")) != NULL) {
+ if (strlen(token) > 0) {
+ parcList_Add(list, strdup(token));
+ }
+ }
+
+ parcMemory_Deallocate((void **)&tofree);
+
+ return list;
+}
+
+CommandReturn controlState_DispatchCommand(ControlState *state,
+ PARCList *args) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ return commandParser_DispatchCommand(state->parser, args);
+}
+
+int controlState_Interactive(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ char *line = NULL;
+ size_t linecap = 0;
+ CommandReturn controlReturn = CommandReturn_Success;
+
+ while (controlReturn != CommandReturn_Exit && !feof(stdin)) {
+ fputs("> ", stdout);
+ fflush(stdout);
+ ssize_t failure = getline(&line, &linecap, stdin);
+ parcAssertTrue(failure > -1, "Error getline");
+
+ PARCList *args = _controlState_ParseStringIntoTokens(line);
+ controlReturn = controlState_DispatchCommand(state, args);
+ // release and get command
+ parcList_Release(&args);
+ }
+ return 0;
+}
+
+void controlState_SetCommandOutput(ControlState *state, char **commandData) {
+ state->commandOutput = commandData;
+}
+
+void controlState_ReleaseCommandOutput(ControlState *state, char **commandData,
+ size_t commandLenght) {
+ for (size_t i = 0; i < commandLenght; i++) {
+ parcMemory_Deallocate(&commandData[i]);
+ }
+ parcMemory_Deallocate(&commandData);
+ state->commandOutput = NULL;
+}
+
+char **controlState_GetCommandOutput(ControlState *state) {
+ return state->commandOutput;
+}
+
+// size_t
+// controlState_GetCommandLen(ControlState *state){
+
+// }
+
+void controlState_SetInteractiveFlag(ControlState *state, bool interactive) {
+ state->isInteractive = interactive;
+}
+
+bool controlState_IsInteractive(ControlState *state) {
+ return state->isInteractive;
+}
+
+int controlState_GetSockfd(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ return state->sockfd;
+}
+
+void *controlState_GetUserdata(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ return state->userdata;
+}
+
+bool controlState_isConfigFile(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ if (state->sockfd != 2) {
+ return false;
+ } else {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/hicn-light/src/config/controlState.h b/hicn-light/src/config/controlState.h
new file mode 100755
index 0000000..905c56c
--- /dev/null
+++ b/hicn-light/src/config/controlState.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file controlState.h
+ * @brief A control program for hicn-light using CLI commands
+ *
+ * Implements the state machine for the control program. It takes a "writeRead"
+ * function as part of the constructor. This abstracts out the backend. It
+ * could be a Portal from hicnLightControl program down to the forwarder or it
+ * could be an internal function within hicn-light.
+ *
+ */
+
+#ifndef control_h
+#define control_h
+
+#include <parc/algol/parc_List.h>
+#include <src/config/commandParser.h>
+
+#include <src/utils/commands.h>
+
+struct controller_state;
+typedef struct controller_state ControlState;
+
+/**
+ * controlState_Create
+ *
+ * Creates the global state for the Control program. The user provides the
+ * writeRead function for sending and receiving the message wrapping command
+ * arguments. For configuration file inside hicn-light, it would make direct
+ * calls to Configuration -> Dispatcher.
+ *
+ * @param [in] userdata A closure passed back to the user when calling
+ * writeRead.
+ * @param [in] writeRead The function to write then read configuration messages
+ * to hicn-light
+ *
+ * @return non-null The control state
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+
+ControlState *controlState_Create(
+ void *userdata,
+ struct iovec *(*writeRead)(ControlState *state, struct iovec *msg),
+ bool openControllerConnetion);
+
+/**
+ * Destroys the control state, closing all network connections
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void controlState_Destroy(ControlState **statePtr);
+
+/**
+ * Registers a CommandOps with the system.
+ *
+ * Each command has its complete command prefix in the "command" field.
+ * RegisterCommand will put these command prefixes in to a tree and then match
+ * what a user types against the longest-matching prefix in the tree. If
+ * there's a match, it will call the "execute" function.
+ *
+ * @param [in] state An allocated ControlState
+ * @param [in] command The command to register with the system
+ *
+ * Example:
+ * @code
+ * static CommandReturn
+ * control_Root_Execute(CommandParser *parser, CommandOps *ops, PARCList
+ * *args)
+ * {
+ * printf("Root Command\n");
+ * return CommandReturn_Success;
+ * }
+ *
+ * static CommandReturn
+ * control_FooBar_Execute(CommandParser *parser, CommandOps *ops, PARCList
+ * *args)
+ * {
+ * printf("Foo Bar Command\n");
+ * return CommandReturn_Success;
+ * }
+ *
+ * const CommandOps control_Root = {
+ * .command = "", // empty string for root
+ * .init = NULL,
+ * .execute = control_Root_Execute
+ * };
+ *
+ * const CommandOps control_FooBar = {
+ * .command = "foo bar", // empty string for root
+ * .init = NULL,
+ * .execute = control_FooBar_Execute
+ * };
+ *
+ * void startup(void)
+ * {
+ * ControlState *state = controlState_Create("happy", "day");
+ * controlState_RegisterCommand(state, control_FooBar);
+ * controlState_RegisterCommand(state, control_Root);
+ *
+ * // this executes "root"
+ * controlState_DispatchCommand(state, "foo");
+ * controlState_Destroy(&state);
+ * }
+ * @endcode
+ */
+void controlState_RegisterCommand(ControlState *state, CommandOps *command);
+
+/**
+ * Performs a longest-matching prefix of the args to the command tree
+ *
+ * The command tree is created with controlState_RegisterCommand.
+ *
+ * @param [in] state The allocated ControlState
+ * @param [in] args Each command_line word parsed to the ordered list
+ *
+ * @return CommandReturn_Success the command was successful
+ * @return CommandReturn_Failure the command failed or was not found
+ * @return CommandReturn_Exit the command indicates that the interactive mode
+ * should exit
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CommandReturn controlState_DispatchCommand(ControlState *state, PARCList *args);
+
+/**
+ * Begin an interactive shell
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+int controlState_Interactive(ControlState *state);
+
+/**
+ * Write then Read a command
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+struct iovec *controlState_WriteRead(ControlState *state, struct iovec *msg);
+
+/**
+ * Sets the Debug mode, which will print out much more information.
+ *
+ * Prints out much more diagnostic information about what hicn-light controller
+ * is doing. yes, you would make a CommandOps to set and unset this :)
+ *
+ * @param [in] debugFlag true means to print debug info, false means to turn it
+ * off
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void controlState_SetDebug(ControlState *state, bool debugFlag);
+
+/**
+ * Returns the debug state of ControlState
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool controlState_GetDebug(ControlState *state);
+#endif // control_h
+
+void controlState_SetCommandOutput(ControlState *state, char **commandData);
+
+void controlState_ReleaseCommandOutput(ControlState *state, char **commandData,
+ size_t commandLenght);
+
+char **controlState_GetCommandOutput(ControlState *state);
+
+void controlState_SetInteractiveFlag(ControlState *state, bool interactive);
+
+bool controlState_IsInteractive(ControlState *state);
+
+void *controlState_GetUserdata(ControlState *state);
+
+bool controlState_isConfigFile(ControlState *state);
+
+int controlState_GetSockfd(ControlState *state);
diff --git a/hicn-light/src/config/controlUnset.c b/hicn-light/src/config/controlUnset.c
new file mode 100755
index 0000000..2da6a65
--- /dev/null
+++ b/hicn-light/src/config/controlUnset.c
@@ -0,0 +1,78 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_Security.h>
+
+#include <src/config/controlUnset.h>
+#include <src/config/controlUnsetDebug.h>
+
+static void _controlUnset_Init(CommandParser *parser, CommandOps *ops);
+
+static CommandReturn _controlUnset_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlUnset_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandUnset = "unset";
+static const char *_commandUnsetHelp = "help unset";
+
+// ===========================================================
+
+CommandOps *controlUnset_Create(ControlState *state) {
+ return commandOps_Create(state, _commandUnset, _controlUnset_Init,
+ _controlUnset_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlUnset_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandUnsetHelp, NULL,
+ _controlUnset_HelpExecute, commandOps_Destroy);
+}
+
+// ===========================================================
+
+static void _controlUnset_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlUnsetDebug_Create(state));
+ controlState_RegisterCommand(state, controlUnsetDebug_HelpCreate(state));
+}
+
+static CommandReturn _controlUnset_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ CommandOps *ops_help_unset_debug = controlUnsetDebug_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_help_unset_debug->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_help_unset_debug);
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlUnset_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlUnset_HelpExecute(parser, ops, args);
+}
diff --git a/hicn-light/src/config/controlUnset.h b/hicn-light/src/config/controlUnset.h
new file mode 100755
index 0000000..6eeb983
--- /dev/null
+++ b/hicn-light/src/config/controlUnset.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.
+ */
+
+/**
+ * @file control_Unset.h
+ * @brief Implements the unset node of the CLI tree
+ *
+ * Implements the "unset" and "help unset" nodes of the command tree
+ *
+ */
+#ifndef Control_Unset_h
+#define Control_Unset_h
+
+#include <src/config/controlState.h>
+CommandOps *controlUnset_Create(ControlState *state);
+CommandOps *controlUnset_HelpCreate(ControlState *state);
+#endif // Control_Unset_h
diff --git a/hicn-light/src/config/controlUnsetDebug.c b/hicn-light/src/config/controlUnsetDebug.c
new file mode 100755
index 0000000..4892bd5
--- /dev/null
+++ b/hicn-light/src/config/controlUnsetDebug.c
@@ -0,0 +1,77 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlUnsetDebug.h>
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+static CommandReturn _controlUnsetDebug_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlUnsetDebug_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandUnsetDebug = "unset debug";
+static const char *_commandUnsetDebugHelp = "help unset debug";
+
+// ====================================================
+
+CommandOps *controlUnsetDebug_Create(ControlState *state) {
+ return commandOps_Create(state, _commandUnsetDebug, NULL,
+ _controlUnsetDebug_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlUnsetDebug_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandUnsetDebugHelp, NULL,
+ _controlUnsetDebug_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlUnsetDebug_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("unset debug: will disable the debug flag\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlUnsetDebug_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlUnsetDebug_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+ controlState_SetDebug(state, false);
+ printf("Debug flag cleared\n\n");
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlUnsetDebug.h b/hicn-light/src/config/controlUnsetDebug.h
new file mode 100755
index 0000000..e34f8aa
--- /dev/null
+++ b/hicn-light/src/config/controlUnsetDebug.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file control_UnsetDebug.h
+ * @brief Unsets the debug flag for more verbose output
+ *
+ * Implements the "unset debug" and "help unset debug" nodes of the CLI tree
+ *
+ */
+
+#ifndef Control_UnsetDebug_h
+#define Control_UnsetDebug_h
+
+#include <src/config/controlState.h>
+CommandOps *controlUnsetDebug_Create(ControlState *state);
+CommandOps *controlUnsetDebug_HelpCreate(ControlState *state);
+#endif // Control_UnsetDebug_h
diff --git a/hicn-light/src/config/symbolicNameTable.c b/hicn-light/src/config/symbolicNameTable.c
new file mode 100755
index 0000000..ccf416d
--- /dev/null
+++ b/hicn-light/src/config/symbolicNameTable.c
@@ -0,0 +1,175 @@
+/*
+ * 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 <ctype.h>
+#include <parc/algol/parc_Hash.h>
+#include <parc/algol/parc_HashCodeTable.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config.h>
+#include <stdio.h>
+
+#include <src/config/symbolicNameTable.h>
+
+struct symblic_name_table {
+ PARCHashCodeTable *symbolicNameTable;
+ PARCHashCodeTable *indexToNameTable;
+};
+
+// ========================================================================================
+// symbolic name table functions
+
+static bool _symbolicNameEquals(const void *keyA, const void *keyB) {
+ return (strcasecmp((const char *)keyA, (const char *)keyB) == 0);
+}
+
+static HashCodeType _symbolicNameHash(const void *keyA) {
+ const char *str = (const char *)keyA;
+ size_t length = strlen(str);
+ return parcHash32_Data(str, length);
+}
+
+static bool _connectionIdEquals(const void *keyA, const void *keyB) {
+ unsigned idA = *((unsigned *)keyA);
+ unsigned idB = *((unsigned *)keyB);
+ return (idA == idB);
+}
+
+static HashCodeType _connectionIdHash(const void *keyA) {
+ unsigned idA = *((unsigned *)keyA);
+ return parcHash32_Int32(idA);
+}
+
+// ========================================================================================
+
+SymbolicNameTable *symbolicNameTable_Create(void) {
+ SymbolicNameTable *table = parcMemory_Allocate(sizeof(SymbolicNameTable));
+
+ if (table) {
+ // key = char *
+ // value = uint32_t *
+ table->symbolicNameTable = parcHashCodeTable_Create(
+ _symbolicNameEquals, _symbolicNameHash, parcMemory_DeallocateImpl,
+ parcMemory_DeallocateImpl);
+ table->indexToNameTable = parcHashCodeTable_Create(
+ _connectionIdEquals, _connectionIdHash, parcMemory_DeallocateImpl,
+ parcMemory_DeallocateImpl);
+ }
+
+ return table;
+}
+
+void symbolicNameTable_Destroy(SymbolicNameTable **tablePtr) {
+ SymbolicNameTable *table = *tablePtr;
+ parcHashCodeTable_Destroy(&table->symbolicNameTable);
+ // parcHashCodeTable_Destroy(&table->indexToNameTable);
+ parcMemory_Deallocate((void **)&table);
+ *tablePtr = NULL;
+}
+
+static char *_createKey(const char *symbolicName) {
+ char *key = parcMemory_StringDuplicate(symbolicName, strlen(symbolicName));
+
+ // convert key to upper case
+ char *p = key;
+
+ // keeps looping until the first null
+ while ((*p = toupper(*p))) {
+ p++;
+ }
+ return key;
+}
+
+bool symbolicNameTable_Exists(SymbolicNameTable *table,
+ const char *symbolicName) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+ parcAssertNotNull(symbolicName, "Parameter symbolicName must be non-null");
+
+ char *key = _createKey(symbolicName);
+ bool found = (parcHashCodeTable_Get(table->symbolicNameTable, key) != NULL);
+ parcMemory_Deallocate((void **)&key);
+ return found;
+}
+
+void symbolicNameTable_Remove(SymbolicNameTable *table,
+ const char *symbolicName) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+ parcAssertNotNull(symbolicName, "Parameter symbolicName must be non-null");
+
+ char *key = _createKey(symbolicName);
+
+ unsigned id = symbolicNameTable_Get(table, symbolicName);
+ uint32_t *value = parcMemory_Allocate(sizeof(uint32_t));
+ *value = id;
+
+ parcHashCodeTable_Del(table->symbolicNameTable, key);
+ parcHashCodeTable_Del(table->indexToNameTable, value);
+ parcMemory_Deallocate((void **)&key);
+ parcMemory_Deallocate((void **)&value);
+}
+
+bool symbolicNameTable_Add(SymbolicNameTable *table, const char *symbolicName,
+ unsigned connid) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+ parcAssertNotNull(symbolicName, "Parameter symbolicName must be non-null");
+ parcAssertTrue(connid < UINT32_MAX, "Parameter connid must be less than %u",
+ UINT32_MAX);
+
+ char *key = _createKey(symbolicName);
+
+ uint32_t *value = parcMemory_Allocate(sizeof(uint32_t));
+ *value = connid;
+
+ bool success = parcHashCodeTable_Add(table->symbolicNameTable, key, value);
+ success = parcHashCodeTable_Add(table->indexToNameTable, value, key);
+ if (!success) {
+ parcMemory_Deallocate((void **)&key);
+ parcMemory_Deallocate((void **)&value);
+ }
+
+ return success;
+}
+
+unsigned symbolicNameTable_Get(SymbolicNameTable *table,
+ const char *symbolicName) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+ parcAssertNotNull(symbolicName, "Parameter symbolicName must be non-null");
+
+ unsigned connid = UINT32_MAX;
+
+ char *key = _createKey(symbolicName);
+
+ uint32_t *value = parcHashCodeTable_Get(table->symbolicNameTable, key);
+ if (value) {
+ connid = *value;
+ }
+
+ parcMemory_Deallocate((void **)&key);
+ return connid;
+}
+
+const char *symbolicNameTable_GetNameByIndex(SymbolicNameTable *table,
+ unsigned id) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+
+ uint32_t *value = parcMemory_Allocate(sizeof(uint32_t));
+ *value = id;
+
+ const char *name = parcHashCodeTable_Get(table->indexToNameTable, value);
+ if (name == NULL) name = "";
+
+ parcMemory_Deallocate((void **)&value);
+ return name;
+}
diff --git a/hicn-light/src/config/symbolicNameTable.h b/hicn-light/src/config/symbolicNameTable.h
new file mode 100755
index 0000000..69919cf
--- /dev/null
+++ b/hicn-light/src/config/symbolicNameTable.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file symbolicNameTable.h
+ * @brief The symbolic name table maps a string name to a connection id
+ *
+ * When configuring tunnels/connections, the user provides a string name
+ * (symbolic name) that they will use to refer to that connection. The symblic
+ * name table translates that symbolic name to a connection id.
+ *
+ */
+
+#ifndef symbolicNameTable_h
+#define symbolicNameTable_h
+
+struct symblic_name_table;
+typedef struct symblic_name_table SymbolicNameTable;
+
+#include <stdbool.h>
+
+/**
+ * Creates a symbolic name table
+ *
+ * Allocates a SymbolicNameTable, which will store the symbolic names
+ * in a hash table.
+ *
+ * @retval non-null An allocated SymbolicNameTable
+ * @retval null An error
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+SymbolicNameTable *symbolicNameTable_Create(void);
+
+/**
+ * Destroys a name table
+ *
+ * All keys and data are released.
+ *
+ * @param [in,out] tablePtr A pointer to a SymbolicNameTable, which will be
+ * NULL'd
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void symbolicNameTable_Destroy(SymbolicNameTable **tablePtr);
+
+/**
+ * Checks if the name (case insensitive) is in the table
+ *
+ * Does a case-insensitive match to see if the name is in the table
+ *
+ * @param [in] table An allocated SymbolicNameTable
+ * @param [in] symbolicName The name to check for
+ *
+ * @retval true The name is in the table
+ * @retval false The name is not in the talbe
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool symbolicNameTable_Exists(SymbolicNameTable *table,
+ const char *symbolicName);
+
+/**
+ * Adds a (name, connid) pair to the table.
+ *
+ * The name is stored case insensitive. The value UINT_MAX is used to indicate
+ * a non-existent key, so it should not be stored as a value in the table.
+ *
+ * @param [in] table An allocated SymbolicNameTable
+ * @param [in] symbolicName The name to save (will make a copy)
+ * @param [in] connid The connection id to associate with the name
+ *
+ * @retval true The pair was added
+ * @retval false The pair was not added (likely duplicate key)
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool symbolicNameTable_Add(SymbolicNameTable *table, const char *symbolicName,
+ unsigned connid);
+
+/**
+ * Returns the connection id associated with the symbolic name
+ *
+ * This function will look for the given name (case insensitive) and return the
+ * corresponding connid. If the name is not in the table, the function will
+ * return UINT_MAX.
+ *
+ * @param [in] table An allocated SymbolicNameTable
+ * @param [in] symbolicName The name to retrieve
+ *
+ * @retval UINT_MAX symbolicName not found
+ * @retval number the corresponding connid.
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+unsigned symbolicNameTable_Get(SymbolicNameTable *table,
+ const char *symbolicName);
+
+void symbolicNameTable_Remove(SymbolicNameTable *table,
+ const char *symbolicName);
+const char *symbolicNameTable_GetNameByIndex(SymbolicNameTable *table,
+ unsigned id);
+
+#endif /* defined(symbolicNameTable_h) */
diff --git a/hicn-light/src/content_store/CMakeLists.txt b/hicn-light/src/content_store/CMakeLists.txt
new file mode 100755
index 0000000..85643cf
--- /dev/null
+++ b/hicn-light/src/content_store/CMakeLists.txt
@@ -0,0 +1,33 @@
+# 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}/contentStoreEntry.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/contentStoreInterface.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/contentStoreLRU.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/listTimeOrdered.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/listLRU.h
+)
+
+list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/contentStoreInterface.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/contentStoreLRU.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/listLRU.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/listTimeOrdered.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/contentStoreEntry.c
+)
+
+set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/hicn-light/src/content_store/contentStoreEntry.c b/hicn-light/src/content_store/contentStoreEntry.c
new file mode 100755
index 0000000..d36ed61
--- /dev/null
+++ b/hicn-light/src/content_store/contentStoreEntry.c
@@ -0,0 +1,136 @@
+/*
+ * 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 <src/config.h>
+#include <stdio.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <src/content_store/contentStoreEntry.h>
+
+#include <parc/assert/parc_Assert.h>
+
+const uint64_t contentStoreEntry_MaxExpiryTime = UINT64_MAX;
+
+struct contentstore_entry {
+ Message *message;
+ ListLruEntry *lruEntry;
+ unsigned refcount;
+ bool hasExpiryTimeTicks;
+ uint64_t expiryTimeTicks;
+};
+
+ContentStoreEntry *contentStoreEntry_Create(Message *contentMessage,
+ ListLru *listLRU) {
+ parcAssertNotNull(contentMessage, "Parameter objectMessage must be non-null");
+
+ ContentStoreEntry *entry =
+ parcMemory_AllocateAndClear(sizeof(ContentStoreEntry));
+ parcAssertNotNull(entry, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(ContentStoreEntry));
+ entry->message = message_Acquire(contentMessage);
+ entry->refcount = 1;
+
+ if (listLRU != NULL) {
+ entry->lruEntry = listLRU_NewHeadEntry(listLRU, entry);
+ }
+
+ entry->hasExpiryTimeTicks = message_HasContentExpiryTime(contentMessage);
+
+ if (entry->hasExpiryTimeTicks) {
+ entry->expiryTimeTicks = message_GetContentExpiryTimeTicks(contentMessage);
+ }
+
+ return entry;
+}
+
+ContentStoreEntry *contentStoreEntry_Acquire(
+ const ContentStoreEntry *original) {
+ parcAssertNotNull(original, "Parameter must be non-null");
+ ((ContentStoreEntry *)original)->refcount++;
+ return (ContentStoreEntry *)original;
+}
+
+void contentStoreEntry_Release(ContentStoreEntry **entryPtr) {
+ parcAssertNotNull(entryPtr, "Parameter must be non-null double pointer");
+ parcAssertNotNull(*entryPtr,
+ "Parameter must dereference to non-null pointer");
+
+ ContentStoreEntry *entry = *entryPtr;
+ parcAssertTrue(entry->refcount > 0, "Illegal state: has refcount of 0");
+
+ entry->refcount--;
+ if (entry->refcount == 0) {
+ if (entry->lruEntry) {
+ listLRU_EntryDestroy(&entry->lruEntry);
+ }
+ message_Release(&entry->message);
+ parcMemory_Deallocate((void **)&entry);
+ }
+ *entryPtr = NULL;
+}
+
+Message *contentStoreEntry_GetMessage(const ContentStoreEntry *storeEntry) {
+ parcAssertNotNull(storeEntry, "Parameter must be non-null");
+ return storeEntry->message;
+}
+
+bool contentStoreEntry_HasExpiryTimeTicks(const ContentStoreEntry *storeEntry) {
+ parcAssertNotNull(storeEntry, "Parameter must be non-null");
+ return storeEntry->hasExpiryTimeTicks;
+}
+
+uint64_t contentStoreEntry_GetExpiryTimeTicks(
+ const ContentStoreEntry *storeEntry) {
+ parcAssertNotNull(storeEntry, "Parameter must be non-null");
+ parcAssertTrue(storeEntry->hasExpiryTimeTicks,
+ "storeEntry has no ExpiryTimeTicks. Did you call "
+ "contentStoreEntry_HasExpiryTimeTicks() first?");
+ return storeEntry->expiryTimeTicks;
+}
+
+int contentStoreEntry_CompareExpiryTime(const ContentStoreEntry *value1,
+ const ContentStoreEntry *value2) {
+ // A signum comparison. negative if key 1 is smaller, 0 if key1 == key2,
+ // greater than 0 if key1 is bigger.
+
+ ContentStoreEntry *v1 = (ContentStoreEntry *)value1;
+ ContentStoreEntry *v2 = (ContentStoreEntry *)value2;
+
+ if (v1->expiryTimeTicks < v2->expiryTimeTicks) {
+ return -1;
+ } else if (v1->expiryTimeTicks > v2->expiryTimeTicks) {
+ return +1;
+ } else {
+ // At this point, the times are the same. Use the address of the message as
+ // the decider. This allows us to store multiple messages with the same
+ // expiry/cache time.
+ if (v1->message < v2->message) {
+ return -1;
+ } else if (v1->message > v2->message) {
+ return +1;
+ }
+ }
+
+ return 0; // The same message has been encountered.
+}
+
+void contentStoreEntry_MoveToHead(ContentStoreEntry *storeEntry) {
+ parcAssertNotNull(storeEntry, "Parameter must be non-null");
+ parcAssertNotNull(storeEntry->lruEntry,
+ "ContentStoreEntry is not attached to an ListLru");
+ if (storeEntry->lruEntry) {
+ listLRU_EntryMoveToHead(storeEntry->lruEntry);
+ }
+}
diff --git a/hicn-light/src/content_store/contentStoreEntry.h b/hicn-light/src/content_store/contentStoreEntry.h
new file mode 100755
index 0000000..766cc15
--- /dev/null
+++ b/hicn-light/src/content_store/contentStoreEntry.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef contentStoreEntry_h
+#define contentStoreEntry_h
+
+#include <src/content_store/listLRU.h>
+#include <src/core/message.h>
+
+struct contentstore_entry;
+typedef struct contentstore_entry ContentStoreEntry;
+
+/**
+ * The max time allowed for an ExpiryTime. Will never be exceeded.
+ */
+extern const uint64_t contentStoreEntry_MaxExpiryTime;
+
+/**
+ * Creates a new `ContentStoreEntry` instance, acquiring a reference to the
+ * supplied `Message`.
+ *
+ * @param message the message to store
+ * @param listLRU the LRU list that this entry will be stored in.
+ * @return A newly created `ContentStoreEntry` instance that must eventually be
+ * released by calling
+ * {@link contentStoreEntry_Release}.
+ *
+ * @see contentStoreEntry_Release
+ */
+ContentStoreEntry *contentStoreEntry_Create(Message *objectMessage,
+ ListLru *listLRU);
+
+/**
+ * Returns a reference counted copy of the supplied `ContentStoreEntry`.
+ *
+ * @param original the ContentStoreEntry to return a reference to.
+ * @return Reference counted copy, must call
+ * <code>contentStoreEntry_Destroy()</code> on it.
+ */
+ContentStoreEntry *contentStoreEntry_Acquire(const ContentStoreEntry *original);
+
+/**
+ * Releases one reference count and destroys object when reaches zero
+ *
+ * @param [in,out] entryPtr A pointer to an allocated ContentStoreEntry
+ *
+ */
+void contentStoreEntry_Release(ContentStoreEntry **entryPtr);
+
+/**
+ * Returns a pointer to the contained {@link Message}.
+ * The caller must called {@link message_Acquire()} if they want to keep a
+ * reference to the returned message.
+ *
+ * @param storeEntry the ContentStoreEntry from which to retrieve the `Message`
+ * pointer.
+ * @return the address of the `Message` contained in the storeEntry.
+ * @see message_Acquire
+ */
+Message *contentStoreEntry_GetMessage(const ContentStoreEntry *storeEntry);
+
+/**
+ * Return true if the message stored in this `ContentStoreEntry` has an
+ * ExpiryTime.
+ *
+ * @param storeEntry the ContentStoreEntry containing the message.
+ * @return true if the referenced message has an ExpiryTime. False, otherwise.
+ */
+bool contentStoreEntry_HasExpiryTimeTicks(const ContentStoreEntry *storeEntry);
+
+/**
+ * Return the ExpiryTime stored in this `ContentStoreEntry`.
+ *
+ * @param storeEntry the ContentStoreEntry from which to retrieve the `Message`
+ * pointer.
+ * @return the address of the `Message` contained in the storeEntry.
+ */
+uint64_t contentStoreEntry_GetExpiryTimeTicks(
+ const ContentStoreEntry *storeEntry);
+
+/**
+ * A signum function comparing two `ContentStoreEntry` instances, using their
+ * ExpiryTime and, if necessary, the addresses of the referenced Message. In
+ * other words, if two ContentStoreEntries have the same ExpiryTime, the
+ * comparison will then be made on the memory addresses of the Messages
+ * referenced by the ContentStoreEntrys. So, the only way two ContentStoreEntrys
+ * will compare equally (0) is if they both have the same ExpiryTime and
+ * reference the same Message.
+ *
+ * Used to determine the ordering relationship of two `ContentStoreEntry`
+ * instances. This is used by the {@link ListTimeOrdered} to keep a list of
+ * ContentStoreEntrys, sorted by ExpiryTime.
+ *
+ * @param [in] storeEntry1 A pointer to a `ContentStoreEntry` instance.
+ * @param [in] storeEntry2 A pointer to a `ContentStoreEntry` instance to be
+ * compared to `storeEntry1`.
+ *
+ * @return 0 if `storeEntry1` and `storeEntry2` are equivalent
+ * @return < 0 if `storeEntry1` < `storeEntry2`
+ * @return > 0 if `storeEntry1` > `storeEntry2`
+ *
+ * Example:
+ * @code
+ * {
+ * ContentStoreEntry *entry1 = contentStoreEntry_Create(...);
+ * ContentStoreEntry *entry2 = contentStoreEntry_Create(...);
+ *
+ * int val = contentStoreEntry_CompareExpiryTime(entry1, entry2);
+ * if (val < 0) {
+ * // entry1 has a lower ExpiryTime, or the same ExpiryTime as entry2
+ * and a different message. } else if (val > 0) {
+ * // entry2 has a lower ExpiryTime, or the same ExpiryTime as entry1
+ * and a different message. } else {
+ * // entry1 and entry2 have the same ExpiryTime AND the same message.
+ * }
+ *
+ * contentStoreEntry_Release(&entry1);
+ * contentStoreEntry_Release(&entry2);
+ *
+ * }
+ * @endcode
+ */
+int contentStoreEntry_CompareExpiryTime(const ContentStoreEntry *storeEntry1,
+ const ContentStoreEntry *storeEntry2);
+
+/**
+ * Move this entry to the head of the LRU list
+ *
+ * Moves the entry to the head of the LRU list it was created with
+ *
+ * @param [in] storeEntry An allocated ContenstoreEntry
+ */
+void contentStoreEntry_MoveToHead(ContentStoreEntry *storeEntry);
+#endif // contentStoreEntry_h
diff --git a/hicn-light/src/content_store/contentStoreInterface.c b/hicn-light/src/content_store/contentStoreInterface.c
new file mode 100755
index 0000000..a420416
--- /dev/null
+++ b/hicn-light/src/content_store/contentStoreInterface.c
@@ -0,0 +1,57 @@
+/*
+ * 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 <src/config.h>
+#include <stdio.h>
+
+#include <src/content_store/contentStoreInterface.h>
+
+void contentStoreInterface_Release(ContentStoreInterface **storeImplPtr) {
+ (*storeImplPtr)->release(storeImplPtr);
+}
+
+bool contentStoreInterface_PutContent(ContentStoreInterface *storeImpl,
+ Message *content,
+ uint64_t currentTimeTicks) {
+ return storeImpl->putContent(storeImpl, content, currentTimeTicks);
+}
+
+bool contentStoreInterface_RemoveContent(ContentStoreInterface *storeImpl,
+ Message *content) {
+ return storeImpl->removeContent(storeImpl, content);
+}
+
+Message *contentStoreInterface_MatchInterest(ContentStoreInterface *storeImpl,
+ Message *interest,
+ uint64_t currentTimeTicks) {
+ return storeImpl->matchInterest(storeImpl, interest, currentTimeTicks);
+}
+
+size_t contentStoreInterface_GetObjectCapacity(
+ ContentStoreInterface *storeImpl) {
+ return storeImpl->getObjectCapacity(storeImpl);
+}
+
+size_t contentStoreInterface_GetObjectCount(ContentStoreInterface *storeImpl) {
+ return storeImpl->getObjectCount(storeImpl);
+}
+
+void contentStoreInterface_Log(ContentStoreInterface *storeImpl) {
+ storeImpl->log(storeImpl);
+}
+
+void *contentStoreInterface_GetPrivateData(ContentStoreInterface *storeImpl) {
+ return storeImpl->_privateData;
+}
diff --git a/hicn-light/src/content_store/contentStoreInterface.h b/hicn-light/src/content_store/contentStoreInterface.h
new file mode 100755
index 0000000..d73c630
--- /dev/null
+++ b/hicn-light/src/content_store/contentStoreInterface.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef contentStoreInterface_h
+#define contentStoreInterface_h
+
+#include <stdio.h>
+
+#include <src/core/message.h>
+
+typedef struct contentstore_config {
+ size_t objectCapacity;
+} ContentStoreConfig;
+
+typedef struct contentstore_interface ContentStoreInterface;
+
+struct contentstore_interface {
+ /**
+ * Place a Message representing a ContentObject into the ContentStore. If
+ * necessary to make room, remove expired content or content that has exceeded
+ * the Recommended Cache Time.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ * @param content - a pointer to a `Message` to place in the store.
+ * @param currentTimeTicks - the current time, in hicn-light ticks, since the
+ * UTC epoch.
+ */
+ bool (*putContent)(ContentStoreInterface *storeImpl, Message *content,
+ uint64_t currentTimeTicks);
+
+ /**
+ * The function to call to remove content from the ContentStore.
+ * It will Release any references that were created when the content was
+ * placed into the ContentStore.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ * @param content - a pointer to a `Message` to remove from the store.
+ */
+ bool (*removeContent)(ContentStoreInterface *storeImpl, Message *content);
+
+ /**
+ * Given a Message that represents and Interest, try to find a matching
+ * ContentObject.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ * @param interest - a pointer to a `Message` representing the Interest to
+ * match.
+ *
+ * @return a pointer to a Message containing the matching ContentObject
+ * @return NULL if no matching ContentObject was found
+ */
+ Message *(*matchInterest)(ContentStoreInterface *storeImpl, Message *interest,
+ uint64_t currentTimeTicks);
+
+ /**
+ * Return the maximum number of ContentObjects that can be stored in this
+ * ContentStore. This is a raw count, not based on memory size.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ *
+ * @return the maximum number of ContentObjects that can be stored
+ */
+ size_t (*getObjectCapacity)(ContentStoreInterface *storeImpl);
+
+ /**
+ * Return the number of ContentObjects currently stored in the ContentStore.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ *
+ * @return the current number of ContentObjects in the ContentStore
+ */
+ size_t (*getObjectCount)(ContentStoreInterface *storeImpl);
+
+ /**
+ * Log a ContentStore implementation specific version of store-related
+ * information.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ */
+ void (*log)(ContentStoreInterface *storeImpl);
+
+ /**
+ * Acquire a new reference to the specified ContentStore instance. This
+ * reference will eventually need to be released by calling {@link
+ * contentStoreInterface_Release}.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ */
+ ContentStoreInterface *(*acquire)(const ContentStoreInterface *storeImpl);
+
+ /**
+ * Release the ContentStore, which will also Release any references held by
+ * it.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ */
+ void (*release)(ContentStoreInterface **storeImpl);
+
+ /**
+ * A pointer to opaque private data used by the ContentStore instance
+ * represented by this instance of ContentStoreInterface.
+ */
+ void *_privateData;
+};
+
+/**
+ * Place a Message representing a ContentObject into the ContentStore. If
+ * necessary to make room, remove expired content or content that has exceeded
+ * the Recommended Cache Time.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ * @param content - a pointer to a `Message` to place in the store.
+ *
+ * @param currentTimeTicks - the current time, in hicn-light ticks, since the
+ * UTC epoch.
+ */
+bool contentStoreInterface_PutContent(ContentStoreInterface *storeImpl,
+ Message *content,
+ uint64_t currentTimeTicks);
+
+/**
+ * The function to call to remove content from the ContentStore.
+ * It will Release any references that were created when the content was placed
+ * into the ContentStore.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ * @param content - a pointer to a `Message` to remove from the store.
+ */
+bool contentStoreInterface_RemoveContent(ContentStoreInterface *storeImpl,
+ Message *content);
+
+/**
+ * Given a Message that represents and Interest, try to find a matching
+ * ContentObject.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ * @param interest - a pointer to a `Message` representing the Interest to
+ * match.
+ *
+ * @return a pointer to a Message containing the matching ContentObject
+ * @return NULL if no matching ContentObject was found
+ */
+Message *contentStoreInterface_MatchInterest(ContentStoreInterface *storeImpl,
+ Message *interest,
+ uint64_t currentTimeTicks);
+
+/**
+ * Return the maximum number of ContentObjects that can be stored in this
+ * ContentStore. This is a raw count, not based on memory size.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ *
+ * @return the maximum number of ContentObjects that can be stored
+ */
+size_t contentStoreInterface_GetObjectCapacity(
+ ContentStoreInterface *storeImpl);
+
+/**
+ * Return the number of ContentObjects currently stored in the ContentStore.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ *
+ * @return the current number of ContentObjects in the ContentStore
+ */
+size_t contentStoreInterface_GetObjectCount(ContentStoreInterface *storeImpl);
+
+/**
+ * Loga ContentStore implementation specific version of store-related
+ * information.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ */
+void contentStoreInterface_Log(ContentStoreInterface *storeImpl);
+
+/**
+ * Acquire a new reference to the specified ContentStore instance. This
+ * reference will eventually need to be released by calling {@link
+ * contentStoreInterface_Release}.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ */
+ContentStoreInterface *contentStoreInterface_Aquire(
+ const ContentStoreInterface *storeImpl);
+
+/**
+ * Release the ContentStore, which will also Release any references held by it.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ */
+void contentStoreInterface_Release(ContentStoreInterface **storeImplPtr);
+
+/**
+ * Return a pointer to the data private to this implementation of the
+ * ContentStore interface.
+ *
+ * @param storeImpl - a pointer to this ContentStoreInterface instance.
+ */
+void *contentStoreInterface_GetPrivateData(ContentStoreInterface *storeImpl);
+#endif // contentStoreInterface_h
diff --git a/hicn-light/src/content_store/contentStoreLRU.c b/hicn-light/src/content_store/contentStoreLRU.c
new file mode 100755
index 0000000..9b69d51
--- /dev/null
+++ b/hicn-light/src/content_store/contentStoreLRU.c
@@ -0,0 +1,455 @@
+/*
+ * 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 <src/config.h>
+#include <stdio.h>
+#include <sys/queue.h>
+
+#include <parc/algol/parc_DisplayIndented.h>
+#include <parc/algol/parc_HashCodeTable.h>
+#include <parc/algol/parc_Object.h>
+
+#include <src/core/logger.h>
+
+#include <src/content_store/contentStoreLRU.h>
+
+#include <src/content_store/contentStoreEntry.h>
+#include <src/content_store/contentStoreInterface.h>
+#include <src/content_store/listLRU.h>
+#include <src/content_store/listTimeOrdered.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <src/processor/hashTableFunction.h>
+
+typedef struct contentstore_stats {
+ uint64_t countExpiryEvictions;
+ uint64_t countRCTEvictions;
+ uint64_t countLruEvictions;
+ uint64_t countAdds;
+ uint64_t countHits;
+ uint64_t countMisses;
+} _ContentStoreLRUStats;
+
+typedef struct contentstore_lru_data {
+ size_t objectCapacity;
+ size_t objectCount;
+
+ Logger *logger;
+
+ // This LRU is just for keeping track of insertion and access order.
+ ListLru *lru;
+
+ ListTimeOrdered *indexByExpirationTime;
+
+ PARCHashCodeTable *storageByName;
+
+ _ContentStoreLRUStats stats;
+} _ContentStoreLRU;
+
+static void _destroyIndexes(_ContentStoreLRU *store) {
+ if (store->indexByExpirationTime != NULL) {
+ listTimeOrdered_Release(&(store->indexByExpirationTime));
+ }
+
+ if (store->storageByName != NULL) {
+ parcHashCodeTable_Destroy(&(store->storageByName));
+ }
+
+ if (store->lru != NULL) {
+ listLRU_Destroy(&(store->lru));
+ }
+}
+
+static void _contentStoreInterface_Destroy(
+ ContentStoreInterface **storeImplPtr) {
+ _ContentStoreLRU *store = contentStoreInterface_GetPrivateData(*storeImplPtr);
+
+ parcObject_Release((PARCObject **)&store);
+}
+
+static bool _contentStoreLRU_Destructor(_ContentStoreLRU **storePtr) {
+ _ContentStoreLRU *store = *storePtr;
+
+ _destroyIndexes(store);
+ logger_Release(&store->logger);
+
+ return true;
+}
+
+parcObject_Override(_ContentStoreLRU, PARCObject,
+ .destructor = (PARCObjectDestructor *)
+ _contentStoreLRU_Destructor);
+
+parcObject_ExtendPARCObject(ContentStoreInterface,
+ _contentStoreInterface_Destroy, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+
+static parcObject_ImplementAcquire(_contentStoreLRU, ContentStoreInterface);
+static parcObject_ImplementRelease(_contentStoreLRU, ContentStoreInterface);
+
+static void _hashTableFunction_ContentStoreEntryDestroyer(void **dataPtr) {
+ contentStoreEntry_Release((ContentStoreEntry **)dataPtr);
+}
+
+static bool _contentStoreLRU_Init(_ContentStoreLRU *store,
+ ContentStoreConfig *config, Logger *logger) {
+ bool result = false;
+
+ store->logger = logger_Acquire(logger);
+
+ size_t initialSize = config->objectCapacity * 2;
+ memset(&store->stats, 0, sizeof(_ContentStoreLRUStats));
+
+ store->objectCapacity = config->objectCapacity;
+ store->objectCount = 0;
+
+ // initial size must be at least 1 or else the data structures break.
+ initialSize = (initialSize == 0) ? 1 : initialSize;
+
+ store->indexByExpirationTime = listTimeOrdered_Create(
+ (TimeOrderList_KeyCompare *)contentStoreEntry_CompareExpiryTime);
+
+ store->storageByName = parcHashCodeTable_Create_Size(
+ hashTableFunction_MessageNameEquals,
+ hashTableFunction_MessageNameHashCode, NULL,
+ _hashTableFunction_ContentStoreEntryDestroyer, initialSize);
+
+ store->lru = listLRU_Create();
+
+ // If any of the index tables couldn't be allocated, we can't continue.
+ if ((store->indexByExpirationTime == NULL) ||
+ (store->storageByName == NULL) || (store->lru == NULL)) {
+ if (logger_IsLoggable(store->logger, LoggerFacility_Processor,
+ PARCLogLevel_Error)) {
+ logger_Log(store->logger, LoggerFacility_Processor, PARCLogLevel_Error,
+ __func__,
+ "ContentStoreLRU could not be created. Could not allocate all "
+ "index tables.",
+ (void *)store, store->objectCapacity);
+ }
+
+ _destroyIndexes(store);
+ result = false;
+ } else {
+ result = true;
+ }
+ return result;
+}
+
+/**
+ * Remove a ContentStoreEntry from all tables and indices.
+ */
+static void _contentStoreLRU_PurgeStoreEntry(_ContentStoreLRU *store,
+ ContentStoreEntry *entryToPurge) {
+ if (contentStoreEntry_HasExpiryTimeTicks(entryToPurge)) {
+ listTimeOrdered_Remove(store->indexByExpirationTime, entryToPurge);
+ }
+
+ Message *content = contentStoreEntry_GetMessage(entryToPurge);
+
+ // This _Del call will call the Release/Destroy on the ContentStoreEntry,
+ // which will remove it from the LRU as well.
+ parcHashCodeTable_Del(store->storageByName, content);
+
+ store->objectCount--;
+}
+
+static bool _contentStoreLRU_RemoveLeastUsed(_ContentStoreLRU *store) {
+ bool result = false;
+
+ if (store->objectCount > 0) {
+ ListLruEntry *lruEntry = listLRU_PopTail(store->lru);
+ ContentStoreEntry *storeEntry =
+ (ContentStoreEntry *)listLRU_EntryGetData(lruEntry);
+
+ if (logger_IsLoggable(store->logger, LoggerFacility_Processor,
+ PARCLogLevel_Debug)) {
+ logger_Log(
+ store->logger, LoggerFacility_Processor, PARCLogLevel_Debug, __func__,
+ "ContentStore %p evict message %p by LRU (LRU evictions %" PRIu64 ")",
+ (void *)store, (void *)contentStoreEntry_GetMessage(storeEntry),
+ store->stats.countLruEvictions);
+ }
+
+ _contentStoreLRU_PurgeStoreEntry(store, storeEntry);
+
+ result = true;
+ }
+ return result;
+}
+
+static void _evictByStorePolicy(_ContentStoreLRU *store,
+ uint64_t currentTimeInTicks) {
+ // We need to make room. Here's the plan:
+ // 1) Check to see if anything has expired. If so, remove it and we're done.
+ // If not, 2) Remove the least recently used item.
+
+ ContentStoreEntry *entry =
+ listTimeOrdered_GetOldest(store->indexByExpirationTime);
+ if (entry && contentStoreEntry_HasExpiryTimeTicks(entry) &&
+ (currentTimeInTicks > contentStoreEntry_GetExpiryTimeTicks(entry))) {
+ // Found an expired entry. Remove it, and we're done.
+
+ store->stats.countExpiryEvictions++;
+ if (logger_IsLoggable(store->logger, LoggerFacility_Processor,
+ PARCLogLevel_Debug)) {
+ logger_Log(store->logger, LoggerFacility_Processor, PARCLogLevel_Debug,
+ __func__,
+ "ContentStore %p evict message %p by ExpiryTime (ExpiryTime "
+ "evictions %" PRIu64 ")",
+ (void *)store, (void *)contentStoreEntry_GetMessage(entry),
+ store->stats.countExpiryEvictions);
+ }
+
+ _contentStoreLRU_PurgeStoreEntry(store, entry);
+ } else {
+ store->stats.countLruEvictions++;
+ _contentStoreLRU_RemoveLeastUsed(store);
+ }
+}
+
+static bool _contentStoreLRU_PutContent(ContentStoreInterface *storeImpl,
+ Message *content,
+ uint64_t currentTimeTicks)
+
+{
+ bool result = false;
+ _ContentStoreLRU *store =
+ (_ContentStoreLRU *)contentStoreInterface_GetPrivateData(storeImpl);
+ parcAssertNotNull(store, "Parameter store must be non-null");
+ parcAssertNotNull(content, "Parameter objectMessage must be non-null");
+
+ parcAssertTrue(message_GetType(content) == MessagePacketType_ContentObject,
+ "Parameter objectMessage must be a Content Object");
+
+ if (store->objectCapacity == 0) {
+ return false;
+ }
+
+ uint64_t expiryTimeTicks = contentStoreEntry_MaxExpiryTime;
+
+ if (message_HasContentExpiryTime(content)) {
+ expiryTimeTicks = message_GetContentExpiryTimeTicks(content);
+ }
+ // Don't add anything that's already expired or has exceeded RCT.
+ if (currentTimeTicks >= expiryTimeTicks) {
+ return false;
+ }
+
+ if (store->objectCount >= store->objectCapacity) {
+ // Store is full. Need to make room.
+ _evictByStorePolicy(store, currentTimeTicks);
+ }
+
+ // And now add a new entry to the head of the LRU.
+
+ ContentStoreEntry *entry = contentStoreEntry_Create(content, store->lru);
+
+ if (entry != NULL) {
+ if (parcHashCodeTable_Add(store->storageByName, content, entry)) {
+ if (contentStoreEntry_HasExpiryTimeTicks(entry)) {
+ listTimeOrdered_Add(store->indexByExpirationTime, entry);
+ }
+
+ store->objectCount++;
+ store->stats.countAdds++;
+
+ if (logger_IsLoggable(store->logger, LoggerFacility_Processor,
+ PARCLogLevel_Debug)) {
+ logger_Log(store->logger, LoggerFacility_Processor, PARCLogLevel_Debug,
+ __func__,
+ "ContentStoreLRU %p saved message %p (object count %" PRIu64
+ ")",
+ (void *)store, (void *)content, store->objectCount);
+ }
+
+ result = true;
+ } else {
+ // Free what we just created, but did not add. 'entry' has ownership of
+ // 'copy', and so will call _Release() on it
+ contentStoreEntry_Release(&entry);
+
+ if (logger_IsLoggable(store->logger, LoggerFacility_Processor,
+ PARCLogLevel_Warning)) {
+ logger_Log(store->logger, LoggerFacility_Processor,
+ PARCLogLevel_Warning, __func__,
+ "ContentStoreLRU %p failed to add message %p to hash table",
+ (void *)store, (void *)content);
+ }
+ }
+ }
+
+ return result;
+}
+
+static Message *_contentStoreLRU_MatchInterest(ContentStoreInterface *storeImpl,
+ Message *interest,
+ uint64_t currentTimeTicks) {
+ Message *result = NULL;
+
+ _ContentStoreLRU *store =
+ (_ContentStoreLRU *)contentStoreInterface_GetPrivateData(storeImpl);
+
+ parcAssertNotNull(store, "Parameter store must be non-null");
+ parcAssertNotNull(interest, "Parameter interestMessage must be non-null");
+ parcAssertTrue(message_GetType(interest) == MessagePacketType_Interest,
+ "Parameter interestMessage must be an Interest");
+
+ PARCHashCodeTable *table;
+ table = store->storageByName;
+
+ ContentStoreEntry *storeEntry = parcHashCodeTable_Get(table, interest);
+
+ bool foundEntry = false;
+
+ if (storeEntry) {
+ if (contentStoreEntry_HasExpiryTimeTicks(storeEntry) &&
+ contentStoreEntry_GetExpiryTimeTicks(storeEntry) < currentTimeTicks) {
+ // the entry is expired, we can remove it
+ _contentStoreLRU_PurgeStoreEntry(store, storeEntry);
+ } else {
+ foundEntry = true;
+ }
+ }
+
+ if (foundEntry) {
+ contentStoreEntry_MoveToHead(storeEntry);
+ result = contentStoreEntry_GetMessage(storeEntry);
+
+ store->stats.countHits++;
+
+ if (logger_IsLoggable(store->logger, LoggerFacility_Processor,
+ PARCLogLevel_Debug)) {
+ logger_Log(store->logger, LoggerFacility_Processor, PARCLogLevel_Debug,
+ __func__,
+ "ContentStoreLRU %p matched interest %p (hits %" PRIu64
+ ", misses %" PRIu64 ")",
+ (void *)store, (void *)interest, store->stats.countHits,
+ store->stats.countMisses);
+ }
+ } else {
+ store->stats.countMisses++;
+
+ if (logger_IsLoggable(store->logger, LoggerFacility_Processor,
+ PARCLogLevel_Debug)) {
+ logger_Log(store->logger, LoggerFacility_Processor, PARCLogLevel_Debug,
+ __func__,
+ "ContentStoreLRU %p missed interest %p (hits %" PRIu64
+ ", misses %" PRIu64 ")",
+ (void *)store, (void *)interest, store->stats.countHits,
+ store->stats.countMisses);
+ }
+ }
+
+ return result;
+}
+
+static bool _contentStoreLRU_RemoveContent(ContentStoreInterface *storeImpl,
+ Message *content) {
+ bool result = false;
+ _ContentStoreLRU *store =
+ (_ContentStoreLRU *)contentStoreInterface_GetPrivateData(storeImpl);
+
+ ContentStoreEntry *storeEntry =
+ parcHashCodeTable_Get(store->storageByName, content);
+
+ if (storeEntry != NULL) {
+ _contentStoreLRU_PurgeStoreEntry(store, storeEntry);
+ result = true;
+ }
+
+ return result;
+}
+
+static void _contentStoreLRU_Log(ContentStoreInterface *storeImpl) {
+ _ContentStoreLRU *store =
+ (_ContentStoreLRU *)contentStoreInterface_GetPrivateData(storeImpl);
+
+ logger_Log(store->logger, LoggerFacility_Processor, PARCLogLevel_All,
+ __func__,
+ "ContentStoreLRU @%p {count = %zu, capacity = %zu {"
+ "stats = @%p {adds = %" PRIu64 ", hits = %" PRIu64
+ ", misses = %" PRIu64 ", LRUEvictons = %" PRIu64
+ ", ExpiryEvictions = %" PRIu64 ", RCTEvictions = %" PRIu64 "} }",
+ store, store->objectCount, store->objectCapacity, &store->stats,
+ store->stats.countAdds, store->stats.countHits,
+ store->stats.countMisses, store->stats.countLruEvictions,
+ store->stats.countExpiryEvictions, store->stats.countRCTEvictions);
+}
+
+static size_t _contentStoreLRU_GetObjectCapacity(
+ ContentStoreInterface *storeImpl) {
+ _ContentStoreLRU *store =
+ (_ContentStoreLRU *)contentStoreInterface_GetPrivateData(storeImpl);
+ return store->objectCapacity;
+}
+
+static size_t _contentStoreLRU_GetObjectCount(
+ ContentStoreInterface *storeImpl) {
+ _ContentStoreLRU *store =
+ (_ContentStoreLRU *)contentStoreInterface_GetPrivateData(storeImpl);
+ return store->objectCount;
+}
+
+static size_t _contentStoreLRU_SetObjectCapacity(
+ ContentStoreInterface *storeImpl, size_t newCapacity) {
+ _ContentStoreLRU *store =
+ (_ContentStoreLRU *)contentStoreInterface_GetPrivateData(storeImpl);
+ return store->objectCapacity = newCapacity;
+}
+
+ContentStoreInterface *contentStoreLRU_Create(ContentStoreConfig *config,
+ Logger *logger) {
+ ContentStoreInterface *storeImpl = NULL;
+
+ parcAssertNotNull(logger, "ContentStoreLRU requires a non-NULL logger");
+
+ storeImpl = parcObject_CreateAndClearInstance(ContentStoreInterface);
+
+ if (storeImpl != NULL) {
+ storeImpl->_privateData =
+ parcObject_CreateAndClearInstance(_ContentStoreLRU);
+
+ if (_contentStoreLRU_Init(storeImpl->_privateData, config, logger)) {
+ storeImpl->putContent = &_contentStoreLRU_PutContent;
+ storeImpl->removeContent = &_contentStoreLRU_RemoveContent;
+
+ storeImpl->matchInterest = &_contentStoreLRU_MatchInterest;
+
+ storeImpl->getObjectCount = &_contentStoreLRU_GetObjectCount;
+ storeImpl->getObjectCapacity = &_contentStoreLRU_GetObjectCapacity;
+
+ storeImpl->log = &_contentStoreLRU_Log;
+
+ storeImpl->acquire = &_contentStoreLRU_Acquire;
+ storeImpl->release = &_contentStoreLRU_Release;
+
+ // Initialize from the config passed to us.
+ _contentStoreLRU_SetObjectCapacity(storeImpl, config->objectCapacity);
+
+ if (logger_IsLoggable(logger, LoggerFacility_Processor,
+ PARCLogLevel_Info)) {
+ logger_Log(logger, LoggerFacility_Processor, PARCLogLevel_Info,
+ __func__, "ContentStoreLRU %p created with capacity %zu",
+ (void *)storeImpl,
+ contentStoreInterface_GetObjectCapacity(storeImpl));
+ }
+ }
+ } else {
+ parcObject_Release((void **)&storeImpl);
+ }
+
+ return storeImpl;
+}
diff --git a/hicn-light/src/content_store/contentStoreLRU.h b/hicn-light/src/content_store/contentStoreLRU.h
new file mode 100755
index 0000000..3c0815e
--- /dev/null
+++ b/hicn-light/src/content_store/contentStoreLRU.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.
+ */
+
+#ifndef contentStoreLRU_h
+#define contentStoreLRU_h
+
+#include <src/content_store/contentStoreInterface.h>
+#include <src/core/logger.h>
+#include <stdio.h>
+
+/**
+ * Create and Initialize an instance of contentStoreLRU. A newly allocated
+ * {@link ContentStoreInterface} object is initialized and returned. It must
+ * eventually be released by calling {@link contentStoreInterface_Release}.
+ *
+ *
+ * @param config An instance of `ContentStoreConfig`, specifying options to be
+ * applied by the underlying contentStoreLRU instance.
+ * @param logger An instance of a {@link Logger} to use for logging content
+ * store events.
+ *
+ * @return a newly created contentStoreLRU instance.
+ *
+ */
+ContentStoreInterface *contentStoreLRU_Create(ContentStoreConfig *config,
+ Logger *logger);
+#endif // contentStoreLRU_h
diff --git a/hicn-light/src/content_store/listLRU.c b/hicn-light/src/content_store/listLRU.c
new file mode 100755
index 0000000..42b491d
--- /dev/null
+++ b/hicn-light/src/content_store/listLRU.c
@@ -0,0 +1,133 @@
+/*
+ * 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 <src/config.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sys/queue.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/content_store/listLRU.h>
+
+struct list_lru_entry {
+ void *userData;
+
+ // always set to the list
+ ListLru *parentList;
+
+ // indicates if the Entry is currently in the list
+ bool inList;
+
+ TAILQ_ENTRY(list_lru_entry) list;
+};
+
+// this defines the TAILQ structure so we can access the tail pointer
+TAILQ_HEAD(lru_s, list_lru_entry);
+
+struct list_lru {
+ struct lru_s head;
+ size_t itemsInList;
+};
+
+void listLRU_EntryDestroy(ListLruEntry **entryPtr) {
+ parcAssertNotNull(entryPtr,
+ "Parameter entryPtr must be non-null double pointer");
+
+ ListLruEntry *entry = *entryPtr;
+ if (entry->inList) {
+ TAILQ_REMOVE(&entry->parentList->head, entry, list);
+ parcAssertTrue(
+ entry->parentList->itemsInList > 0,
+ "Invalid state, removed entry from list, but itemsInList is 0");
+ entry->parentList->itemsInList--;
+ }
+
+ parcMemory_Deallocate((void **)&entry);
+ *entryPtr = NULL;
+}
+
+void listLRU_EntryMoveToHead(ListLruEntry *entry) {
+ parcAssertNotNull(entry, "Parameter entry must be non-null");
+
+ TAILQ_REMOVE(&entry->parentList->head, entry, list);
+ TAILQ_INSERT_HEAD(&entry->parentList->head, entry, list);
+}
+
+void *listLRU_EntryGetData(ListLruEntry *entry) { return entry->userData; }
+
+ListLru *listLRU_Create() {
+ ListLru *list = parcMemory_AllocateAndClear(sizeof(ListLru));
+ parcAssertNotNull(list, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(ListLru));
+ list->itemsInList = 0;
+ TAILQ_INIT(&list->head);
+ return list;
+}
+
+void listLRU_Destroy(ListLru **lruPtr) {
+ parcAssertNotNull(lruPtr, "Parameter lruPtr must be non-null double pointer");
+
+ ListLru *lru = *lruPtr;
+
+ ListLruEntry *entry = TAILQ_FIRST(&lru->head);
+ while (entry != NULL) {
+ ListLruEntry *next = TAILQ_NEXT(entry, list);
+ listLRU_EntryDestroy(&entry);
+ entry = next;
+ }
+
+ parcMemory_Deallocate((void **)&lru);
+ *lruPtr = NULL;
+}
+
+ListLruEntry *listLRU_NewHeadEntry(ListLru *lru, void *data) {
+ parcAssertNotNull(lru, "Parameter lru must be non-null");
+ parcAssertNotNull(data, "Parameter data must be non-null");
+
+ ListLruEntry *entry = parcMemory_AllocateAndClear(sizeof(ListLruEntry));
+ parcAssertNotNull(entry, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(ListLruEntry));
+ entry->userData = data;
+ entry->parentList = lru;
+ entry->inList = true;
+
+ TAILQ_INSERT_HEAD(&lru->head, entry, list);
+ lru->itemsInList++;
+
+ return entry;
+}
+
+ListLruEntry *listLRU_PopTail(ListLru *lru) {
+ parcAssertNotNull(lru, "Parameter lru must be non-null");
+
+ ListLruEntry *entry = TAILQ_LAST(&lru->head, lru_s);
+
+ if (entry) {
+ parcAssertTrue(
+ lru->itemsInList > 0,
+ "Invalid state, removed entry from list, but itemsInList is 0");
+ lru->itemsInList--;
+ TAILQ_REMOVE(&lru->head, entry, list);
+ entry->inList = false;
+ }
+
+ return entry;
+}
+
+size_t listLRU_Length(const ListLru *lru) {
+ parcAssertNotNull(lru, "Parameter lru must be non-null");
+ return lru->itemsInList;
+}
diff --git a/hicn-light/src/content_store/listLRU.h b/hicn-light/src/content_store/listLRU.h
new file mode 100755
index 0000000..75f698b
--- /dev/null
+++ b/hicn-light/src/content_store/listLRU.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file listLRU.h
+ * @brief Maintains an LRU for the content store
+ *
+ * An LRU list is make up of LRU entries. The entries are bound to the list.
+ * The user of the list is reponsible for knowing when there's too many things
+ * and wants to remove one. The LRU list will grow without bound otherwise.
+ *
+ * The LRU list is meant to be used as an auxiliary data structure, not the
+ * primary storage of data elements.
+ *
+ */
+
+#ifndef listLRU_h
+#define listLRU_h
+
+struct list_lru_entry;
+typedef struct list_lru_entry ListLruEntry;
+
+struct list_lru;
+typedef struct list_lru ListLru;
+
+/**
+ * @function lruEntry_Destroy
+ * @abstract Destroys and element. This will also remove it from the list.
+ */
+void listLRU_EntryDestroy(ListLruEntry **entryPtr);
+
+/**
+ * @function listLRU_EntryMoveToHead
+ * @abstract move an element to head
+ */
+void listLRU_EntryMoveToHead(ListLruEntry *entry);
+
+/**
+ * @function lruEntry_GetData
+ * @abstract Returns the user-supplied opaque data when the entry was created
+ */
+void *listLRU_EntryGetData(ListLruEntry *entry);
+
+/**
+ * @function listLRU_Create
+ * @abstract Creates a new Least-Recently-Used list
+ */
+ListLru *listLRU_Create();
+
+/**
+ * @function listLRU_Destroy
+ * @abstract Destroys a list and frees all the elements in it
+ */
+void listLRU_Destroy(ListLru **listPtr);
+
+/**
+ * Returns the number of items in the list
+ *
+ * @param [in] lru An allocated ListLru
+ * @retval number The number of items in the LRU list
+ */
+size_t listLRU_Length(const ListLru *lru);
+
+/**
+ * @function listLRU_NewHeadEntry
+ * @abstract Creates a new entry for the list. It is inserted at the head of
+ * the list.
+ */
+ListLruEntry *listLRU_NewHeadEntry(ListLru *lru, void *data);
+
+/**
+ * @function listLRU_PopTail
+ * @abstract Removes the tail element from the list and returns it to the user
+ * @discussion
+ * Pops the tail element. The user should examine its data to destroy their
+ * tail object, then call <code>LruEntry_Destroy()</code> to free the
+ * LRU entry.
+ *
+ * @return The tail element, or NULL for an empty list
+ */
+ListLruEntry *listLRU_PopTail(ListLru *list);
+#endif // listLRU_h
diff --git a/hicn-light/src/content_store/listTimeOrdered.c b/hicn-light/src/content_store/listTimeOrdered.c
new file mode 100755
index 0000000..44697d2
--- /dev/null
+++ b/hicn-light/src/content_store/listTimeOrdered.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <parc/assert/parc_Assert.h>
+#include <src/config.h>
+#include <src/content_store/listTimeOrdered.h>
+
+#include <parc/algol/parc_Object.h>
+#include <parc/algol/parc_TreeRedBlack.h>
+
+/**
+ * A list of ContentStoreEntrys, kept in sorted order by time. The ordering is
+ * calculated by a key compare function (e.g. {@link TimeOrderList_KeyCompare}),
+ * passed in.
+ *
+ * This container does not hold references to the objects that it contains. In
+ * other words, it does not Acquire() the Messages that are placed in it. That
+ * reference count is managed by the owning ContentStore. This is purely an
+ * index, and provides an easy to way index Messages based on a specified time
+ * value. Typically, that would be the Expiration Time.
+ *
+ * It maintains a tree, sorted by the time values passed in to the Add()
+ * function. It does not manage capacity, and can grow uncontrollably if the
+ * owning ContentStore does not manage it. Items are indexed first by time, then
+ * address of the Message (just as a distringuishing attribute). This allows us
+ * to store multiple items with the same expiration time.
+ */
+
+struct list_timeordered {
+ PARCTreeRedBlack *timeOrderedTree;
+};
+
+static void _finalRelease(ListTimeOrdered **listP) {
+ ListTimeOrdered *list = *listP;
+ parcTreeRedBlack_Destroy(&list->timeOrderedTree);
+}
+
+parcObject_ExtendPARCObject(ListTimeOrdered, _finalRelease, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+
+parcObject_ImplementAcquire(listTimeOrdered, ListTimeOrdered);
+
+parcObject_ImplementRelease(listTimeOrdered, ListTimeOrdered);
+
+ListTimeOrdered *listTimeOrdered_Create(
+ TimeOrderList_KeyCompare *keyCompareFunction) {
+ ListTimeOrdered *result = parcObject_CreateInstance(ListTimeOrdered);
+ if (NULL != result) {
+ result->timeOrderedTree =
+ parcTreeRedBlack_Create(keyCompareFunction, // keyCompare
+ NULL, // keyFree
+ NULL, // keyCopy
+ NULL, // valueEquals
+ NULL, // valueFree
+ NULL); // valueCopy
+ }
+ return result;
+}
+
+void listTimeOrdered_Add(ListTimeOrdered *list, ContentStoreEntry *entry) {
+ parcTreeRedBlack_Insert(list->timeOrderedTree, entry, entry);
+}
+
+ContentStoreEntry *listTimeOrdered_GetOldest(ListTimeOrdered *list) {
+ return parcTreeRedBlack_FirstKey(list->timeOrderedTree);
+}
+
+bool listTimeOrdered_Remove(ListTimeOrdered *list,
+ ContentStoreEntry *storeEntry) {
+ bool result = false;
+
+ ContentStoreEntry *entry = (ContentStoreEntry *)parcTreeRedBlack_Remove(
+ list->timeOrderedTree, storeEntry);
+ if (entry != NULL) {
+ result = true;
+ }
+ return result;
+}
+
+size_t listTimeOrdered_Length(ListTimeOrdered *list) {
+ return (size_t)parcTreeRedBlack_Size(list->timeOrderedTree);
+}
diff --git a/hicn-light/src/content_store/listTimeOrdered.h b/hicn-light/src/content_store/listTimeOrdered.h
new file mode 100755
index 0000000..b18bd16
--- /dev/null
+++ b/hicn-light/src/content_store/listTimeOrdered.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef listTimeOrdered_h
+#define listTimeOrdered_h
+
+#include <parc/algol/parc_TreeRedBlack.h>
+#include <src/content_store/contentStoreEntry.h>
+#include <src/core/message.h>
+#include <stdio.h>
+
+struct list_timeordered;
+typedef struct list_timeordered ListTimeOrdered;
+
+/**
+ * A signum function that takes two instances of ContentStoreEntrys and
+ * returns a value based on their relative values.
+ */
+typedef PARCTreeRedBlack_KeyCompare TimeOrderList_KeyCompare;
+
+/**
+ * Create a new instance of `ListTimeOrdered` that will maintain the order of
+ * its list items using the supplied `keyCompareFunction`.
+ *
+ * The newly created `ListTimeOrdered` must eventually be released by calling
+ * {@link listTimeOrdered_Release}.
+ *
+ * @param keyCompareFunction the signum comparison function to use to sort
+ * stored items.
+ * @return a new instance of `TimeOrderList`.
+ * @return NULL if the new instance couldn't be created.
+ *
+ */
+ListTimeOrdered *listTimeOrdered_Create(
+ TimeOrderList_KeyCompare *keyCompareFunction);
+
+/**
+ * Release a previously acquired reference to the specified instance,
+ * decrementing the reference count for the instance.
+ *
+ * The pointer to the instance is set to NULL as a side-effect of this function.
+ *
+ * If the invocation causes the last reference to the instance to be released,
+ * the instance is deallocated and the instance's implementation will perform
+ * additional cleanup and release other privately held references.
+ *
+ */
+void listTimeOrdered_Release(ListTimeOrdered **listP);
+
+/**
+ * Add a {@link ContentStoreEntry} instance to the specified list. Note that a
+ * new refernece to the specified `storeEntry` is not acquired.
+ *
+ * @param list the list instance into which to add the specified storeEntry.
+ * @param storeEntry the storeEntry instance to add.
+ *
+ */
+void listTimeOrdered_Add(ListTimeOrdered *list, ContentStoreEntry *storeEntry);
+
+/**
+ * Remove a {@link ContentStoreEntry} instance from the specified list.
+ *
+ * @param list the list instance from which to remove the specified storeEntry.
+ * @param storeEntry the storeEntry instance to remove.
+ * @return true if the removal was succesful.
+ * @return false if the removal was not succesful.
+ *
+ */
+bool listTimeOrdered_Remove(ListTimeOrdered *list,
+ ContentStoreEntry *storeEntry);
+
+/**
+ * Return the oldest {@link ContentStoreEntry} instance in this list. That is,
+ * the one with the smallest time value.
+ *
+ * @param list the list instance from which to retrieve the oldest storeEntry.
+ * @param the oldest `ContentStoreEntry` in the list
+ * @param NULL if no `ContentStoreEntry` was available.
+ *
+ */
+ContentStoreEntry *listTimeOrdered_GetOldest(ListTimeOrdered *list);
+
+/**
+ * Return the number of items currently stored in the list.
+ *
+ * @param list the `ListTimeOrdered` instance from which to retrieve the count.
+ * @return the number of items in the list.
+ *
+ */
+size_t listTimeOrdered_Length(ListTimeOrdered *list);
+#endif /* defined(listTimeOrdered_h) */
diff --git a/hicn-light/src/core/CMakeLists.txt b/hicn-light/src/core/CMakeLists.txt
new file mode 100755
index 0000000..1d7dc03
--- /dev/null
+++ b/hicn-light/src/core/CMakeLists.txt
@@ -0,0 +1,55 @@
+# 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}/connectionManager.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/ticks.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/connectionList.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/connectionTable.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/connection.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/forwarder.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/logger.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/dispatcher.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/message.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/messagePacketType.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/numberSet.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/streamBuffer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/system.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/mapMe.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/wldr.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/messageHandler.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/nameBitvector.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/name.h
+)
+
+list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/connection.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/connectionList.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/connectionManager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/connectionTable.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/dispatcher.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/forwarder.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/logger.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/message.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/numberSet.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/streamBuffer.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/mapMe.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wldr.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/nameBitvector.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/name.c
+)
+
+set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/hicn-light/src/core/connection.c b/hicn-light/src/core/connection.c
new file mode 100755
index 0000000..073b726
--- /dev/null
+++ b/hicn-light/src/core/connection.c
@@ -0,0 +1,265 @@
+/*
+ * 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 <limits.h>
+#include <src/config.h>
+#include <stdio.h>
+
+#include <src/core/connection.h>
+#include <src/core/messageHandler.h>
+#include <src/core/ticks.h>
+#include <src/core/wldr.h>
+#include <src/io/addressPair.h>
+#include <src/io/ioOperations.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+
+struct connection {
+ const AddressPair *addressPair;
+ IoOperations *ops;
+
+ unsigned refCount;
+
+ bool probing_active;
+ unsigned probing_interval;
+ unsigned counter;
+ Ticks last_sent;
+ Ticks delay;
+
+ bool wldrAutoStart; // if true, wldr can be set automatically
+ // by default this value is set to true.
+ // if wldr is activated using a command (config
+ // file/hicnLightControl) this value is set to false so
+ // that a base station can not disable wldr at the client
+ Wldr *wldr;
+};
+
+Connection *connection_Create(IoOperations *ops) {
+ parcAssertNotNull(ops, "Parameter ops must be non-null");
+ Connection *conn = parcMemory_AllocateAndClear(sizeof(Connection));
+ parcAssertNotNull(conn, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(Connection));
+ conn->addressPair = ioOperations_GetAddressPair(ops);
+ conn->ops = ops;
+ conn->refCount = 1;
+ conn->wldr = NULL;
+ conn->probing_active = false;
+
+ conn->wldrAutoStart = true;
+ conn->probing_interval = 0;
+ conn->counter = 0;
+ conn->last_sent = 0;
+ conn->delay = INT_MAX;
+ return conn;
+}
+
+Connection *connection_Acquire(Connection *connection) {
+ parcAssertNotNull(connection, "Parameter conn must be non-null");
+ connection->refCount++;
+ return connection;
+}
+
+void connection_Release(Connection **connectionPtr) {
+ parcAssertNotNull(connectionPtr, "Parameter must be non-null double pointer");
+ parcAssertNotNull(*connectionPtr,
+ "Parameter must dereference to non-null pointer");
+ Connection *conn = *connectionPtr;
+
+ parcAssertTrue(
+ conn->refCount > 0,
+ "Invalid state, connection reference count should be positive, got 0.");
+ conn->refCount--;
+ if (conn->refCount == 0) {
+ // don't destroy addressPair, its part of ops.
+ ioOperations_Release(&conn->ops);
+ if (conn->wldr != NULL) {
+ wldr_Destroy(&(conn->wldr));
+ }
+ parcMemory_Deallocate((void **)&conn);
+ }
+ *connectionPtr = NULL;
+}
+
+bool connection_Send(const Connection *conn, Message *message) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ parcAssertNotNull(message, "Parameter message must be non-null");
+
+ if (ioOperations_IsUp(conn->ops)) {
+ if (message_GetType(message) == MessagePacketType_ContentObject) {
+ uint8_t connectionId = (uint8_t)connection_GetConnectionId(conn);
+ message_UpdatePathLabel(message, connectionId);
+ }
+ if (conn->wldr != NULL) {
+ wldr_SetLabel(conn->wldr, message);
+ } else {
+ message_ResetWldrLabel(message);
+ }
+ return ioOperations_Send(conn->ops, NULL, message);
+ }
+ return false;
+}
+
+static void _sendProbe(Connection *conn, unsigned probeType, uint8_t *message) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+
+ if (probeType == PACKET_TYPE_PROBE_REQUEST) {
+ Ticks now = ioOperations_SendProbe(conn->ops, probeType, message);
+ if (now != 0) {
+ conn->last_sent = now;
+ }
+ } else {
+ ioOperations_SendProbe(conn->ops, probeType, message);
+ }
+}
+
+void connection_Probe(Connection *conn) {
+ _sendProbe(conn, PACKET_TYPE_PROBE_REQUEST, NULL);
+}
+
+void connection_HandleProbe(Connection *conn, uint8_t *probe,
+ Ticks actualTime) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ parcAssertNotNull(probe, "Parameter pkt must be non-null");
+
+ uint8_t probeType = messageHandler_GetProbePacketType(probe);
+ if (probeType == PACKET_TYPE_PROBE_REQUEST) {
+ _sendProbe(conn, PACKET_TYPE_PROBE_REPLY, probe);
+ } else if (probeType == PACKET_TYPE_PROBE_REPLY) {
+ Ticks delay = actualTime - conn->last_sent;
+ if (delay == 0) {
+ delay = 1;
+ }
+ if (delay < conn->delay) {
+ conn->delay = delay;
+ }
+ } else {
+ printf("receivde unkwon probe type\n");
+ }
+}
+
+uint64_t connection_GetDelay(Connection *conn) { return (uint64_t)conn->delay; }
+
+IoOperations *connection_GetIoOperations(const Connection *conn) {
+ return conn->ops;
+}
+
+unsigned connection_GetConnectionId(const Connection *conn) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ return ioOperations_GetConnectionId(conn->ops);
+}
+
+const AddressPair *connection_GetAddressPair(const Connection *conn) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ return ioOperations_GetAddressPair(conn->ops);
+}
+
+bool connection_IsUp(const Connection *conn) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ if (!conn->ops) return false;
+ return ioOperations_IsUp(conn->ops);
+}
+
+bool connection_IsLocal(const Connection *conn) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ return ioOperations_IsLocal(conn->ops);
+}
+
+const void *connection_Class(const Connection *conn) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ return ioOperations_Class(conn->ops);
+}
+
+bool connection_ReSend(const Connection *conn, Message *message,
+ bool notification) {
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ parcAssertNotNull(message, "Parameter message must be non-null");
+ bool res = false;
+
+ if (connection_IsUp(conn)) {
+ // here the wldr header is alreay set: this message is a retransmission or a
+ // notification
+
+ // we need to recompiute the path lable since we always store a pointer to
+ // the same message if this message will be sent again to someonelse, the new
+ // path label must be computed starting from the orignal labelorignal label.
+ // Notice that we heve the same problem in case of PIT aggregation. That case
+ // is handled insied the MessageProcessor. This is specific to WLDR
+ // retransmittions. This is done only for data packets
+
+ if (message_GetType(message) == MessagePacketType_ContentObject) {
+ uint8_t connectionId = (uint8_t)connection_GetConnectionId(conn);
+ uint32_t old_path_label = message_GetPathLabel(message);
+ message_UpdatePathLabel(message, connectionId);
+
+ res = ioOperations_Send(conn->ops, NULL, message);
+
+ message_SetPathLabel(message, old_path_label);
+ } else {
+ res = ioOperations_Send(conn->ops, NULL, message);
+ }
+ }
+
+ if (notification) {
+ // the notification is never destroyed
+ message_Release(&message);
+ }
+
+ return res;
+}
+
+void connection_AllowWldrAutoStart(Connection *conn, bool allow) {
+ conn->wldrAutoStart = allow;
+}
+
+void connection_EnableWldr(Connection *conn) {
+ if (!connection_IsLocal(conn)) {
+ if (conn->wldr == NULL) {
+ printf("----------------- enable wldr\n");
+ conn->wldr = wldr_Init();
+ }
+ }
+}
+
+void connection_DisableWldr(Connection *conn) {
+ if (!connection_IsLocal(conn)) {
+ if (conn->wldr != NULL) {
+ printf("----------------- disable wldr\n");
+ wldr_Destroy(&(conn->wldr));
+ conn->wldr = NULL;
+ }
+ }
+}
+
+bool connection_HasWldr(const Connection *conn) {
+ if (conn->wldr == NULL) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool connection_WldrAutoStartAllowed(const Connection *conn) {
+ return conn->wldrAutoStart;
+}
+
+void connection_DetectLosses(Connection *conn, Message *message) {
+ if (conn->wldr != NULL) wldr_DetectLosses(conn->wldr, conn, message);
+}
+
+void connection_HandleWldrNotification(Connection *conn, Message *message) {
+ if (conn->wldr != NULL)
+ wldr_HandleWldrNotification(conn->wldr, conn, message);
+}
diff --git a/hicn-light/src/core/connection.h b/hicn-light/src/core/connection.h
new file mode 100755
index 0000000..b5c7035
--- /dev/null
+++ b/hicn-light/src/core/connection.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file connection.h
+ * @brief Wrapper for different types of connections
+ *
+ * A connection wraps a specific set of {@link IoOperations}. Those operations
+ * allow for input and output. Connections get stored in the Connection Table.
+ *
+ */
+
+#ifndef connection_h
+#define connection_h
+#include <src/config.h>
+#include <src/io/ioOperations.h>
+#include <src/utils/address.h>
+
+// packet types for probing
+#define PACKET_TYPE_PROBE_REQUEST 5
+#define PACKET_TYPE_PROBE_REPLY 6
+
+struct connection;
+typedef struct connection Connection;
+
+/**
+ * Creates a connection object.
+ */
+Connection *connection_Create(IoOperations *ops);
+
+/**
+ * @function connection_Release
+ * @abstract Releases a reference count, destroying on last release
+ * @discussion
+ * Only frees the memory on the final reference count. The pointer will
+ * always be NULL'd.
+ */
+void connection_Release(Connection **connectionPtr);
+
+/**
+ * @function connection_Acquire
+ * @abstract A reference counted copy.
+ * @discussion
+ * A shallow copy, they share the same memory.
+ */
+Connection *connection_Acquire(Connection *connection);
+
+/**
+ * @function connection_Send
+ * @abstract Sends the message on the connection
+ * @return true if message sent, false if connection not up
+ */
+bool connection_Send(const Connection *conn, Message *message);
+
+/**
+ * Return the `IoOperations` instance associated with the specified `Connection`
+ * instance.
+ * @param [in] connection The allocated connection
+ * @return a pointer to the IoOperations instance associated by th specified
+ * connection.
+ */
+IoOperations *connection_GetIoOperations(const Connection *conn);
+
+/**
+ * Returns the unique identifier of the connection
+ * Calls the underlying IoOperations to fetch the connection id
+ * @param [in] connection The allocated connection
+ * @return unsigned The unique connection id
+ */
+unsigned connection_GetConnectionId(const Connection *conn);
+
+/**
+ * Returns the (remote, local) address pair that describes the connection
+ * @param [in] connection The allocated connection
+ * @return non-null The connection's remote and local address
+ * @return null Should never return NULL
+ */
+const AddressPair *connection_GetAddressPair(const Connection *conn);
+
+/**
+ * Checks if the connection is in the "up" state
+ * @param [in] connection The allocated connection
+ * @return true The connection is in the "up" state
+ * @return false The connection is not in the "up" state
+ */
+bool connection_IsUp(const Connection *conn);
+
+/**
+ * Checks if the connection is to a Local/Loopback address
+ *
+ * A local connection is PF_LOCAL (PF_UNIX) and a loopback connection is
+ * 127.0.0.0/8 or ::1 for IPv6.
+ *
+ * @param [in] connection The allocated connection
+ *
+ * @retval true The connection is local or loopback
+ * @retval false The connection is not local or loopback
+ */
+bool connection_IsLocal(const Connection *conn);
+
+/**
+ * Returns an opaque pointer representing the class of the Io Operations
+ *
+ * Returns an opaque pointer that an implementation can use to detect if
+ * the connection is based on that class.
+ *
+ * @param [in] conn The Connection to analyze
+ *
+ * @return non-null An opaque pointer for each concrete implementation
+ */
+const void *connection_Class(const Connection *conn);
+
+bool connection_ReSend(const Connection *conn, Message *message,
+ bool notification);
+
+void connection_Probe(Connection *conn);
+
+void connection_HandleProbe(Connection *conn, uint8_t *message,
+ Ticks actualTime);
+
+uint64_t connection_GetDelay(Connection *conn);
+
+void connection_AllowWldrAutoStart(Connection *conn, bool allow);
+
+void connection_EnableWldr(Connection *conn);
+
+void connection_DisableWldr(Connection *conn);
+
+bool connection_HasWldr(const Connection *conn);
+
+bool connection_WldrAutoStartAllowed(const Connection *conn);
+
+void connection_DetectLosses(Connection *conn, Message *message);
+
+void connection_HandleWldrNotification(Connection *conn, Message *message);
+#endif // connection_h
diff --git a/hicn-light/src/core/connectionList.c b/hicn-light/src/core/connectionList.c
new file mode 100755
index 0000000..b2913fa
--- /dev/null
+++ b/hicn-light/src/core/connectionList.c
@@ -0,0 +1,68 @@
+/*
+ * 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 <src/config.h>
+#include <stdio.h>
+
+#include <parc/algol/parc_ArrayList.h>
+#include <parc/algol/parc_Memory.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <src/core/connectionList.h>
+
+struct connection_list {
+ PARCArrayList *listOfConnections;
+};
+
+static void connectionList_ArrayDestroyer(void **voidPtr) {
+ Connection **entryPtr = (Connection **)voidPtr;
+ connection_Release(entryPtr);
+}
+
+ConnectionList *connectionList_Create() {
+ ConnectionList *list = parcMemory_AllocateAndClear(sizeof(ConnectionList));
+ parcAssertNotNull(list, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(ConnectionList));
+ list->listOfConnections = parcArrayList_Create(connectionList_ArrayDestroyer);
+ return list;
+}
+
+void connectionList_Destroy(ConnectionList **listPtr) {
+ parcAssertNotNull(listPtr, "Parameter must be non-null double pointer");
+ parcAssertNotNull(*listPtr, "Parameter must dereference to non-null pointer");
+ ConnectionList *list = *listPtr;
+ parcArrayList_Destroy(&list->listOfConnections);
+ parcMemory_Deallocate((void **)&list);
+ *listPtr = NULL;
+}
+
+void connectionList_Append(ConnectionList *list, Connection *entry) {
+ parcAssertNotNull(list, "Parameter list must be non-null");
+ parcAssertNotNull(entry, "Parameter entry must be non-null");
+
+ parcArrayList_Add(list->listOfConnections, connection_Acquire(entry));
+}
+
+size_t connectionList_Length(const ConnectionList *list) {
+ parcAssertNotNull(list, "Parameter list must be non-null");
+ return parcArrayList_Size(list->listOfConnections);
+}
+
+Connection *connectionList_Get(ConnectionList *list, size_t index) {
+ parcAssertNotNull(list, "Parameter list must be non-null");
+ Connection *original =
+ (Connection *)parcArrayList_Get(list->listOfConnections, index);
+ return original;
+}
diff --git a/hicn-light/src/core/connectionList.h b/hicn-light/src/core/connectionList.h
new file mode 100755
index 0000000..cdca129
--- /dev/null
+++ b/hicn-light/src/core/connectionList.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.
+ */
+
+/**
+ * @file connectionList.h
+ * @brief A typesafe list of Connection objects
+ *
+ * <#Detailed Description#>
+ *
+ */
+
+#ifndef connectionList_h
+#define connectionList_h
+
+struct connection_list;
+typedef struct connection_list ConnectionList;
+
+#include <src/core/connection.h>
+
+/**
+ * Creates a lis of Connection
+ *
+ * @return non-null An allocated list
+ * @return null An error
+ */
+ConnectionList *connectionList_Create(void);
+
+/**
+ * Destroys the list and all objects inside it
+ */
+void connectionList_Destroy(ConnectionList **listPtr);
+
+/**
+ * @function connectionList_Append
+ * @abstract Adds a connection entry to the list.
+ * @discussion
+ * Acquires a reference to the passed entry and stores it in the list.
+ */
+void connectionList_Append(ConnectionList *list, Connection *entry);
+
+/**
+ * Returns the number of items on the list
+ * @param [in] list The allocated list to check
+ * @return number The number of items on the list
+ */
+size_t connectionList_Length(const ConnectionList *list);
+
+/**
+ * @function connectionList_Get
+ * @abstract Returns the connection entry.
+ * @discussion
+ * Caller must not destroy the returned value. If you will store the
+ * entry in your own data structure, you should acquire your own reference.
+ * Will assert if you go beyond the end of the list.
+ *
+ */
+Connection *connectionList_Get(ConnectionList *list, size_t index);
+#endif // connectionList_h
diff --git a/hicn-light/src/core/connectionManager.c b/hicn-light/src/core/connectionManager.c
new file mode 100755
index 0000000..2089e14
--- /dev/null
+++ b/hicn-light/src/core/connectionManager.c
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+/**
+ * The Connection Manager sets itself up as a listener to the Messenger so it
+ * can take action based on system events.
+ *
+ * The Connection Manager queues and then processes in a later time slice the
+ * messages.
+ *
+ */
+
+#include <src/config.h>
+#include <src/core/connectionManager.h>
+#include <src/core/forwarder.h>
+#include <src/messenger/messenger.h>
+#include <src/messenger/messengerRecipient.h>
+#include <src/messenger/missiveDeque.h>
+#include <stdio.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <parc/assert/parc_Assert.h>
+
+struct connection_manager {
+ Forwarder *forwarder;
+ Logger *logger;
+
+ MessengerRecipient *messengerRecipient;
+
+ // we queue missives as they come in to process in our own
+ // event timeslice
+ MissiveDeque *missiveQueue;
+
+ // for deferred queue processing
+ PARCEventTimer *timerEvent;
+};
+
+/**
+ * Receives missives from the messenger, queues them, and schedules our
+ * execution
+ *
+ * We defer processing of missives to a later time slice
+ */
+static void connectionManager_MessengerCallback(MessengerRecipient *recipient,
+ Missive *missive);
+
+/**
+ * Event callback
+ *
+ * This is our main run loop to process our queue of messages. It is scheduled
+ * in {@link connectionManager_MessengerCallback} when the queue becomes
+ * non-empty.
+ *
+ * When we are called here, we have exclusive use of the system, so we will not
+ * create any message loops
+ *
+ * @param [in] fd unused, required for compliance with function prototype
+ * @param [in] which_event unused, required for compliance with function
+ * prototype
+ * @param [in] connManagerVoidPtr A void* to ConnectionManager
+ *
+ */
+static void connectionManager_ProcessQueue(int fd, PARCEventType which_event,
+ void *connManagerVoidPtr);
+
+static void connectionManager_ProcessClosedMissive(
+ ConnectionManager *connManager, const Missive *missive);
+
+// ========================================================
+// Public API
+
+ConnectionManager *connectionManager_Create(Forwarder *forwarder) {
+ ConnectionManager *connManager =
+ parcMemory_AllocateAndClear(sizeof(ConnectionManager));
+ parcAssertNotNull(connManager,
+ "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(ConnectionManager));
+ connManager->forwarder = forwarder;
+ connManager->missiveQueue = missiveDeque_Create();
+ connManager->logger = logger_Acquire(forwarder_GetLogger(forwarder));
+
+ Messenger *messenger = forwarder_GetMessenger(connManager->forwarder);
+
+ // creates the timer, but does not start it
+ PARCEventScheduler *base =
+ dispatcher_GetEventScheduler(forwarder_GetDispatcher(forwarder));
+ connManager->timerEvent = parcEventTimer_Create(
+ base, 0, connectionManager_ProcessQueue, connManager);
+
+ connManager->messengerRecipient = messengerRecipient_Create(
+ connManager, connectionManager_MessengerCallback);
+ messenger_Register(messenger, connManager->messengerRecipient);
+ return connManager;
+}
+
+void connectionManager_Destroy(ConnectionManager **managerPtr) {
+ parcAssertNotNull(managerPtr, "Double pointer must be non-null");
+ parcAssertNotNull(*managerPtr, "Double pointer must dereference to non-null");
+
+ ConnectionManager *connManager = *managerPtr;
+
+ Messenger *messenger = forwarder_GetMessenger(connManager->forwarder);
+ parcEventTimer_Destroy(&(connManager->timerEvent));
+ messenger_Unregister(messenger, connManager->messengerRecipient);
+ messengerRecipient_Destroy(&connManager->messengerRecipient);
+ missiveDeque_Release(&connManager->missiveQueue);
+ logger_Release(&connManager->logger);
+
+ parcMemory_Deallocate((void **)&connManager);
+ *managerPtr = NULL;
+}
+
+// ========================================================
+// Internal Functions
+
+static void connectionManager_MessengerCallback(MessengerRecipient *recipient,
+ Missive *missive) {
+ ConnectionManager *connManager =
+ messengerRecipient_GetRecipientContext(recipient);
+
+ // we do not release our reference count, we store it until later
+ // We are called with our own reference, so we do not need to acquire the
+ // missive here.
+ missiveDeque_Append(connManager->missiveQueue, missive);
+
+ if (missiveDeque_Size(connManager->missiveQueue) == 1) {
+ // When it becomes non-empty, schedule {@link
+ // connectionManager_ProcessQueue}
+ struct timeval immediateTimeout = {0, 0};
+ parcEventTimer_Start(connManager->timerEvent, &immediateTimeout);
+ }
+}
+
+static void connectionManager_ProcessQueue(int fd, PARCEventType which_event,
+ void *connManagerVoidPtr) {
+ ConnectionManager *connManager = (ConnectionManager *)connManagerVoidPtr;
+
+ Missive *missive;
+ while ((missive = missiveDeque_RemoveFirst(connManager->missiveQueue)) !=
+ NULL) {
+ switch (missive_GetType(missive)) {
+ case MissiveType_ConnectionCreate:
+ // hook to signal that a new connection was created
+ break;
+ case MissiveType_ConnectionUp:
+ // hook to signal that a new connection is up
+ break;
+ case MissiveType_ConnectionDown:
+ // hook to signal that a connection is down
+ break;
+ case MissiveType_ConnectionClosed:
+ connectionManager_ProcessClosedMissive(connManager, missive);
+ break;
+ case MissiveType_ConnectionDestroyed:
+ // hook to signal that a connection was destroyed
+ break;
+ default:
+ parcTrapUnexpectedState("Missive %p of unknown type: %d",
+ (void *)missive, missive_GetType(missive));
+ }
+ missive_Release(&missive);
+ }
+}
+
+static void connectionManager_ProcessClosedMissive(
+ ConnectionManager *connManager, const Missive *missive) {
+ logger_Log(connManager->logger, LoggerFacility_Core, PARCLogLevel_Debug,
+ __func__, "Processing CLOSED message for connid %u",
+ missive_GetConnectionId(missive));
+
+ ConnectionTable *table = forwarder_GetConnectionTable(connManager->forwarder);
+ const Connection *conn =
+ connectionTable_FindById(table, missive_GetConnectionId(missive));
+
+ if (conn) {
+ // this will destroy the connection if its the last reference count
+ connectionTable_Remove(table, conn);
+
+ // remove from FIB
+ forwarder_RemoveConnectionIdFromRoutes(connManager->forwarder,
+ missive_GetConnectionId(missive));
+ }
+}
diff --git a/hicn-light/src/core/connectionManager.h b/hicn-light/src/core/connectionManager.h
new file mode 100755
index 0000000..b77553e
--- /dev/null
+++ b/hicn-light/src/core/connectionManager.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file connectionManager.h
+ * @brief The connection manager handles connection events, such as going down
+ *
+ * The connection manager listens to the event notification system. Based on
+ * those events, the connection manager will take specific actions. This is
+ * expected to be a singleton instantiated by the forwarder.
+ *
+ */
+
+#ifndef connectionManager_h
+#define connectionManager_h
+
+#include <src/core/forwarder.h>
+
+struct connection_manager;
+typedef struct connection_manager ConnectionManager;
+
+ConnectionManager *connectionManager_Create(Forwarder *forwarder);
+
+void connectionManager_Destroy(ConnectionManager **managerPtr);
+#endif // connectionManager_h
diff --git a/hicn-light/src/core/connectionTable.c b/hicn-light/src/core/connectionTable.c
new file mode 100755
index 0000000..ba0942d
--- /dev/null
+++ b/hicn-light/src/core/connectionTable.c
@@ -0,0 +1,224 @@
+/*
+ * 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.
+ */
+
+/**
+ * @header ConnectionTable
+ * @abstract Record