Browse Source

Flip-over from tap/stdin eventually

wip/flip-over-tap
Ralph Rönnquist 10 months ago
parent
commit
4df48b046e
  1. 4
      debian/changelog
  2. 47
      rrqnet.c

4
debian/changelog

@ -1,3 +1,7 @@
rrqnet (1.5.2) unstable; urgency=medium
* change: source flip-over away from tap/stdin eventually
-- Ralph Ronnquist <ralph.ronnquist@gmail.com> Wed, 27 Oct 2021 09:34:37 +1100
rrqnet (1.5.1) unstable; urgency=medium
* Bug fix: flip-over limits are microseconds.

47
rrqnet.c

@ -1030,54 +1030,63 @@ static struct Interface *input_check(
}
}
Interface_FIND( buf+6, x );
// x is the previous interface for the source MAC, or null.
if ( x == 0 ) {
// Totally new MAC. Should bind it to the remote
// Totally new MAC, so create a new interface for it and bind
// that to the channel.
VERBOSEOUT( "New MAC %s from %s\n",
inet_mtoa( buf+6 ), inet_stoa( src ) );
x = add_interface( buf+6, r );
r->rec_when = now; // Update activity stamp for remote
x->rec_when = now;
r->rec_when = now; // Update channel activity stamp
x->rec_when = now; // Update interface activity stamp
return x;
}
// Seen that MAC already
// Seen that MAC already.
if ( x->remote == r ) {
VERBOSE2OUT( "RECV %s from %s again\n",
inet_mtoa( buf+6 ), inet_stoa( &x->remote->uaddr ) );
r->rec_when = now; // Update activity stamp
x->rec_when = now; // Update activity stamp
r->rec_when = now; // Update channel activity stamp
x->rec_when = now; // Update interface activity stamp
return x;
}
// MAC clash from two different connections
// r = current
// x->remote = previous
// There is a MAC "clash" from two different channels.
// r = current channel
// x->remote = previous channel
VERBOSE2OUT( "RECV %s from %s previously from %s\n",
inet_mtoa( buf+6 ),
inet_stoa( &r->uaddr ),
inet_stoa( &x->remote->uaddr ) );
// Consider source fallover:
// treat tap/stdio differently from other channels
if ( r->spec ) {
// The packet source MAC has arrived on other than its
// previous channel. It thus gets dropped if tap/stdin is the
// 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);
if ( x->remote->spec == 0 || RECENT_MICROS( *buf & 1, dmac ) ) {
// The incoming packet is not from tap/stdin.
int64_t time_since_last = DIFF_MICROS( &now, &x->rec_when);
// Fallover happens if the previous is sufficiently idle
if ( x->remote->spec == 0 ) {
// Fallover limits are 4 times larger for tap/stdio
time_since_last /= 4;
}
// The effective idle time (i.e. the time since last packet)
// of the previous interface must be more than RECENT_MICROS,
// which has different limits for incoming broadcast and
// unicast.
if ( RECENT_MICROS( *buf & 1, time_since_last ) ) {
if ( verbose >= 2 ) {
fprintf(
stderr,
"Dropped. MAC %s (%ld) from %s, should be %s\n",
inet_mtoa( buf+6 ), dmac,
inet_mtoa( buf+6 ), time_since_last,
inet_stoa( src ), inet_stoa( &x->remote->uaddr ) );
}
return 0;
}
// Check if previous package on the interface was recent
// falling through when old channel is deemed inactive
//
} else if ( r->uaddr.in.sa_family ) {
// Multicast incoming clashing with tap/stdio
VERBOSE3OUT( "Dropped multicast loopback\n" );
return 0;
}
// New remote takes over the MAC
VERBOSEOUT( "MAC %s from %s cancels previous %s\n",
inet_mtoa( buf+6 ), inet_stoa( src ),

Loading…
Cancel
Save