|
|
@ -1086,9 +1086,11 @@ static void unmap_if_mapped(struct SockAddr *s) { |
|
|
|
} |
|
|
|
|
|
|
|
// Route the packet from the given src
|
|
|
|
static struct Interface *input_check( |
|
|
|
unsigned char *buf,ssize_t len,struct SockAddr *src ) |
|
|
|
{ |
|
|
|
static struct Interface *input_check(PacketItem *pi) { |
|
|
|
unsigned char *buf = pi->buffer; |
|
|
|
ssize_t len = pi->len; |
|
|
|
struct SockAddr *src = &pi->src; |
|
|
|
|
|
|
|
VERBOSE2OUT( "RECV %ld bytes from %s\n", len, inet_stoa( src ) ); |
|
|
|
struct Remote *r = 0; |
|
|
|
struct timeval now = { 0 }; |
|
|
@ -1106,6 +1108,24 @@ static struct Interface *input_check( |
|
|
|
VERBOSEOUT( "New remote %s by %s\n", inet_stoa( src ), a->source ); |
|
|
|
r = add_remote( src, a ); |
|
|
|
//r->rec_when = now; // Set activity stamp of new remote
|
|
|
|
// Set the local addressing for the remote, unless set already
|
|
|
|
// Note: potential for multi-thread competition here
|
|
|
|
if ( udp6 ) { |
|
|
|
r->ifindex = pi->dstinfo.in6.ipi6_ifindex; |
|
|
|
r->laddr.in6.sin6_family = AF_INET6; |
|
|
|
r->laddr.in6.sin6_port = htons( udp_port ); |
|
|
|
memcpy( &r->laddr.in6.sin6_addr, |
|
|
|
&pi->dstinfo.in6.ipi6_addr, |
|
|
|
16 ); |
|
|
|
unmap_if_mapped( &r->laddr ); |
|
|
|
} else { |
|
|
|
r->ifindex = pi->dstinfo.in4.ipi_ifindex; |
|
|
|
r->laddr.in4.sin_family = AF_INET; |
|
|
|
r->laddr.in4.sin_port = htons( udp_port ); |
|
|
|
memcpy( &r->laddr.in4.sin_addr, |
|
|
|
&pi->dstinfo.in4.ipi_spec_dst, |
|
|
|
4 ); |
|
|
|
} |
|
|
|
} |
|
|
|
if ( len < 12 ) { |
|
|
|
// Ignore short data, but maintain channel
|
|
|
@ -1208,55 +1228,35 @@ static struct Interface *input_check( |
|
|
|
|
|
|
|
// Check packet and deliver out
|
|
|
|
static void route_packet(PacketItem *pi) { |
|
|
|
unsigned char *buf = pi->buffer; |
|
|
|
int len = pi->len; |
|
|
|
struct SockAddr *src = &pi->src; |
|
|
|
struct Interface *x = input_check( buf, len, src ); |
|
|
|
//unsigned char *buf = pi->buffer;
|
|
|
|
//ssize_t len = pi->len;
|
|
|
|
struct Interface *x = input_check( pi ); |
|
|
|
if ( x == 0 ) { |
|
|
|
VERBOSE2OUT( "not a nice packet\n" ); |
|
|
|
return; // not a nice packet
|
|
|
|
} |
|
|
|
// Set the local addressing for the remote, unless set already
|
|
|
|
if ( x->remote->ifindex == 0 ) { |
|
|
|
if ( udp6 ) { |
|
|
|
x->remote->ifindex = pi->dstinfo.in6.ipi6_ifindex; |
|
|
|
x->remote->laddr.in6.sin6_family = AF_INET6; |
|
|
|
x->remote->laddr.in6.sin6_port = htons( udp_port ); |
|
|
|
memcpy( &x->remote->laddr.in6.sin6_addr, |
|
|
|
&pi->dstinfo.in6.ipi6_addr, |
|
|
|
16 ); |
|
|
|
unmap_if_mapped( &x->remote->laddr ); |
|
|
|
} else { |
|
|
|
x->remote->ifindex = pi->dstinfo.in4.ipi_ifindex; |
|
|
|
x->remote->laddr.in4.sin_family = AF_INET; |
|
|
|
x->remote->laddr.in4.sin_port = htons( udp_port ); |
|
|
|
memcpy( &x->remote->laddr.in4.sin_addr, |
|
|
|
&pi->dstinfo.in4.ipi_spec_dst, |
|
|
|
4 ); |
|
|
|
} |
|
|
|
} |
|
|
|
if ( ( *buf & 1 ) == 0 ) { |
|
|
|
if ( ( *pi->buffer & 1 ) == 0 ) { |
|
|
|
// unicast
|
|
|
|
struct Interface *y = 0; // reuse for destination interface
|
|
|
|
Interface_FIND( buf, y ); |
|
|
|
Interface_FIND( pi->buffer, y ); |
|
|
|
if ( y == 0 ) { |
|
|
|
VERBOSE2OUT( "RECV %s -> %s from %s without channel and dropped\n", |
|
|
|
inet_mtoa( buf+6 ), inet_mtoa( buf ), |
|
|
|
inet_mtoa( pi->buffer + 6 ), inet_mtoa( pi->buffer ), |
|
|
|
inet_stoa( &x->remote->uaddr ) ); |
|
|
|
return; |
|
|
|
} |
|
|
|
if ( x->remote == y->remote ) { |
|
|
|
VERBOSEOUT( "RECV loop for %s -> %s from %s to %s\n", |
|
|
|
inet_mtoa( buf+6 ), inet_mtoa( buf ), |
|
|
|
inet_mtoa( pi->buffer+6 ), inet_mtoa( pi->buffer ), |
|
|
|
inet_stoa( &x->remote->uaddr ), |
|
|
|
inet_stoa( &y->remote->uaddr ) ); |
|
|
|
Interface_DEL( y ); // Need to see this interface again
|
|
|
|
return; |
|
|
|
} |
|
|
|
VERBOSE2OUT( "RECV route %s -> %s\n", |
|
|
|
inet_mtoa( buf+6 ), |
|
|
|
inet_mtoa( buf ) ); |
|
|
|
write_remote( buf, len, y->remote ); |
|
|
|
inet_mtoa( pi->buffer+6 ), |
|
|
|
inet_mtoa( pi->buffer ) ); |
|
|
|
write_remote( pi->buffer, pi->len, y->remote ); |
|
|
|
return; |
|
|
|
} |
|
|
|
// broadcast. +x+ is source interface
|
|
|
@ -1267,7 +1267,7 @@ static void route_packet(PacketItem *pi) { |
|
|
|
now.tv_sec = time( 0 ); |
|
|
|
} |
|
|
|
VERBOSE2OUT( "BC %s -> %s from %s to %s\n", |
|
|
|
inet_mtoa( buf+6 ), inet_mtoa( buf ), |
|
|
|
inet_mtoa( pi->buffer+6 ), inet_mtoa( pi->buffer ), |
|
|
|
inet_stoa( &x->remote->uaddr ), |
|
|
|
inet_stoa( &x->remote->laddr ) ); |
|
|
|
struct Remote *r; |
|
|
@ -1296,7 +1296,7 @@ static void route_packet(PacketItem *pi) { |
|
|
|
} |
|
|
|
// Send packet to the remote
|
|
|
|
// Only no-clash or to the tap/stdin
|
|
|
|
write_remote( buf, len, r ); |
|
|
|
write_remote( pi->buffer, pi->len, r ); |
|
|
|
} |
|
|
|
Remote_UNLOCK; |
|
|
|
} |
|
|
|