]> git.gsnw.org Git - fping.git/commitdiff
start work on seqmap
authorDavid Schweikert <david@schweikert.ch>
Mon, 22 Jul 2013 22:25:53 +0000 (00:25 +0200)
committerDavid Schweikert <david@schweikert.ch>
Mon, 22 Jul 2013 22:25:53 +0000 (00:25 +0200)
src/Makefile.am
src/seqmap.c [new file with mode: 0644]
src/seqmap.h [new file with mode: 0644]

index 93d108e4b9635faed1e83d065418272c2c76a799..5607a00db28104222526ad544d41856ffec3f04e 100644 (file)
@@ -9,8 +9,8 @@ endif
 
 sbin_PROGRAMS = ${prog}
 
-fping_SOURCES = fping.c options.h
+fping_SOURCES = fping.c options.h seqmap.h seqmap.c
 fping_DEPENDENCIES = ../config.h
-fping6_SOURCES = fping.c options.h
+fping6_SOURCES = fping.c options.h seqmap.h seqmap.c
 fping6_DEPENDENCIES = ../config.h
 fping6_CFLAGS = $(AM_CFLAGS) -DIPV6
diff --git a/src/seqmap.c b/src/seqmap.c
new file mode 100644 (file)
index 0000000..2e6c030
--- /dev/null
@@ -0,0 +1,119 @@
+/* 
+ * fping: fast-ping, file-ping, favorite-ping, funky-ping
+ *
+ *   Ping a list of target hosts in a round robin fashion.
+ *   A better ping overall.
+ *
+ * fping website:  http://www.fping.org
+ *
+ * Current maintainer of fping: David Schweikert
+ * Please send suggestions and patches to: david@schweikert.ch
+ *
+ *
+ * Original author:  Roland Schemers  <schemers@stanford.edu>
+ * IPv6 Support:     Jeroen Massar    <jeroen@unfix.org / jeroen@ipng.nl>
+ * Improved main loop: David Schweikert <david@schweikert.ch>
+ * Debian Merge, TOS settings: Tobi Oetiker <tobi@oetiker.ch>
+ * Bugfixes, byte order & senseful seq.-numbers: Stephan Fuhrmann (stephan.fuhrmann AT 1und1.de)
+ *
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by Stanford University.  The name of the University may not be used 
+ * to endorse or promote products derived from this software without 
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * seqmap.c: implementation of a mapping between sequence number and (host, ping_nr)
+ *           we can't just use ping_nr*host_count + host_nr, because it can
+ *           overflow the 16 bit of the icmp header field. See also:
+ *           https://github.com/schweikert/fping/issues/48
+ */
+
+#include "seqmap.h"
+#include "options.h"
+#include "limits.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* description of the data structure used:
+ *
+ * - we assume that no more than SEQMAP_MAXSEQ (65000) pings are sent in
+ *   the timeout interval (SEQMAP_TIMEOUT_IN_S)
+ * - we store the values in an array with SEQMAP_MAXSEQ elements
+ * - current sequence number % SEQMAP_MAXSEQ gives the current index
+ * - when entering a value, we check that the current entry is expired
+ */
+
+static SEQMAP_VALUE *seqmap_map = NULL;
+static unsigned int seqmap_next_id = 0;
+static SEQMAP_VALUE *seqmap_free_list;
+
+#define SEQMAP_TIMEOUT_IN_S       10
+#define SEQMAP_UNASSIGNED_HOST_NR UINT_MAX
+
+void seqmap_init()
+{
+    unsigned int i;
+
+    seqmap_map = calloc(SEQMAP_MAXSEQ, sizeof(SEQMAP_VALUE));
+    if(seqmap_map == NULL) {
+        perror("malloc error (can't allocate seqmap_map)");
+    }
+}
+
+unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct timeval *now)
+{
+    unsigned int current_id;
+    SEQMAP_VALUE *next_value;
+
+    if(!seqmap_map) {
+        fprintf(stderr, "fping internal error: seqmap not initialized.\n");
+        exit(4);
+    }
+
+    /* check if expired (note that unused seqmap values will have fields set to
+     * 0, so will be seen as expired */
+    next_value = &seqmap_map[seqmap_next_id];
+    if(next_value->ping_ts.tv_sec != 0 && (now->tv_sec - next_value->ping_ts.tv_sec) < SEQMAP_TIMEOUT_IN_S) {
+        fprintf(stderr, "fping error: not enough sequence numbers available! (expire_timeout=%d, host_nr=%d, ping_count=%d, seqmap_next_id=%d)\n",
+            SEQMAP_TIMEOUT_IN_S, host_nr, ping_count, seqmap_next_id);
+        exit(4);
+    }
+
+    /* store the value */
+    next_value->host_nr = host_nr;
+    next_value->ping_count = ping_count;
+    next_value->ping_ts.tv_sec = now->tv_sec;
+    next_value->ping_ts.tv_usec = now->tv_usec;
+
+    /* increase next id */
+    current_id = seqmap_next_id;
+    seqmap_next_id = (seqmap_next_id + 1) % SEQMAP_MAXSEQ;
+
+    return current_id;
+}
+
+SEQMAP_VALUE *seqmap_fetch(unsigned int id, struct timeval *now)
+{
+    SEQMAP_VALUE *value;
+
+    if(id > SEQMAP_MAXSEQ) {
+        return NULL;
+    }
+
+    value = &seqmap_map[id];
+
+    /* verify that value is not expired */
+    if(now->tv_sec - value->ping_ts.tv_sec >= SEQMAP_TIMEOUT_IN_S) {
+        return NULL;
+    }
+
+    return value;
+}
diff --git a/src/seqmap.h b/src/seqmap.h
new file mode 100644 (file)
index 0000000..0887e68
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef SEQMAP_H
+#define SEQMAP_H
+
+#include <sys/time.h>
+
+typedef struct seqmap_value
+{
+    unsigned int    host_nr;
+    unsigned int    ping_count;
+    struct timeval  ping_ts;
+
+} SEQMAP_VALUE;
+
+#define SEQMAP_MAXSEQ 65000
+
+#endif