(libT) patch from jhujhiti to add ipv6 support.

This commit is contained in:
Charles Kerr 2008-11-30 00:47:18 +00:00
parent 76cde98d0b
commit a2ad4f6543
21 changed files with 377 additions and 285 deletions

View File

@ -51,7 +51,7 @@ main( void )
char * tmpfile_txt = "transmission-blocklist-test.txt";
char * tmpfile_bin = "transmission-blocklist-test.bin";
#endif
struct in_addr addr;
struct tr_address addr;
int test = 0;
tr_blocklist * b;
@ -63,31 +63,31 @@ main( void )
_tr_blocklistSetContent( b, tmpfile_txt );
/* now run some tests */
check( !tr_netResolve( "216.16.1.143", &addr ) );
check( tr_pton( "216.16.1.143", &addr ) );
check( !_tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.144", &addr ) );
check( tr_pton( "216.16.1.144", &addr ) );
check( _tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.145", &addr ) );
check( tr_pton( "216.16.1.145", &addr ) );
check( _tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.146", &addr ) );
check( tr_pton( "216.16.1.146", &addr ) );
check( _tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.147", &addr ) );
check( tr_pton( "216.16.1.147", &addr ) );
check( _tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.148", &addr ) );
check( tr_pton( "216.16.1.148", &addr ) );
check( _tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.149", &addr ) );
check( tr_pton( "216.16.1.149", &addr ) );
check( _tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.150", &addr ) );
check( tr_pton( "216.16.1.150", &addr ) );
check( _tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.151", &addr ) );
check( tr_pton( "216.16.1.151", &addr ) );
check( _tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.152", &addr ) );
check( tr_pton( "216.16.1.152", &addr ) );
check( !_tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "216.16.1.153", &addr ) );
check( tr_pton( "216.16.1.153", &addr ) );
check( !_tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "217.0.0.1", &addr ) );
check( tr_pton( "217.0.0.1", &addr ) );
check( !_tr_blocklistHasAddress( b, &addr ) );
check( !tr_netResolve( "255.0.0.1", &addr ) );
check( tr_pton( "255.0.0.1", &addr ) );
/* cleanup */
_tr_blocklistFree( b );

View File

@ -31,7 +31,7 @@
#include "transmission.h"
#include "platform.h"
#include "blocklist.h"
#include "net.h" /* tr_netResolve() */
#include "net.h"
#include "utils.h"
/***
@ -198,8 +198,8 @@ _tr_blocklistSetEnabled( tr_blocklist * b,
}
int
_tr_blocklistHasAddress( tr_blocklist * b,
const struct in_addr * addr )
_tr_blocklistHasAddress( tr_blocklist * b,
const tr_address * addr )
{
uint32_t needle;
const struct tr_ip_range * range;
@ -211,7 +211,7 @@ _tr_blocklistHasAddress( tr_blocklist * b,
if( !b->rules )
return 0;
needle = ntohl( addr->s_addr );
needle = ntohl( addr->addr.addr4.s_addr );
range = bsearch( &needle,
b->rules,
@ -259,7 +259,7 @@ _tr_blocklistSetContent( tr_blocklist * b,
{
char * rangeBegin;
char * rangeEnd;
struct in_addr in_addr;
tr_address addr;
struct tr_ip_range range;
rangeBegin = strrchr( line, ':' );
@ -270,13 +270,13 @@ _tr_blocklistSetContent( tr_blocklist * b,
if( !rangeEnd ){ free( line ); continue; }
*rangeEnd++ = '\0';
if( tr_netResolve( rangeBegin, &in_addr ) )
if( !tr_pton( rangeBegin, &addr ) )
tr_err( "blocklist skipped invalid address [%s]\n", rangeBegin );
range.begin = ntohl( in_addr.s_addr );
range.begin = ntohl( addr.addr.addr4.s_addr );
if( tr_netResolve( rangeEnd, &in_addr ) )
if( !tr_pton( rangeEnd, &addr ) )
tr_err( "blocklist skipped invalid address [%s]\n", rangeEnd );
range.end = ntohl( in_addr.s_addr );
range.end = ntohl( addr.addr.addr4.s_addr );
free( line );

View File

@ -17,7 +17,8 @@
#ifndef TR_BLOCKLIST_H
#define TR_BLOCKLIST_H
struct in_addr;
struct tr_address;
typedef struct tr_blocklist tr_blocklist;
tr_blocklist* _tr_blocklistNew( const char * filename,
@ -33,16 +34,13 @@ void _tr_blocklistFree( tr_blocklist * );
int _tr_blocklistIsEnabled( tr_blocklist * );
void _tr_blocklistSetEnabled( tr_blocklist *,
int isEnabled );
void _tr_blocklistSetEnabled( tr_blocklist * ,
int isEnabled );
int _tr_blocklistHasAddress(
tr_blocklist *,
const struct
in_addr * addr );
int _tr_blocklistHasAddress( tr_blocklist *,
const tr_address * addr );
int _tr_blocklistSetContent(
tr_blocklist *,
const char * filename );
int _tr_blocklistSetContent( tr_blocklist *,
const char * filename );
#endif

View File

@ -471,13 +471,13 @@ tr_fdSocketCreate( int type )
}
int
tr_fdSocketAccept( int b,
struct in_addr * addr,
tr_port_t * port )
tr_fdSocketAccept( int b,
tr_address * addr,
tr_port_t * port )
{
int s = -1;
unsigned int len;
struct sockaddr_in sock;
int s = -1;
unsigned int len;
struct sockaddr_storage sock;
assert( addr );
assert( port );
@ -485,13 +485,28 @@ tr_fdSocketAccept( int b,
tr_lockLock( gFd->lock );
if( gFd->socketCount < getSocketMax( gFd ) )
{
len = sizeof( sock );
len = sizeof( struct sockaddr );
s = accept( b, (struct sockaddr *) &sock, &len );
}
if( s > -1 )
{
*addr = sock.sin_addr;
*port = sock.sin_port;
/* "The ss_family field of the sockaddr_storage structure will always
* align with the family field of any protocol-specific structure." */
if( sock.ss_family == AF_INET )
{
struct sockaddr_in * sock4 = (struct sockaddr_in *)&sock;
addr->type = TR_AF_INET;
addr->addr.addr4.s_addr = sock4->sin_addr.s_addr;
*port = sock4->sin_port;
}
else
{
struct sockaddr_in6 * sock6 = (struct sockaddr_in6 *)&sock;
addr->type = TR_AF_INET6;
memcpy( &addr->addr, &sock6->sin6_addr,
sizeof( struct sockaddr_in6 ) );
*port = sock6->sin6_port;
}
++gFd->socketCount;
}
tr_lockUnlock( gFd->lock );

View File

@ -87,9 +87,9 @@ void tr_fdFileClose( const char * filename );
**********************************************************************/
int tr_fdSocketCreate( int type );
int tr_fdSocketAccept( int b,
struct in_addr * addr,
tr_port_t * port );
int tr_fdSocketAccept( int b,
tr_address * addr,
tr_port_t * port );
void tr_fdSocketClose( int s );

View File

@ -1196,9 +1196,9 @@ tr_handshakeGetIO( tr_handshake * handshake )
return handshake->io;
}
const struct in_addr *
const tr_address *
tr_handshakeGetAddr( const struct tr_handshake * handshake,
uint16_t * port )
uint16_t * port )
{
assert( handshake );
assert( handshake->io );

View File

@ -19,7 +19,6 @@
#include "transmission.h"
struct in_addr;
struct tr_peerIo;
typedef struct tr_handshake tr_handshake;
@ -35,10 +34,8 @@ tr_handshake * tr_handshakeNew( struct tr_peerIo * io,
handshakeDoneCB doneCB,
void * doneUserData );
const struct in_addr * tr_handshakeGetAddr(
const struct tr_handshake * handshake,
uint16_t
* setme_port );
const tr_address * tr_handshakeGetAddr( const struct tr_handshake * handshake,
uint16_t * setme_port );
void tr_handshakeAbort( tr_handshake * handshake );

View File

@ -47,6 +47,9 @@
#include "platform.h"
#include "utils.h"
const tr_address tr_in6addr_any = { TR_AF_INET6, { IN6ADDR_ANY_INIT } };
const tr_address tr_inaddr_any = { TR_AF_INET,
{ { { { INADDR_ANY, 0x00, 0x00, 0x00 } } } } };
void
tr_netInit( void )
@ -63,19 +66,79 @@ tr_netInit( void )
}
}
/***********************************************************************
* DNS resolution
*
* Synchronous "resolution": only works with character strings
* representing numbers expressed in the Internet standard `.' notation.
* Returns a non-zero value if an error occurs.
**********************************************************************/
int
tr_netResolve( const char * address,
struct in_addr * addr )
const char *
tr_ntop( const tr_address * src,
char * dst,
int size )
{
addr->s_addr = inet_addr( address );
return addr->s_addr == 0xFFFFFFFF;
if( src->type == TR_AF_INET )
return inet_ntop( AF_INET, &src->addr, dst, size );
else
return inet_ntop( AF_INET6, &src->addr, dst, size );
}
/*
* Non-threadsafe version of tr_ntop, which uses a static memory area for a buffer.
* This function is suitable to be called from libTransmission's networking code,
* which is single-threaded.
*/
const char *
tr_ntop_non_ts( const tr_address * src )
{
static char buf[INET6_ADDRSTRLEN];
return tr_ntop( src, buf, sizeof( buf ) );
}
tr_address *
tr_pton( const char * src,
tr_address * dst )
{
int retval = inet_pton( AF_INET, src, &dst->addr );
if( retval < 0 )
return NULL;
else if( retval == 0 )
retval = inet_pton( AF_INET6, src, &dst->addr );
else
{
dst->type = TR_AF_INET;
return dst;
}
if( retval < 1 )
return NULL;
dst->type = TR_AF_INET6;
return dst;
}
/*
* Compare two tr_address structures.
* Returns:
* <0 if a < b
* >0 if a > b
* 0 if a == b
*/
int
tr_compareAddresses( const tr_address * a,
const tr_address * b)
{
int retval;
int addrlen;
/* IPv6 addresses are always "greater than" IPv4 */
if( a->type == TR_AF_INET && b->type == TR_AF_INET6 )
return 1;
if( a->type == TR_AF_INET6 && b->type == TR_AF_INET )
return -1;
if( a->type == TR_AF_INET )
addrlen = sizeof( struct in_addr );
else
addrlen = sizeof( struct in6_addr );
retval = memcmp( &a->addr, &b->addr, addrlen );
if( retval == 0 )
return 0;
return retval;
}
/***********************************************************************
@ -136,27 +199,49 @@ setSndBuf( tr_session * session UNUSED, int fd UNUSED )
#endif
}
int
tr_netOpenTCP( tr_session * session,
const struct in_addr * addr,
tr_port_t port )
static void
setup_sockaddr( const tr_address * addr,
tr_port_t port,
struct sockaddr_storage * sockaddr)
{
int s;
struct sockaddr_in sock;
const int type = SOCK_STREAM;
struct sockaddr_in sock4;
struct sockaddr_in6 sock6;
if( addr->type == TR_AF_INET )
{
memset( &sock4, 0, sizeof( sock4 ) );
sock4.sin_family = AF_INET;
sock4.sin_addr.s_addr = addr->addr.addr4.s_addr;
sock4.sin_port = port;
memcpy( sockaddr, &sock4, sizeof( sock4 ) );
}
else
{
memset( &sock6, 0, sizeof( sock6 ) );
sock6.sin6_family = AF_INET6;
sock6.sin6_port = port;
memcpy( &sock6.sin6_addr, &addr->addr, sizeof( struct in6_addr ) );
memcpy( sockaddr, &sock6, sizeof( sock6 ) );
}
}
int
tr_netOpenTCP( tr_session * session,
const tr_address * addr,
tr_port_t port )
{
int s;
struct sockaddr_storage sock;
const int type = SOCK_STREAM;
if( ( s = createSocket( type ) ) < 0 )
return -1;
setSndBuf( session, s );
memset( &sock, 0, sizeof( sock ) );
sock.sin_family = AF_INET;
sock.sin_addr.s_addr = addr->s_addr;
sock.sin_port = port;
setup_sockaddr( addr, port, &sock );
if( ( connect( s, (struct sockaddr *) &sock,
sizeof( struct sockaddr_in ) ) < 0 )
sizeof( struct sockaddr ) ) < 0 )
#ifdef WIN32
&& ( sockerrno != WSAEWOULDBLOCK )
#endif
@ -164,7 +249,7 @@ tr_netOpenTCP( tr_session * session,
{
tr_err( _(
"Couldn't connect socket %d to %s, port %d (errno %d - %s)" ),
s, inet_ntoa( *addr ), port,
s, tr_ntop_non_ts( addr ), port,
sockerrno, tr_strerror( sockerrno ) );
tr_netClose( s );
s = -1;
@ -177,11 +262,12 @@ tr_netOpenTCP( tr_session * session,
}
int
tr_netBindTCP( int port )
tr_netBindTCP( const tr_address * addr,
int port )
{
int s;
struct sockaddr_in sock;
const int type = SOCK_STREAM;
int s;
struct sockaddr_storage sock;
const int type = SOCK_STREAM;
#if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT )
int optval;
@ -194,30 +280,28 @@ tr_netBindTCP( int port )
optval = 1;
setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof( optval ) );
#endif
memset( &sock, 0, sizeof( sock ) );
sock.sin_family = AF_INET;
sock.sin_addr.s_addr = INADDR_ANY;
sock.sin_port = htons( port );
setup_sockaddr( addr, htons( port ), &sock );
if( bind( s, (struct sockaddr *) &sock,
sizeof( struct sockaddr_in ) ) )
sizeof( struct sockaddr ) ) )
{
tr_err( _( "Couldn't bind port %d: %s" ), port,
tr_strerror( sockerrno ) );
tr_err( _( "Couldn't bind port %d on %s: %s" ), port,
tr_ntop_non_ts( addr ), tr_strerror( sockerrno ) );
tr_netClose( s );
return -1;
}
tr_dbg( "Bound socket %d to port %d", s, port );
tr_dbg( "Bound socket %d to port %d on %s", s, port,
tr_ntop_non_ts( addr ) );
return s;
}
int
tr_netAccept( tr_session * session,
int b,
struct in_addr * addr,
tr_port_t * port )
tr_netAccept( tr_session * session,
int b,
tr_address * addr,
tr_port_t * port )
{
int fd = makeSocketNonBlocking( tr_fdSocketAccept( b, addr, port ) );
setSndBuf( session, fd );
@ -229,16 +313,3 @@ tr_netClose( int s )
{
tr_fdSocketClose( s );
}
void
tr_netNtop( const struct in_addr * addr,
char * buf,
int len )
{
const uint8_t * cast;
cast = (const uint8_t *)addr;
tr_snprintf( buf, len, "%hhu.%hhu.%hhu.%hhu",
cast[0], cast[1], cast[2], cast[3] );
}

View File

@ -60,40 +60,54 @@
#define sockerrno errno
#endif
struct in_addr;
struct sockaddr_in;
struct tr_session;
/***********************************************************************
* DNS resolution
**********************************************************************/
int tr_netResolve( const char *,
struct in_addr * );
#define TR_AF_INET 0
#define TR_AF_INET6 1
typedef struct tr_address {
unsigned short type : 1;
union {
/* The order here is important for tr_in{,6}addr_any initialization,
* since we can't use C99 designated initializers */
struct in6_addr addr6;
struct in_addr addr4;
} addr;
} tr_address;
extern const tr_address tr_inaddr_any;
extern const tr_address tr_in6addr_any;
const char *tr_ntop( const tr_address * src,
char * dst,
int size );
const char *tr_ntop_non_ts( const tr_address * src );
tr_address *tr_pton( const char * src,
tr_address * dst );
int tr_compareAddresses( const tr_address * a,
const tr_address * b);
/***********************************************************************
* Sockets
**********************************************************************/
int tr_netOpenTCP( struct tr_handle * session,
const struct in_addr * addr,
tr_port_t port );
int tr_netOpenTCP( struct tr_handle * session,
const tr_address * addr,
tr_port_t port );
int tr_netBindTCP( int port );
int tr_netBindTCP( const tr_address * addr,
int port );
int tr_netAccept( struct tr_handle * session,
int bound,
struct in_addr * setme_addr,
tr_port_t * setme_port );
int tr_netAccept( struct tr_handle * session,
int bound,
tr_address * setme_addr,
tr_port_t * setme_port );
int tr_netSetTOS( int s,
int tos );
void tr_netClose( int s );
void tr_netNtop( const struct in_addr * addr,
char * buf,
int len );
void tr_netInit( void );
#endif /* _TR_NET_H_ */

View File

@ -19,7 +19,6 @@
#ifdef WIN32
#include <winsock2.h>
#else
#include <netinet/in.h> /* struct in_addr */
#include <arpa/inet.h> /* inet_ntoa */
#endif
@ -97,7 +96,7 @@ struct tr_peerIo
tr_session * session;
struct in_addr in_addr;
tr_address addr;
struct tr_iobuf * iobuf;
tr_list * output_datatypes; /* struct tr_datatype */
@ -238,12 +237,12 @@ isPeerIo( const tr_peerIo * io )
}
static tr_peerIo*
tr_peerIoNew( tr_session * session,
const struct in_addr * in_addr,
uint16_t port,
const uint8_t * torrentHash,
int isIncoming,
int socket )
tr_peerIoNew( tr_session * session,
const tr_address * addr,
uint16_t port,
const uint8_t * torrentHash,
int isIncoming,
int socket )
{
tr_peerIo * io;
@ -254,7 +253,7 @@ tr_peerIoNew( tr_session * session,
io->magicNumber = MAGIC_NUMBER;
io->crypto = tr_cryptoNew( torrentHash, isIncoming );
io->session = session;
io->in_addr = *in_addr;
io->addr = *addr;
io->port = port;
io->socket = socket;
io->isIncoming = isIncoming != 0;
@ -266,38 +265,38 @@ tr_peerIoNew( tr_session * session,
}
tr_peerIo*
tr_peerIoNewIncoming( tr_session * session,
const struct in_addr * in_addr,
uint16_t port,
int socket )
tr_peerIoNewIncoming( tr_session * session,
const tr_address * addr,
uint16_t port,
int socket )
{
assert( session );
assert( in_addr );
assert( addr );
assert( socket >= 0 );
return tr_peerIoNew( session, in_addr, port,
return tr_peerIoNew( session, addr, port,
NULL, 1,
socket );
}
tr_peerIo*
tr_peerIoNewOutgoing( tr_session * session,
const struct in_addr * in_addr,
int port,
const uint8_t * torrentHash )
tr_peerIoNewOutgoing( tr_session * session,
const tr_address * addr,
int port,
const uint8_t * torrentHash )
{
int socket;
assert( session );
assert( in_addr );
assert( addr );
assert( port >= 0 );
assert( torrentHash );
socket = tr_netOpenTCP( session, in_addr, port );
socket = tr_netOpenTCP( session, addr, port );
return socket < 0
? NULL
: tr_peerIoNew( session, in_addr, port, torrentHash, 0, socket );
: tr_peerIoNew( session, addr, port, torrentHash, 0, socket );
}
static void
@ -336,33 +335,37 @@ tr_peerIoGetSession( tr_peerIo * io )
return io->session;
}
const struct in_addr*
const tr_address*
tr_peerIoGetAddress( const tr_peerIo * io,
uint16_t * port )
uint16_t * port )
{
assert( isPeerIo( io ) );
if( port )
*port = io->port;
return &io->in_addr;
return &io->addr;
}
const char*
tr_peerIoAddrStr( const struct in_addr * addr,
uint16_t port )
tr_peerIoAddrStr( const tr_address * addr,
uint16_t port )
{
static char buf[512];
tr_snprintf( buf, sizeof( buf ), "%s:%u", inet_ntoa( *addr ),
ntohs( port ) );
if( addr->type == TR_AF_INET )
tr_snprintf( buf, sizeof( buf ), "%s:%u", tr_ntop_non_ts( addr ),
ntohs( port ) );
else
tr_snprintf( buf, sizeof( buf ), "[%s]:%u", tr_ntop_non_ts( addr ),
ntohs( port ) );
return buf;
}
const char*
tr_peerIoGetAddrStr( const tr_peerIo * io )
{
return tr_peerIoAddrStr( &io->in_addr, io->port );
return tr_peerIoAddrStr( &io->addr, io->port );
}
static void
@ -401,7 +404,7 @@ tr_peerIoReconnect( tr_peerIo * io )
if( io->socket >= 0 )
tr_netClose( io->socket );
io->socket = tr_netOpenTCP( io->session, &io->in_addr, io->port );
io->socket = tr_netOpenTCP( io->session, &io->addr, io->port );
if( io->socket >= 0 )
{

View File

@ -21,7 +21,6 @@
***
**/
struct in_addr;
struct evbuffer;
struct tr_bandwidth;
struct tr_crypto;
@ -32,15 +31,15 @@ typedef struct tr_peerIo tr_peerIo;
***
**/
tr_peerIo* tr_peerIoNewOutgoing( struct tr_handle * session,
const struct in_addr * addr,
int port,
const uint8_t * torrentHash );
tr_peerIo* tr_peerIoNewOutgoing( struct tr_handle * session,
const tr_address * addr,
int port,
const uint8_t * torrentHash );
tr_peerIo* tr_peerIoNewIncoming( struct tr_handle * session,
const struct in_addr * addr,
uint16_t port,
int socket );
tr_peerIo* tr_peerIoNewIncoming( struct tr_handle * session,
const tr_address * addr,
uint16_t port,
int socket );
void tr_peerIoFree( tr_peerIo * io );
@ -59,12 +58,12 @@ int tr_peerIoSupportsLTEP( const tr_peerIo * io );
***
**/
const char* tr_peerIoAddrStr( const struct in_addr * addr,
uint16_t port );
const char* tr_peerIoAddrStr( const tr_address * addr,
uint16_t port );
const char* tr_peerIoGetAddrStr( const tr_peerIo * io );
const struct in_addr*tr_peerIoGetAddress( const tr_peerIo * io,
const tr_address * tr_peerIoGetAddress( const tr_peerIo * io,
uint16_t * port );
const uint8_t* tr_peerIoGetTorrentHash( tr_peerIo * io );

View File

@ -21,8 +21,6 @@
#ifdef WIN32
#include <winsock2.h> /* struct in_addr */
#else
#include <netinet/in.h> /* struct in_addr */
#endif
#include "publish.h" /* tr_publisher_tag */
@ -52,7 +50,7 @@ typedef struct tr_peer
uint8_t encryption_preference;
uint16_t port;
struct in_addr in_addr;
tr_address addr;
struct tr_peerIo * io;
struct tr_bitfield * blame;

View File

@ -95,14 +95,14 @@ enum
* into this list for new ones. */
struct peer_atom
{
uint8_t from;
uint8_t flags; /* these match the added_f flags */
uint8_t myflags; /* flags that aren't defined in added_f */
uint16_t port;
uint16_t numFails;
struct in_addr addr;
time_t time; /* when the peer's connection status last changed */
time_t piece_data_time;
uint8_t from;
uint8_t flags; /* these match the added_f flags */
uint8_t myflags; /* flags that aren't defined in added_f */
uint16_t port;
uint16_t numFails;
tr_address addr;
time_t time; /* when the peer's connection status last changed */
time_t piece_data_time;
};
typedef struct
@ -183,23 +183,13 @@ torrentIsLocked( const Torrent * t )
***
**/
static int
compareAddresses( const struct in_addr * a,
const struct in_addr * b )
{
if( a->s_addr != b->s_addr )
return a->s_addr < b->s_addr ? -1 : 1;
return 0;
}
static int
handshakeCompareToAddr( const void * va,
const void * vb )
{
const tr_handshake * a = va;
return compareAddresses( tr_handshakeGetAddr( a, NULL ), vb );
return tr_compareAddresses( tr_handshakeGetAddr( a, NULL ), vb );
}
static int
@ -210,11 +200,11 @@ handshakeCompare( const void * a,
}
static tr_handshake*
getExistingHandshake( tr_ptrArray * handshakes,
const struct in_addr * in_addr )
getExistingHandshake( tr_ptrArray * handshakes,
const tr_address * addr )
{
return tr_ptrArrayFindSorted( handshakes,
in_addr,
addr,
handshakeCompareToAddr );
}
@ -224,7 +214,7 @@ comparePeerAtomToAddress( const void * va,
{
const struct peer_atom * a = va;
return compareAddresses( &a->addr, vb );
return tr_compareAddresses( &a->addr, vb );
}
static int
@ -276,7 +266,7 @@ peerCompare( const void * va,
const tr_peer * a = va;
const tr_peer * b = vb;
return compareAddresses( &a->in_addr, &b->in_addr );
return tr_compareAddresses( &a->addr, &b->addr );
}
static int
@ -285,32 +275,32 @@ peerCompareToAddr( const void * va,
{
const tr_peer * a = va;
return compareAddresses( &a->in_addr, vb );
return tr_compareAddresses( &a->addr, vb );
}
static tr_peer*
getExistingPeer( Torrent * torrent,
const struct in_addr * in_addr )
getExistingPeer( Torrent * torrent,
const tr_address * addr )
{
assert( torrentIsLocked( torrent ) );
assert( in_addr );
assert( addr );
return tr_ptrArrayFindSorted( torrent->peers,
in_addr,
addr,
peerCompareToAddr );
}
static struct peer_atom*
getExistingAtom( const Torrent * t,
const struct in_addr * addr )
getExistingAtom( const Torrent * t,
const tr_address * addr )
{
assert( torrentIsLocked( t ) );
return tr_ptrArrayFindSorted( t->pool, addr, comparePeerAtomToAddress );
}
static int
peerIsInUse( const Torrent * ct,
const struct in_addr * addr )
peerIsInUse( const Torrent * ct,
const tr_address * addr )
{
Torrent * t = (Torrent*) ct;
@ -322,29 +312,29 @@ peerIsInUse( const Torrent * ct,
}
static tr_peer*
peerConstructor( tr_torrent * tor, const struct in_addr * in_addr )
peerConstructor( tr_torrent * tor, const tr_address * addr )
{
tr_peer * p;
p = tr_new0( tr_peer, 1 );
memcpy( &p->in_addr, in_addr, sizeof( struct in_addr ) );
memcpy( &p->addr, addr, sizeof( tr_address ) );
p->bandwidth = tr_bandwidthNew( tor->session, tor->bandwidth );
return p;
}
static tr_peer*
getPeer( Torrent * torrent,
const struct in_addr * in_addr )
getPeer( Torrent * torrent,
const tr_address * addr )
{
tr_peer * peer;
assert( torrentIsLocked( torrent ) );
peer = getExistingPeer( torrent, in_addr );
peer = getExistingPeer( torrent, addr );
if( peer == NULL )
{
peer = peerConstructor( torrent->tor, in_addr );
peer = peerConstructor( torrent->tor, addr );
tr_ptrArrayInsertSorted( torrent->peers, peer, peerCompare );
}
@ -380,7 +370,7 @@ removePeer( Torrent * t,
assert( torrentIsLocked( t ) );
atom = getExistingAtom( t, &peer->in_addr );
atom = getExistingAtom( t, &peer->addr );
assert( atom );
atom->time = time( NULL );
@ -530,9 +520,9 @@ clientIsUploadingTo( const tr_peer * peer )
***/
int
tr_peerMgrPeerIsSeed( const tr_peerMgr * mgr,
const uint8_t * torrentHash,
const struct in_addr * addr )
tr_peerMgrPeerIsSeed( const tr_peerMgr * mgr,
const uint8_t * torrentHash,
const tr_address * addr )
{
int isSeed = FALSE;
const Torrent * t = NULL;
@ -905,12 +895,12 @@ addStrike( Torrent * t,
tr_peer * peer )
{
tordbg( t, "increasing peer %s strike count to %d",
tr_peerIoAddrStr( &peer->in_addr,
tr_peerIoAddrStr( &peer->addr,
peer->port ), peer->strikes + 1 );
if( ++peer->strikes >= MAX_BAD_PIECES_PER_PEER )
{
struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
struct peer_atom * atom = getExistingAtom( t, &peer->addr );
atom->myflags |= MYFLAG_BANNED;
peer->doPurge = 1;
tordbg( t, "banning peer %s",
@ -975,7 +965,7 @@ peerCallbackFunc( void * vpeer,
/* update our atom */
if( peer ) {
struct peer_atom * a = getExistingAtom( t, &peer->in_addr );
struct peer_atom * a = getExistingAtom( t, &peer->addr );
a->piece_data_time = now;
}
@ -1004,7 +994,7 @@ peerCallbackFunc( void * vpeer,
/* update our atom */
if( peer ) {
struct peer_atom * a = getExistingAtom( t, &peer->in_addr );
struct peer_atom * a = getExistingAtom( t, &peer->addr );
a->piece_data_time = now;
}
@ -1015,8 +1005,7 @@ peerCallbackFunc( void * vpeer,
{
if( peer )
{
struct peer_atom * atom = getExistingAtom( t,
&peer->in_addr );
struct peer_atom * atom = getExistingAtom( t, &peer->addr );
const int peerIsSeed = e->progress >= 1.0;
if( peerIsSeed )
{
@ -1111,11 +1100,11 @@ peerCallbackFunc( void * vpeer,
}
static void
ensureAtomExists( Torrent * t,
const struct in_addr * addr,
uint16_t port,
uint8_t flags,
uint8_t from )
ensureAtomExists( Torrent * t,
const tr_address * addr,
uint16_t port,
uint8_t flags,
uint8_t from )
{
if( getExistingAtom( t, addr ) == NULL )
{
@ -1152,13 +1141,13 @@ myHandshakeDoneCB( tr_handshake * handshake,
const uint8_t * peer_id,
void * vmanager )
{
int ok = isConnected;
int success = FALSE;
uint16_t port;
const struct in_addr * addr;
tr_peerMgr * manager = (tr_peerMgr*) vmanager;
Torrent * t;
tr_handshake * ours;
int ok = isConnected;
int success = FALSE;
uint16_t port;
const tr_address * addr;
tr_peerMgr * manager = (tr_peerMgr*) vmanager;
Torrent * t;
tr_handshake * ours;
assert( io );
assert( isConnected == 0 || isConnected == 1 );
@ -1253,17 +1242,17 @@ myHandshakeDoneCB( tr_handshake * handshake,
}
void
tr_peerMgrAddIncoming( tr_peerMgr * manager,
struct in_addr * addr,
uint16_t port,
int socket )
tr_peerMgrAddIncoming( tr_peerMgr * manager,
tr_address * addr,
uint16_t port,
int socket )
{
managerLock( manager );
if( tr_sessionIsAddressBlocked( manager->session, addr ) )
{
tr_dbg( "Banned IP address \"%s\" tried to connect to us",
inet_ntoa( *addr ) );
tr_ntop_non_ts( addr ) );
tr_netClose( socket );
}
else if( getExistingHandshake( manager->incomingHandshakes, addr ) )
@ -1300,8 +1289,8 @@ tr_peerMgrAddPex( tr_peerMgr * manager,
managerLock( manager );
t = getExistingTorrent( manager, torrentHash );
if( !tr_sessionIsAddressBlocked( t->manager->session, &pex->in_addr ) )
ensureAtomExists( t, &pex->in_addr, pex->port, pex->flags, from );
if( !tr_sessionIsAddressBlocked( t->manager->session, &pex->addr ) )
ensureAtomExists( t, &pex->addr, pex->port, pex->flags, from );
managerUnlock( manager );
}
@ -1320,7 +1309,8 @@ tr_peerMgrCompactToPex( const void * compact,
for( i = 0; i < n; ++i )
{
memcpy( &pex[i].in_addr, walk, 4 ); walk += 4;
pex[i].addr.type = TR_AF_INET;
memcpy( &pex[i].addr.addr, walk, 4 ); walk += 4;
memcpy( &pex[i].port, walk, 2 ); walk += 2;
if( added_f && ( n == added_f_len ) )
pex[i].flags = added_f[i];
@ -1357,7 +1347,7 @@ tr_peerMgrSetBlame( tr_peerMgr * manager,
tordbg(
t,
"peer %s contributed to corrupt piece (%d); now has %d strikes",
tr_peerIoAddrStr( &peer->in_addr, peer->port ),
tr_peerIoAddrStr( &peer->addr, peer->port ),
pieceIndex, (int)peer->strikes + 1 );
addStrike( t, peer );
}
@ -1371,8 +1361,7 @@ tr_pexCompare( const void * va,
{
const tr_pex * a = va;
const tr_pex * b = vb;
int i =
memcmp( &a->in_addr, &b->in_addr, sizeof( struct in_addr ) );
int i = tr_compareAddresses( &a->addr, &b->addr );
if( i ) return i;
if( a->port < b->port ) return -1;
@ -1420,7 +1409,7 @@ tr_peerMgrGetPeers( tr_peerMgr * manager,
for( i = 0; i < peerCount; ++i, ++walk )
{
const tr_peer * peer = peers[i];
walk->in_addr = peer->in_addr;
walk->addr = peer->addr;
walk->port = peer->port;
walk->flags = 0;
if( peerPrefersCrypto( peer ) ) walk->flags |= ADDED_F_ENCRYPTION_FLAG;
@ -1658,7 +1647,7 @@ tr_peerMgrTorrentStats( const tr_peerMgr * manager,
for( i = 0; i < size; ++i )
{
const tr_peer * peer = peers[i];
const struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
const struct peer_atom * atom = getExistingAtom( t, &peer->addr );
if( peer->io == NULL ) /* not connected */
continue;
@ -1746,10 +1735,10 @@ tr_peerMgrPeerStats( const tr_peerMgr * manager,
{
char * pch;
const tr_peer * peer = peers[i];
const struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
const struct peer_atom * atom = getExistingAtom( t, &peer->addr );
tr_peer_stat * stat = ret + i;
tr_netNtop( &peer->in_addr, stat->addr, sizeof( stat->addr ) );
tr_ntop( &peer->addr, stat->addr, sizeof( stat->addr ) );
tr_strlcpy( stat->client, ( peer->client ? peer->client : "" ),
sizeof( stat->client ) );
stat->port = ntohs( peer->port );
@ -1945,7 +1934,7 @@ shouldPeerBeClosed( const Torrent * t,
{
const tr_torrent * tor = t->tor;
const time_t now = time( NULL );
const struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
const struct peer_atom * atom = getExistingAtom( t, &peer->addr );
/* if it's marked for purging, close it */
if( peer->doPurge )
@ -2207,7 +2196,7 @@ reconnectPulse( void * vtorrent )
for( i = 0; i < nBad; ++i )
{
tr_peer * peer = connections[i];
struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
struct peer_atom * atom = getExistingAtom( t, &peer->addr );
if( peer->pieceDataActivityDate )
atom->numFails = 0;
else

View File

@ -21,11 +21,10 @@
#ifdef WIN32
#include <winsock2.h> /* struct in_addr */
#else
#include <netinet/in.h> /* struct in_addr */
#endif
struct in_addr;
#include "net.h"
struct tr_handle;
struct tr_peer_stat;
struct tr_torrent;
@ -42,9 +41,9 @@ enum
typedef struct tr_pex
{
struct in_addr in_addr;
uint16_t port;
uint8_t flags;
tr_address addr;
uint16_t port;
uint8_t flags;
}
tr_pex;
@ -54,14 +53,14 @@ tr_peerMgr* tr_peerMgrNew( struct tr_handle * );
void tr_peerMgrFree( tr_peerMgr * manager );
int tr_peerMgrPeerIsSeed( const tr_peerMgr * mgr,
const uint8_t * torrentHash,
const struct in_addr * addr );
int tr_peerMgrPeerIsSeed( const tr_peerMgr * mgr,
const uint8_t * torrentHash,
const tr_address * addr );
void tr_peerMgrAddIncoming( tr_peerMgr * manager,
struct in_addr * addr,
uint16_t port,
int socket );
void tr_peerMgrAddIncoming( tr_peerMgr * manager,
tr_address * addr,
uint16_t port,
int socket );
tr_pex * tr_peerMgrCompactToPex( const void * compact,
size_t compactLen,

View File

@ -1759,6 +1759,7 @@ pexElementCb( void * vpex,
diffs->elements[diffs->elementCount++] = *pex;
}
/* TODO: ipv6 pex */
static void
sendPex( tr_peermsgs * msgs )
{
@ -1806,7 +1807,7 @@ sendPex( tr_peermsgs * msgs )
/* "added" */
tmp = walk = tr_new( uint8_t, diffs.addedCount * 6 );
for( i = 0; i < diffs.addedCount; ++i ) {
memcpy( walk, &diffs.added[i].in_addr, 4 ); walk += 4;
memcpy( walk, &diffs.added[i].addr.addr, 4 ); walk += 4;
memcpy( walk, &diffs.added[i].port, 2 ); walk += 2;
}
assert( ( walk - tmp ) == diffs.addedCount * 6 );
@ -1824,7 +1825,7 @@ sendPex( tr_peermsgs * msgs )
/* "dropped" */
tmp = walk = tr_new( uint8_t, diffs.droppedCount * 6 );
for( i = 0; i < diffs.droppedCount; ++i ) {
memcpy( walk, &diffs.dropped[i].in_addr, 4 ); walk += 4;
memcpy( walk, &diffs.dropped[i].addr.addr, 4 ); walk += 4;
memcpy( walk, &diffs.dropped[i].port, 2 ); walk += 2;
}
assert( ( walk - tmp ) == diffs.droppedCount * 6 );

View File

@ -114,7 +114,8 @@ incomingPeersPulse( tr_shared * s )
{
int socket;
errno = 0;
socket = tr_netBindTCP( s->publicPort );
/* TODO: this is where we want to listen on another socket */
socket = tr_netBindTCP( &tr_inaddr_any, s->publicPort );
if( socket >= 0 )
{
tr_ninf( getKey( ),
@ -138,9 +139,9 @@ incomingPeersPulse( tr_shared * s )
for( ; ; ) /* check for new incoming peer connections */
{
int socket;
uint16_t port;
struct in_addr addr;
int socket;
uint16_t port;
tr_address addr;
if( s->bindSocket < 0 )
break;

View File

@ -61,6 +61,7 @@ getResumeFilename( const tr_torrent * tor )
****
***/
/* TODO: fast resume is done with pex */
static void
savePeers( tr_benc * dict,
const tr_torrent * tor )

View File

@ -799,8 +799,8 @@ tr_blocklistSetContent( tr_session * session,
}
int
tr_sessionIsAddressBlocked( const tr_session * session,
const struct in_addr * addr )
tr_sessionIsAddressBlocked( const tr_session * session,
const tr_address * addr )
{
tr_list * l;

View File

@ -39,6 +39,8 @@
#endif
#endif
#include "net.h"
typedef enum { TR_NET_OK, TR_NET_ERROR, TR_NET_WAIT } tr_tristate_t;
@ -121,10 +123,8 @@ void tr_sessionSetTorrentFile( tr_session * session,
const char * hashString,
const char * filename );
struct in_addr;
int tr_sessionIsAddressBlocked( const tr_session * session,
const struct in_addr * addr );
int tr_sessionIsAddressBlocked( const tr_session * session,
const tr_address * addr );
void tr_globalLock( tr_session * );

View File

@ -280,6 +280,7 @@ static uint8_t *
parseOldPeers( tr_benc * bePeers,
size_t * byteCount )
{
/* TODO: wtf */
int i;
uint8_t * compact, *walk;
const int peerCount = bePeers->val.l.count;
@ -290,17 +291,21 @@ parseOldPeers( tr_benc * bePeers,
for( i = 0, walk = compact; i < peerCount; ++i )
{
const char * s;
int64_t itmp;
struct in_addr addr;
tr_port_t port;
tr_benc * peer = &bePeers->val.l.vals[i];
const char * s;
int64_t itmp;
tr_address addr;
tr_port_t port;
tr_benc * peer = &bePeers->val.l.vals[i];
if( !tr_bencDictFindStr( peer, "ip",
&s ) || tr_netResolve( s, &addr ) )
continue;
if( tr_bencDictFindStr( peer, "ip", &s ) )
{
if( tr_pton( s, &addr ) == NULL )
continue;
if( addr.type != TR_AF_INET )
continue;
}
memcpy( walk, &addr, 4 );
memcpy( walk, &addr.addr.addr4.s_addr, 4 );
walk += 4;
if( !tr_bencDictFindInt( peer, "port",

View File

@ -49,6 +49,7 @@ extern "C" {
#define PRIu32 "lu"
#endif
#include <time.h> /* time_t */
#include <netinet/in.h> /* INET6_ADDRSTRLEN */
#define SHA_DIGEST_LENGTH 20
@ -1061,7 +1062,7 @@ typedef struct tr_peer_stat
uint8_t from;
uint16_t port;
char addr[16];
char addr[INET6_ADDRSTRLEN];
char client[80];
char flagStr[32];