aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/strategies/probe_generator.c
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-light/src/hicn/strategies/probe_generator.c')
-rw-r--r--hicn-light/src/hicn/strategies/probe_generator.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/hicn-light/src/hicn/strategies/probe_generator.c b/hicn-light/src/hicn/strategies/probe_generator.c
new file mode 100644
index 000000000..fd0bf5471
--- /dev/null
+++ b/hicn-light/src/hicn/strategies/probe_generator.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2021-2022 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "probe_generator.h"
+
+#include <hicn/core/forwarder.h>
+#include <hicn/core/nexthops.h>
+
+// map functions
+static void add_to_map(probe_generator_t *pg, unsigned seq, Ticks now) {
+ khiter_t k;
+ int ret;
+ k = kh_put_bp_map(pg->ticks_by_seq, seq, &ret);
+ kh_value(pg->ticks_by_seq, k) = now;
+}
+
+static Ticks get_from_map(probe_generator_t *pg, unsigned seq) {
+ khiter_t k;
+ k = kh_get_bp_map(pg->ticks_by_seq, seq);
+ if (k == kh_end(pg->ticks_by_seq)) return 0;
+ Ticks t = kh_value(pg->ticks_by_seq, k);
+ return t;
+}
+
+static void remove_from_map(probe_generator_t *pg, unsigned seq) {
+ khiter_t k;
+ k = kh_get_bp_map(pg->ticks_by_seq, seq);
+ if (k != kh_end(pg->ticks_by_seq)) kh_del_bp_map(pg->ticks_by_seq, k);
+}
+
+static void clear_map(probe_generator_t *pg) {
+ kh_clear(bp_map, pg->ticks_by_seq);
+}
+
+// seq number generator
+
+static uint32_t get_seq_number(probe_generator_t *pg) {
+ uint32_t seq = 0;
+ uint32_t try = 0;
+ while (try < 3) { // try up to 3 times
+ seq =
+ (rand() % (MAX_PROBE_SUFFIX - MIN_PROBE_SUFFIX + 1)) + MIN_PROBE_SUFFIX;
+ Ticks time = get_from_map(pg, seq);
+ if (time == 0) return seq; // seq does not exists
+ try++;
+ }
+ return 0;
+}
+
+// probing functions
+
+probe_generator_t *create_probe_generator() {
+ probe_generator_t *pg = calloc(1, sizeof(probe_generator_t));
+ if (!pg) return NULL;
+
+ pg->ticks_by_seq = kh_init_bp_map();
+ return pg;
+}
+
+void destroy_probe_generator(probe_generator_t *pg) {
+ kh_destroy_bp_map(pg->ticks_by_seq);
+ free(pg);
+}
+
+int generate_probe(probe_generator_t *pg, const msgbuf_t *msgbuf,
+ const forwarder_t *forwarder, nexthop_t nexthop) {
+ msgbuf_pool_t *msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
+ connection_table_t *table = forwarder_get_connection_table(forwarder);
+ connection_t *conn = connection_table_get_by_id(table, nexthop);
+ if (!conn) return -1;
+
+ msgbuf_t *probe;
+ off_t msg_id = msgbuf_pool_get_id(msgbuf_pool, (msgbuf_t *)msgbuf);
+ off_t probe_offset = msgbuf_pool_clone(msgbuf_pool, &probe, msg_id);
+
+ uint32_t seq = get_seq_number(pg);
+ if (seq == 0) return -1;
+ msgbuf_modify_suffix(probe, seq);
+ connection_send(conn, probe_offset, true);
+ connection_flush(conn);
+ add_to_map(pg, seq, ticks_now());
+ msgbuf_pool_put(msgbuf_pool, probe);
+
+ return 0;
+}
+
+Ticks register_probe(probe_generator_t *pg, unsigned seq) {
+ Ticks now = ticks_now();
+ add_to_map(pg, seq, now);
+ return now;
+}
+
+Ticks get_probe_send_time(probe_generator_t *pg, unsigned seq) {
+ return get_from_map(pg, seq);
+}
+
+void delete_probe(probe_generator_t *pg, unsigned seq) {
+ remove_from_map(pg, seq);
+}
+
+void delete_all_probes(probe_generator_t *pg) { clear_map(pg); }