From f4c744266fd15130d6d677319d4c289028a1b70c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 15 Dec 2009 17:39:19 +0000 Subject: [PATCH] (trunk libT) #2667 "ignore martian addresses" -- modified this ticket. previously we ignored them from LTEP; now we ignore them regardless of the source. this commit implements this filtering change. --- libtransmission/net.c | 123 +++++++++++++++++++----------------- libtransmission/net.h | 10 ++- libtransmission/peer-io.c | 6 +- libtransmission/peer-msgs.c | 6 +- 4 files changed, 74 insertions(+), 71 deletions(-) diff --git a/libtransmission/net.c b/libtransmission/net.c index 66ce6b022..5abec6bee 100644 --- a/libtransmission/net.c +++ b/libtransmission/net.c @@ -240,57 +240,11 @@ setup_sockaddr( const tr_address * addr, } } -static tr_bool -isMulticastAddress( const tr_address * addr ) -{ - if( addr->type == TR_AF_INET && IN_MULTICAST( htonl( addr->addr.addr4.s_addr ) ) ) - return TRUE; - - if( addr->type == TR_AF_INET6 && ( addr->addr.addr6.s6_addr[0] == 0xff ) ) - return TRUE; - - return FALSE; -} - -static TR_INLINE tr_bool -isIPv4MappedOrCompatAddress( const tr_address * addr ) -{ - if( addr->type == TR_AF_INET6 ) - { - if( IN6_IS_ADDR_V4MAPPED( &addr->addr.addr6 ) || - IN6_IS_ADDR_V4COMPAT( &addr->addr.addr6 ) ) - return TRUE; - } - return FALSE; -} - -static TR_INLINE tr_bool -isIPv6LinkLocalAddress( const tr_address * addr ) -{ - if( addr->type == TR_AF_INET6 && - IN6_IS_ADDR_LINKLOCAL( &addr->addr.addr6 ) ) - return TRUE; - return FALSE; -} - -tr_bool -tr_isValidPeerAddress( const tr_address * addr, tr_port port ) -{ - if( isMulticastAddress( addr ) || isIPv6LinkLocalAddress( addr ) || - isIPv4MappedOrCompatAddress( addr ) ) - return FALSE; - - if( port == 0 ) - return FALSE; - - return TRUE; -} - int -tr_netOpenTCP( tr_session * session, - const tr_address * addr, - tr_port port, - tr_bool isSeed ) +tr_netOpenPeerSocket( tr_session * session, + const tr_address * addr, + tr_port port, + tr_bool clientIsSeed ) { static const int domains[NUM_TR_AF_INET_TYPES] = { AF_INET, AF_INET6 }; int s; @@ -302,7 +256,7 @@ tr_netOpenTCP( tr_session * session, assert( tr_isAddress( addr ) ); - if( isMulticastAddress( addr ) || isIPv6LinkLocalAddress( addr ) ) + if( !tr_isValidPeerAddress( addr, port ) ) return -EINVAL; s = tr_fdSocketCreate( session, domains[addr->type], SOCK_STREAM ); @@ -310,7 +264,7 @@ tr_netOpenTCP( tr_session * session, return -1; /* seeds don't need much of a read buffer... */ - if( isSeed ) { + if( clientIsSeed ) { int n = 8192; if( setsockopt( s, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n) ) ) tr_inf( "Unable to set SO_RCVBUF on socket %d: %s", s, tr_strerror( sockerrno ) ); @@ -634,28 +588,81 @@ tr_globalIPv6( void ) return have_ipv6 ? ipv6 : NULL; } -int -tr_isMartian( int af, const unsigned char * address ) +/*** +**** +**** +***/ + +static tr_bool +isMulticastAddress( const tr_address * addr ) +{ + if( addr->type == TR_AF_INET && IN_MULTICAST( htonl( addr->addr.addr4.s_addr ) ) ) + return TRUE; + + if( addr->type == TR_AF_INET6 && ( addr->addr.addr6.s6_addr[0] == 0xff ) ) + return TRUE; + + return FALSE; +} + +static tr_bool +isIPv4MappedOrCompatAddress( const tr_address * addr ) +{ + return ( ( addr->type == TR_AF_INET6 ) + && ( IN6_IS_ADDR_V4MAPPED( &addr->addr.addr6 ) + || IN6_IS_ADDR_V4COMPAT( &addr->addr.addr6 ) ) ); +} + +static tr_bool +isIPv6LinkLocalAddress( const tr_address * addr ) +{ + return ( ( addr->type == TR_AF_INET6 ) + && IN6_IS_ADDR_LINKLOCAL( &addr->addr.addr6 ) ); +} + +/* isMartianAddr was written by Juliusz Chroboczek, + and is covered under the same license as third-party/dht/dht.c. */ +static tr_bool +isMartianAddr( const struct tr_address * a ) { static const unsigned char v4prefix[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }; static const unsigned char zeroes[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - switch( af ) + assert( tr_isAddress( a ) ); + + switch( a->type ) { - case AF_INET: + case TR_AF_INET: { + const unsigned char * address = (const unsigned char*)&a->addr.addr4; return (address[0] == 0) || (address[0] == 127) || ((address[0] & 0xE0) == 0xE0); + break; + } - case AF_INET6: + case TR_AF_INET6: { + const unsigned char * address = (const unsigned char*)&a->addr.addr6; return (address[0] == 0xFF) || (address[0] == 0xFE && (address[1] & 0xC0) == 0x80) || (memcmp(address, zeroes, 15) == 0 && (address[15] == 0 || address[15] == 1)) || (memcmp(address, v4prefix, 12) == 0); + break; + } default: - return FALSE; + return TRUE; } } + +tr_bool +tr_isValidPeerAddress( const tr_address * addr, tr_port port ) +{ + return ( port != 0 ) + && ( tr_isAddress( addr ) ) + && ( !isMulticastAddress( addr ) ) + && ( !isIPv6LinkLocalAddress( addr ) ) + && ( !isIPv4MappedOrCompatAddress( addr ) ) + && ( !isMartianAddr( addr ) ); +} diff --git a/libtransmission/net.h b/libtransmission/net.h index 2b1d6536c..cf59988c6 100644 --- a/libtransmission/net.h +++ b/libtransmission/net.h @@ -98,10 +98,10 @@ tr_bool tr_net_hasIPv6( tr_port ); /*********************************************************************** * Sockets **********************************************************************/ -int tr_netOpenTCP( tr_session * session, - const tr_address * addr, - tr_port port, - tr_bool isSeed ); +int tr_netOpenPeerSocket( tr_session * session, + const tr_address * addr, + tr_port port, + tr_bool clientIsSeed ); int tr_netBindTCP( const tr_address * addr, tr_port port, @@ -125,7 +125,5 @@ int tr_globalAddress(int af, void *addr, int *addr_len); const unsigned char *tr_globalIPv6( void ); -int tr_isMartian( int af, const unsigned char * address ); - #endif /* _TR_NET_H_ */ diff --git a/libtransmission/peer-io.c b/libtransmission/peer-io.c index 8224ccef2..37fc41626 100644 --- a/libtransmission/peer-io.c +++ b/libtransmission/peer-io.c @@ -431,8 +431,8 @@ tr_peerIoNewOutgoing( tr_session * session, assert( tr_isAddress( addr ) ); assert( torrentHash ); - fd = tr_netOpenTCP( session, addr, port, isSeed ); - dbgmsg( NULL, "tr_netOpenTCP returned fd %d", fd ); + fd = tr_netOpenPeerSocket( session, addr, port, isSeed ); + dbgmsg( NULL, "tr_netOpenPeerSocket returned fd %d", fd ); return fd < 0 ? NULL : tr_peerIoNew( session, parent, addr, port, torrentHash, FALSE, isSeed, fd ); @@ -561,7 +561,7 @@ tr_peerIoReconnect( tr_peerIo * io ) if( io->socket >= 0 ) tr_netClose( session, io->socket ); - io->socket = tr_netOpenTCP( session, &io->addr, io->port, io->isSeed ); + io->socket = tr_netOpenPeerSocket( session, &io->addr, io->port, io->isSeed ); if( io->socket >= 0 ) { tr_netSetTOS( io->socket, session->peerSocketTOS ); diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c index 02bfbc62c..81d9d0ef1 100644 --- a/libtransmission/peer-msgs.c +++ b/libtransmission/peer-msgs.c @@ -982,8 +982,7 @@ parseLtepHandshake( tr_peermsgs * msgs, if( tr_peerIoIsIncoming( msgs->peer->io ) && tr_bencDictFindRaw( &val, "ipv4", &addr, &addr_len ) - && ( addr_len == 4 ) - && ( !tr_isMartian( AF_INET, addr ) ) ) + && ( addr_len == 4 ) ) { pex.addr.type = TR_AF_INET; memcpy( &pex.addr.addr.addr4, addr, 4 ); @@ -992,8 +991,7 @@ parseLtepHandshake( tr_peermsgs * msgs, if( tr_peerIoIsIncoming( msgs->peer->io ) && tr_bencDictFindRaw( &val, "ipv6", &addr, &addr_len ) - && ( addr_len == 16 ) - && ( !tr_isMartian( AF_INET6, addr ) ) ) + && ( addr_len == 16 ) ) { pex.addr.type = TR_AF_INET6; memcpy( &pex.addr.addr.addr6, addr, 16 ); -- 2.40.0