added origin
[rrq/rrqnet.git] / rrqnet.c
index 193e6739524ff82094e6c8f386631639992a1617..69c363c0f9c30bf144a069520cf85270ea919a72 100644 (file)
--- a/rrqnet.c
+++ b/rrqnet.c
@@ -16,6 +16,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <linux/if.h>
 #include <linux/if_tun.h>
 #include <stddef.h>
@@ -99,8 +100,7 @@ typedef struct _ReaderData {
 } ReaderData;
 
 // heartbeat interval, in seconds
-#define HEARTBEAT 30
-#define HEARTBEAT_MICROS ( HEARTBEAT * 1000000 )
+#define HEARTBEAT_MICROS ( heart_rate * 1000000 )
 
 // Macros for timing, for struct timeval variables
 #define TIME_MICROS(TM) (((int64_t) (TM)->tv_sec * 1000000) + (TM)->tv_usec )
@@ -184,6 +184,7 @@ static int udp_fd;
 static int udp_port;
 static int threads_count = 0;
 static int buffers_count = 0;
+static int heart_rate = 30;
 
 // Setup for multicast channel
 static struct {
@@ -691,6 +692,14 @@ static int parse_threads_count(char *arg) {
     return 0;
 }
 
+static int parse_heartbeat_rate(char *arg) {
+    if ( ( sscanf( arg, "%u", &heart_rate ) != 1 ) || heart_rate < 0 ) {
+       return 1;
+    }
+    VERBOSEOUT( "** Heartbeat rate = %d\n", heart_rate );
+    return 0;
+}
+
 static int parse_buffers_count(char *arg) {
     if ( ( sscanf( arg, "%u", &buffers_count ) != 1 ) || buffers_count < 1 ) {
        return 1;
@@ -946,7 +955,7 @@ static void sendpacket4(unsigned char *buf, int n,struct Remote *r) {
        .msg_controllen = CMSG_SPACE( sizeof( struct in_pktinfo ) ),
        .msg_flags = 0 // unused
     };
-    VERBOSE2OUT( "sendmsg ipv4 %lu from %s to %s\n",
+    VERBOSE2OUT( "sendmsg ipv4 %zu from %s to %s\n",
                 msg.msg_controllen,
                 inet_stoa( &r->laddr ),
                 inet_stoa( &r->uaddr ) );
@@ -1091,7 +1100,7 @@ static struct Interface *input_check(PacketItem *pi) {
     ssize_t len = pi->len;
     struct SockAddr *src = &pi->src;
 
-    VERBOSE2OUT( "RECV %ld bytes from %s\n", len, inet_stoa( src ) );
+    VERBOSE2OUT( "RECV %zd bytes from %s\n", len, inet_stoa( src ) );
     struct Remote *r = 0;
     struct timeval now = { 0 };
     if ( gettimeofday( &now, 0 ) ) {
@@ -1131,7 +1140,7 @@ static struct Interface *input_check(PacketItem *pi) {
        // Ignore short data, but maintain channel
        r->rec_when = now; // Update activity stamp touched remote
        if ( len > 0 ) {
-           VERBOSEOUT( "Ignoring %ld bytes from %s\n",
+           VERBOSEOUT( "Ignoring %zd bytes from %s\n",
                        len, inet_stoa( src ) );
        }
        return 0;
@@ -1197,12 +1206,12 @@ static struct Interface *input_check(PacketItem *pi) {
        // primary channel, or the time since the last packet for that
        // interface is less than RECENT_MICROS, with different limits
        // for broadcast and unicast.
-       int64_t dmac = DIFF_MICROS( &now, &x->rec_when);
+       uint64_t dmac = DIFF_MICROS( &now, &x->rec_when);
        if ( x->remote->spec == 0 || RECENT_MICROS( *buf & 1, dmac ) ) {
            if ( verbose >= 2 ) {
                fprintf(
                    stderr,
-                   "Dropped. MAC %s (%ld) from %s, should be %s\n",
+                   "Dropped. MAC %s (%"PRIu64") from %s, should be %s\n",
                    inet_mtoa( buf+6 ), dmac,
                    inet_stoa( src ), inet_stoa( &x->remote->uaddr ) );
            }
@@ -1287,7 +1296,7 @@ static void route_packet(PacketItem *pi) {
        if ( r->spec && ! is_uplink( r->spec ) &&
             DIFF_MICROS( &now, &r->rec_when ) > VERYOLD_MICROS ) {
            // remove old downlink connection
-           VERBOSEOUT( "Old remote discarded %s (%ld)\n",
+           VERBOSEOUT( "Old remote discarded %s (%"PRId64")\n",
                        inet_stoa( &r->uaddr ),
                        TIME_MICROS( &r->rec_when ) );
            // Removing a downlink might have threading implications
@@ -1461,7 +1470,7 @@ static void heartbeat(int fd) {
        r = (struct Remote *) tmp;
        VERBOSE3OUT( "heartbeat check %s\n", inet_stoa( &r->uaddr ) );
        if ( r->spec && is_uplink( r->spec ) ) {
-           if ( DIFF_MICROS( &now, &r->rec_when ) > HEARTBEAT_MICROS ) {
+           if ( DIFF_MICROS( &now, &r->rec_when ) >= HEARTBEAT_MICROS ) {
                VERBOSE3OUT( "heartbeat %s\n", inet_stoa( &r->uaddr ) );
                write_remote( data, 0, r );
            }
@@ -1626,6 +1635,15 @@ int main(int argc, char *argv[]) {
        i += 2;
        ENSUREARGS( 1 );
     }
+    // then: optional -H seconds
+    if ( strncmp( "-H", argv[i], 2 ) == 0 ) {
+       ENSUREARGS( 2 );
+       if ( parse_heartbeat_rate( argv[i+1] ) ) {
+           usage();
+       }
+       i += 2;
+       ENSUREARGS( 1 );
+    }
     // then: optional -m mcast
     if ( strncmp( "-m", argv[i], 2 ) == 0 ) {
        ENSUREARGS( 2 );
@@ -1791,8 +1809,12 @@ int main(int argc, char *argv[]) {
 
     // Start heartbeating to uplinks
     for ( ;; ) {
-       sleep( HEARTBEAT );
-       heartbeat( udp_fd );
+       if ( heart_rate != 0 ) {
+           sleep( heart_rate );
+           heartbeat( udp_fd );
+       } else {
+           sleep( 600 );
+       }
     }
     return 0;
 }