|
|
@ -24,7 +24,7 @@ |
|
|
|
#include <string.h> |
|
|
|
#include <sys/ioctl.h> |
|
|
|
#include <sys/stat.h> |
|
|
|
#include <sys/timeb.h> |
|
|
|
#include <sys/time.h> |
|
|
|
#include <sys/types.h> |
|
|
|
#include <time.h> |
|
|
|
#include <unistd.h> |
|
|
@ -66,13 +66,13 @@ struct Allowed { |
|
|
|
struct Remote { |
|
|
|
struct SockAddr uaddr; |
|
|
|
struct Allowed *spec; // Rule being instantiated
|
|
|
|
struct timeb rec_when; // Last received packet time, in seconds
|
|
|
|
struct timeval rec_when; // Last received packet time, in seconds
|
|
|
|
}; |
|
|
|
|
|
|
|
// Details of an interface at a remote.
|
|
|
|
struct Interface { |
|
|
|
unsigned char mac[6]; // MAC address used last (key for by_mac table)
|
|
|
|
struct timeb rec_when; // Last packet time, in seconds
|
|
|
|
struct timeval rec_when; // Last packet time, in seconds
|
|
|
|
struct Remote *remote; |
|
|
|
}; |
|
|
|
|
|
|
@ -89,21 +89,20 @@ typedef struct _PacketItem { |
|
|
|
|
|
|
|
// heartbeat interval, in seconds
|
|
|
|
#define HEARTBEAT 30 |
|
|
|
#define HEARTBEAT_MILLIS ( HEARTBEAT * 1000 ) |
|
|
|
#define HEARTBEAT_MICROS ( HEARTBEAT * 1000000 ) |
|
|
|
|
|
|
|
// Macros for timing, for struct timeb variables
|
|
|
|
#define TIMEB_MILLIS(TM) (((int64_t) (TM)->time * 1000) + (TM)->millitm ) |
|
|
|
#define DIFFB_MILLIS(TM1,TM2) ( TIMEB_MILLIS(TM1) - TIMEB_MILLIS(TM2) ) |
|
|
|
// Macros for timing, for struct timeval variables
|
|
|
|
#define TIME_MICROS(TM) (((int64_t) (TM)->tv_sec * 1000000) + (TM)->tv_usec ) |
|
|
|
#define DIFF_MICROS(TM1,TM2) ( TIME_MICROS(TM1) - TIME_MICROS(TM2) ) |
|
|
|
|
|
|
|
// RECENT(T,M) is the time logic for requiring a gap time (in
|
|
|
|
// milliseconds) before shifting a MAC to a new remote. The limit is
|
|
|
|
// 6000 for broadcast and 20000 for unicast.
|
|
|
|
#define RECENT(T,M) ((M) < ((T)? 6000 : 20000 )) |
|
|
|
|
|
|
|
// VERYOLD_MILLIS is used for discarding downlink remotes whose latest
|
|
|
|
// VERYOLD_MICROSS is used for discarding downlink remotes whose latest
|
|
|
|
// activity is older than this.
|
|
|
|
#define VERYOLD_MILLIS 180000 |
|
|
|
|
|
|
|
#define VERYOLD_MICROS 180000000 |
|
|
|
|
|
|
|
////////// Variables
|
|
|
|
|
|
|
@ -979,10 +978,10 @@ static struct Interface *input_check( |
|
|
|
{ |
|
|
|
VERBOSE2OUT( "RECV %ld bytes from %s\n", len, inet_stoa( src ) ); |
|
|
|
struct Remote *r = 0; |
|
|
|
struct timeb now = { 0 }; |
|
|
|
if ( ftime( &now ) ) { |
|
|
|
struct timeval now = { 0 }; |
|
|
|
if ( gettimeofday( &now, 0 ) ) { |
|
|
|
perror( "RECV time" ); |
|
|
|
now.time = time( 0 ); |
|
|
|
now.tv_sec = time( 0 ); |
|
|
|
} |
|
|
|
Remote_FIND( src, r ); |
|
|
|
if ( r == 0 ) { |
|
|
@ -1065,7 +1064,7 @@ static struct Interface *input_check( |
|
|
|
// primary channel, or the time since the last packet for that
|
|
|
|
// interface is less than RECENT, with different limits for
|
|
|
|
// broadcast and unicast.
|
|
|
|
int64_t dmac = DIFFB_MILLIS( &now, &x->rec_when); |
|
|
|
int64_t dmac = DIFF_MICROS( &now, &x->rec_when); |
|
|
|
if ( x->remote->spec == 0 || RECENT( *buf & 1, dmac ) ) { |
|
|
|
if ( verbose >= 2 ) { |
|
|
|
fprintf( |
|
|
@ -1126,10 +1125,10 @@ static void route_packet(unsigned char *buf,int len,struct SockAddr *src) { |
|
|
|
} |
|
|
|
// broadcast. +x+ is source interface
|
|
|
|
// x->rec_when is not updated
|
|
|
|
struct timeb now = { 0 }; |
|
|
|
if ( ftime( &now ) ) { |
|
|
|
struct timeval now = { 0 }; |
|
|
|
if ( gettimeofday( &now, 0 ) ) { |
|
|
|
perror( "RECV time" ); |
|
|
|
now.time = time( 0 ); |
|
|
|
now.tv_sec = time( 0 ); |
|
|
|
} |
|
|
|
VERBOSE2OUT( "BC %s -> %s from %s\n", |
|
|
|
inet_mtoa( buf+6 ), inet_mtoa( buf ), |
|
|
@ -1149,11 +1148,11 @@ static void route_packet(unsigned char *buf,int len,struct SockAddr *src) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
if ( r->spec && ! is_uplink( r->spec ) && |
|
|
|
DIFFB_MILLIS( &now, &r->rec_when ) > VERYOLD_MILLIS ) { |
|
|
|
DIFF_MICROS( &now, &r->rec_when ) > VERYOLD_MICROS ) { |
|
|
|
// remove old downlink connection
|
|
|
|
VERBOSEOUT( "Old remote discarded %s (%ld)\n", |
|
|
|
inet_stoa( &r->uaddr ), |
|
|
|
TIMEB_MILLIS( &r->rec_when ) ); |
|
|
|
TIME_MICROS( &r->rec_when ) ); |
|
|
|
// Removing a downlink might have threading implications
|
|
|
|
delete_remote( r ); |
|
|
|
continue; |
|
|
@ -1227,7 +1226,8 @@ static void doreadUDP(int fd) { |
|
|
|
exit( 1 ); |
|
|
|
} |
|
|
|
#ifdef GPROF |
|
|
|
if ( len == 17 && memcmp( buf, "STOPSTOPSTOPSTOP", 16 ) == 0 ) { |
|
|
|
if ( todo->len == 17 && |
|
|
|
memcmp( todo->buffer, "STOPSTOPSTOPSTOP", 16 ) == 0 ) { |
|
|
|
exit( 0 ); |
|
|
|
} |
|
|
|
#endif |
|
|
@ -1288,11 +1288,11 @@ static void heartbeat(int fd) { |
|
|
|
VERBOSE3OUT( "heartbeat fd=%d\n", fd ); |
|
|
|
struct Remote *r; |
|
|
|
unsigned int i = 0; |
|
|
|
struct timeb now; |
|
|
|
if ( ftime( &now ) ) { |
|
|
|
struct timeval now; |
|
|
|
if ( gettimeofday( &now, 0 ) ) { |
|
|
|
perror( "HEARTBEAT time" ); |
|
|
|
now.time = time( 0 ); |
|
|
|
now.millitm = 0; |
|
|
|
now.tv_sec = time( 0 ); |
|
|
|
now.tv_usec = 0; |
|
|
|
} |
|
|
|
Remote_LOCK; |
|
|
|
for ( ; i < remotes.by_addr.size; i++ ) { |
|
|
@ -1303,7 +1303,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 ( DIFFB_MILLIS( &now, &r->rec_when ) > HEARTBEAT_MILLIS ) { |
|
|
|
if ( DIFF_MICROS( &now, &r->rec_when ) > HEARTBEAT_MICROS ) { |
|
|
|
VERBOSE3OUT( "heartbeat %s\n", inet_stoa( &r->uaddr ) ); |
|
|
|
write_remote( data, 0, r ); |
|
|
|
} |
|
|
|