This is loosely related to #2910, but only in the sense of laying the groundwork for #2910's fix...
continue;
if( !tr_bencDictFindStr( peer, "ip", &ip ) )
continue;
- if( tr_pton( ip, &addr ) == NULL )
+ if( !tr_address_from_string( &addr, ip ) )
continue;
if( !tr_bencDictFindInt( peer, "port", &port ) )
continue;
if( ( port < 0 ) || ( port > USHRT_MAX ) )
continue;
- if( !tr_isValidPeerAddress( &addr, port ) )
+ if( !tr_address_is_valid_for_peers( &addr, port ) )
continue;
pex[n].addr = addr;
_tr_blocklistSetContent( b, tmpfile_txt );
/* now run some tests */
- check( tr_pton( "216.16.1.143", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.143" ) );
check( !_tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.144", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.144" ) );
check( _tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.145", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.145" ) );
check( _tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.146", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.146" ) );
check( _tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.147", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.147" ) );
check( _tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.148", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.148" ) );
check( _tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.149", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.149" ) );
check( _tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.150", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.150" ) );
check( _tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.151", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.151" ) );
check( _tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.152", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.152" ) );
check( !_tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "216.16.1.153", &addr ) );
+ check( tr_address_from_string( &addr, "216.16.1.153" ) );
check( !_tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "217.0.0.1", &addr ) );
+ check( tr_address_from_string( &addr, "217.0.0.1" ) );
check( !_tr_blocklistHasAddress( b, &addr ) );
- check( tr_pton( "255.0.0.1", &addr ) );
+ check( tr_address_from_string( &addr, "255.0.0.1" ) );
/* cleanup */
_tr_blocklistFree( b );
}
void
-_tr_blocklistSetEnabled( tr_blocklist * b,
- int isEnabled )
+_tr_blocklistSetEnabled( tr_blocklist * b, bool isEnabled )
{
b->isEnabled = isEnabled ? 1 : 0;
}
int
-_tr_blocklistHasAddress( tr_blocklist * b,
- const tr_address * addr )
+_tr_blocklistHasAddress( tr_blocklist * b, const tr_address * addr )
{
uint32_t needle;
const struct tr_ipv4_range * range;
- assert( tr_isAddress( addr ) );
+ assert( tr_address_is_valid( addr ) );
if( !b->isEnabled || addr->type == TR_AF_INET6 )
return 0;
return false;
tr_snprintf( str, sizeof( str ), "%d.%d.%d.%d", b[0], b[1], b[2], b[3] );
- if( tr_pton( str, &addr ) == NULL )
+ if( !tr_address_from_string( &addr, str ) )
return false;
range->begin = ntohl( addr.addr.addr4.s_addr );
tr_snprintf( str, sizeof( str ), "%d.%d.%d.%d", e[0], e[1], e[2], e[3] );
- if( tr_pton( str, &addr ) == NULL )
+ if( !tr_address_from_string( &addr, str ) )
return false;
range->end = ntohl( addr.addr.addr4.s_addr );
return false;
tr_snprintf( str, sizeof(str), "%d.%d.%d.%d", a[0], a[1], a[2], a[3] );
- if( tr_pton( str, &addr ) == NULL )
+ if( !tr_address_from_string( &addr, str ) )
return false;
range->begin = ntohl( addr.addr.addr4.s_addr );
tr_snprintf( str, sizeof(str), "%d.%d.%d.%d", b[0], b[1], b[2], b[3] );
- if( tr_pton( str, &addr ) == NULL )
+ if( !tr_address_from_string( &addr, str ) )
return false;
range->end = ntohl( addr.addr.addr4.s_addr );
int _tr_blocklistIsEnabled ( tr_blocklist * b );
void _tr_blocklistSetEnabled ( tr_blocklist * b,
- int isEnabled );
+ bool isEnabled );
int _tr_blocklistHasAddress ( tr_blocklist * b,
const struct tr_address * addr );
if( fd >= 0 )
{
- if( ( gFd->socket_count < gFd->socket_limit ) && tr_ssToAddr( addr, port, &sock ) )
+ if( ( gFd->socket_count < gFd->socket_limit )
+ && tr_address_from_sockaddr_storage( addr, port, &sock ) )
{
++gFd->socket_count;
}
}
const char *
-tr_ntop( const tr_address * src, char * dst, int size )
+tr_address_to_string_with_buf( const tr_address * addr, char * buf, size_t buflen )
{
- assert( tr_isAddress( src ) );
+ assert( tr_address_is_valid( addr ) );
- if( src->type == TR_AF_INET )
- return evutil_inet_ntop( AF_INET, &src->addr, dst, size );
+ if( addr->type == TR_AF_INET )
+ return evutil_inet_ntop( AF_INET, &addr->addr, buf, buflen );
else
- return evutil_inet_ntop( AF_INET6, &src->addr, dst, size );
+ return evutil_inet_ntop( AF_INET6, &addr->addr, buf, buflen );
}
/*
- * Non-threadsafe version of tr_ntop, which uses a static memory area for a buffer.
+ * Non-threadsafe version of tr_address_to_string_with_buf()
+ * and 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 )
+tr_address_to_string( const tr_address * addr )
{
static char buf[INET6_ADDRSTRLEN];
- return tr_ntop( src, buf, sizeof( buf ) );
+ return tr_address_to_string_with_buf( addr, buf, sizeof( buf ) );
}
-tr_address *
-tr_pton( const char * src, tr_address * dst )
+bool
+tr_address_from_string( tr_address * dst, const char * src )
{
- int retval = evutil_inet_pton( AF_INET, src, &dst->addr );
- assert( dst );
- if( retval < 0 )
- return NULL;
- else if( retval == 0 )
- retval = evutil_inet_pton( AF_INET6, src, &dst->addr );
- else
- {
+ bool ok;
+
+ if(( ok = evutil_inet_pton( AF_INET, src, &dst->addr ) == 1 ))
dst->type = TR_AF_INET;
- return dst;
- }
- if( retval < 1 )
- return NULL;
- dst->type = TR_AF_INET6;
- return dst;
+ if( !ok ) /* try IPv6 */
+ if(( ok = evutil_inet_pton( AF_INET6, src, &dst->addr ) == 1 ))
+ dst->type = TR_AF_INET6;
+
+ return ok;
}
/*
* 0 if a == b
*/
int
-tr_compareAddresses( const tr_address * a, const tr_address * b)
+tr_address_compare( const tr_address * a, const tr_address * b)
{
static const int sizes[2] = { sizeof(struct in_addr), sizeof(struct in6_addr) };
}
bool
-tr_ssToAddr( tr_address * setme_addr,
- tr_port * setme_port,
- const struct sockaddr_storage * from )
+tr_address_from_sockaddr_storage( tr_address * setme_addr,
+ tr_port * setme_port,
+ const struct sockaddr_storage * from )
{
if( from->ss_family == AF_INET )
{
tr_port port,
struct sockaddr_storage * sockaddr)
{
- assert( tr_isAddress( addr ) );
+ assert( tr_address_is_valid( addr ) );
if( addr->type == TR_AF_INET )
{
socklen_t sourcelen;
struct sockaddr_storage source_sock;
- assert( tr_isAddress( addr ) );
+ assert( tr_address_is_valid( addr ) );
- if( !tr_isValidPeerAddress( addr, port ) )
+ if( !tr_address_is_valid_for_peers( addr, port ) )
return -EINVAL;
s = tr_fdSocketCreate( session, domains[addr->type], SOCK_STREAM );
if( bind( s, ( struct sockaddr * ) &source_sock, sourcelen ) )
{
tr_err( _( "Couldn't set source address %s on %d: %s" ),
- tr_ntop_non_ts( source_addr ), s, tr_strerror( errno ) );
+ tr_address_to_string( source_addr ), s, tr_strerror( errno ) );
return -errno;
}
if( ( tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH )
|| addr->type == TR_AF_INET )
tr_err( _( "Couldn't connect socket %d to %s, port %d (errno %d - %s)" ),
- s, tr_ntop_non_ts( addr ), (int)ntohs( port ), tmperrno,
+ s, tr_address_to_string( addr ), (int)ntohs( port ), tmperrno,
tr_strerror( tmperrno ) );
tr_netClose( session, s );
s = -tmperrno;
int addrlen;
int optval;
- assert( tr_isAddress( addr ) );
+ assert( tr_address_is_valid( addr ) );
fd = socket( domains[addr->type], SOCK_STREAM, 0 );
if( fd < 0 ) {
else
fmt = _( "Couldn't bind port %d on %s: %s (%s)" );
- tr_err( fmt, port, tr_ntop_non_ts( addr ), tr_strerror( err ), hint );
+ tr_err( fmt, port, tr_address_to_string( addr ), tr_strerror( err ), hint );
}
tr_netCloseSocket( fd );
*errOut = err;
}
if( !suppressMsgs )
- tr_dbg( "Bound socket %d to port %d on %s", fd, port, tr_ntop_non_ts( addr ) );
+ tr_dbg( "Bound socket %d to port %d on %s", fd, port, tr_address_to_string( addr ) );
if( listen( fd, 128 ) == -1 ) {
*errOut = sockerrno;
static const unsigned char zeroes[16] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- assert( tr_isAddress( a ) );
+ assert( tr_address_is_valid( a ) );
switch( a->type )
{
}
bool
-tr_isValidPeerAddress( const tr_address * addr, tr_port port )
+tr_address_is_valid_for_peers( const tr_address * addr, tr_port port )
{
return ( port != 0 )
- && ( tr_isAddress( addr ) )
+ && ( tr_address_is_valid( addr ) )
&& ( !isIPv6LinkLocalAddress( addr ) )
&& ( !isIPv4MappedAddress( addr ) )
&& ( !isMartianAddr( addr ) );
#define sockerrno errno
#endif
-struct tr_session;
+/****
+*****
+***** tr_address
+*****
+****/
typedef enum tr_address_type
{
extern const tr_address tr_inaddr_any;
extern const tr_address tr_in6addr_any;
-bool tr_ssToAddr( tr_address * setme_addr,
- tr_port * setme_port,
- const struct sockaddr_storage * from );
+const char* tr_address_to_string( const tr_address * addr );
-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);
+const char* tr_address_to_string_with_buf( const tr_address * addr,
+ char * buf,
+ size_t buflen );
-bool tr_isValidPeerAddress( const tr_address * addr, tr_port port );
+bool tr_address_from_string ( tr_address * setme,
+ const char * string );
-static inline bool tr_isAddress( const tr_address * a ) { return ( a != NULL ) && ( a->type==TR_AF_INET || a->type==TR_AF_INET6 ); }
+bool tr_address_from_sockaddr_storage( tr_address * setme,
+ tr_port * port,
+ const struct sockaddr_storage * src );
-bool tr_net_hasIPv6( tr_port );
+int tr_address_compare( const tr_address * a,
+ const tr_address * b );
+
+bool tr_address_is_valid_for_peers( const tr_address * addr,
+ tr_port port );
+
+static inline bool
+tr_address_is_valid( const tr_address * a )
+{
+ return ( a != NULL ) && ( a->type==TR_AF_INET || a->type==TR_AF_INET6 );
+}
/***********************************************************************
* Sockets
**********************************************************************/
+
+struct tr_session;
+
int tr_netOpenPeerSocket( tr_session * session,
const tr_address * addr,
tr_port port,
void tr_netInit( void );
+bool tr_net_hasIPv6( tr_port );
+
/**
* @brief get a human-representable string representing the network error.
struct UTPSocket * utp_socket )
{
assert( session );
- assert( tr_isAddress( addr ) );
+ assert( tr_address_is_valid( addr ) );
return tr_peerIoNew( session, parent, addr, port, NULL, true, false,
fd, utp_socket );
struct UTPSocket *utp_socket = NULL;
assert( session );
- assert( tr_isAddress( addr ) );
+ assert( tr_address_is_valid( addr ) );
assert( torrentHash );
if( utp )
tr_peerIoAddrStr( const tr_address * addr, tr_port port )
{
static char buf[512];
-
- 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 ) );
+ tr_snprintf( buf, sizeof( buf ), "[%s]:%u", tr_address_to_string( addr ), ntohs( port ) );
return buf;
}
&& ( io->magicNumber == PEER_IO_MAGIC_NUMBER )
&& ( io->refCount >= 0 )
&& ( tr_isBandwidth( &io->bandwidth ) )
- && ( tr_isAddress( &io->addr ) );
+ && ( tr_address_is_valid( &io->addr ) );
}
/**
return ( atom != NULL )
&& ( atom->fromFirst < TR_PEER_FROM__MAX )
&& ( atom->fromBest < TR_PEER_FROM__MAX )
- && ( tr_isAddress( &atom->addr ) );
+ && ( tr_address_is_valid( &atom->addr ) );
}
#endif
{
const tr_handshake * a = va;
- return tr_compareAddresses( tr_handshakeGetAddr( a, NULL ), vb );
+ return tr_address_compare( tr_handshakeGetAddr( a, NULL ), vb );
}
static int
{
const struct peer_atom * a = va;
- return tr_compareAddresses( &a->addr, vb );
+ return tr_address_compare( &a->addr, vb );
}
static int
static int
peerCompare( const void * a, const void * b )
{
- return tr_compareAddresses( tr_peerAddress( a ), tr_peerAddress( b ) );
+ return tr_address_compare( tr_peerAddress( a ), tr_peerAddress( b ) );
}
static struct peer_atom*
{
struct peer_atom * a;
- assert( tr_isAddress( addr ) );
+ assert( tr_address_is_valid( addr ) );
assert( from < TR_PEER_FROM__MAX );
a = getExistingAtom( t, addr );
if( tr_sessionIsAddressBlocked( session, addr ) )
{
- tr_dbg( "Banned IP address \"%s\" tried to connect to us", tr_ntop_non_ts( addr ) );
+ tr_dbg( "Banned IP address \"%s\" tried to connect to us", tr_address_to_string( addr ) );
if(socket >= 0)
tr_netClose( session, socket );
else
managerLock( t->manager );
if( !tr_sessionIsAddressBlocked( t->manager->session, &pex->addr ) )
- if( tr_isValidPeerAddress( &pex->addr, pex->port ) )
+ if( tr_address_is_valid_for_peers( &pex->addr, pex->port ) )
ensureAtomExists( t, &pex->addr, pex->port, pex->flags, seedProbability, from );
managerUnlock( t->manager );
assert( tr_isPex( a ) );
assert( tr_isPex( b ) );
- if(( i = tr_compareAddresses( &a->addr, &b->addr )))
+ if(( i = tr_address_compare( &a->addr, &b->addr )))
return i;
if( a->port != b->port )
const struct peer_atom * atom = atoms[i];
if( atom->addr.type == af )
{
- assert( tr_isAddress( &atom->addr ) );
+ assert( tr_address_is_valid( &atom->addr ) );
walk->addr = atom->addr;
walk->port = atom->port;
walk->flags = atom->flags;
const struct peer_atom * atom = peer->atom;
tr_peer_stat * stat = ret + i;
- tr_ntop( &atom->addr, stat->addr, sizeof( stat->addr ) );
+ tr_address_to_string_with_buf( &atom->addr, stat->addr, sizeof( stat->addr ) );
tr_strlcpy( stat->client, ( peer->client ? peer->client : "" ),
sizeof( stat->client ) );
stat->port = ntohs( peer->atom->port );
assert( tr_isAtom( a ) );
assert( tr_isAtom( b ) );
- return tr_compareAddresses( &a->addr, &b->addr );
+ return tr_address_compare( &a->addr, &b->addr );
}
/* best come first, worst go last */
static inline bool
tr_isPex( const tr_pex * pex )
{
- return pex && tr_isAddress( &pex->addr );
+ return pex && tr_address_is_valid( &pex->addr );
}
const tr_address * tr_peerAddress( const tr_peer * );
for( i = 0; i < SHA_DIGEST_LENGTH; ++i )
infohash[i] = 0xaa;
- tr_pton( "80.4.4.200", &addr );
+ tr_address_from_string( &addr, "80.4.4.200" );
numwant = 7;
numgot = tr_generateAllowedSet( buf, numwant, pieceCount, infohash, &addr );
addr.type = TR_AF_INET;
addr.addr.addr4 = server->bindAddress;
server->httpd = evhttp_new( server->session->event_base );
- evhttp_bind_socket( server->httpd, tr_ntop_non_ts( &addr ), server->port );
+ evhttp_bind_socket( server->httpd, tr_address_to_string( &addr ), server->port );
evhttp_set_gencb( server->httpd, handle_request, server );
}
tr_address addr;
addr.type = TR_AF_INET;
addr.addr.addr4 = server->bindAddress;
- return tr_ntop_non_ts( &addr );
+ return tr_address_to_string( &addr );
}
/****
found = tr_bencDictFindStr( settings, TR_PREFS_KEY_RPC_BIND_ADDRESS, &str );
assert( found );
- if( tr_pton( str, &address ) == NULL ) {
+ if( !tr_address_from_string( &address, str ) ) {
tr_err( _( "%s is not a valid address" ), str );
address = tr_inaddr_any;
} else if( address.type != TR_AF_INET ) {
}
if( is_default_value && bindinfo )
- *is_default_value = !tr_strcmp0( default_value, tr_ntop_non_ts( &bindinfo->addr ) );
+ *is_default_value = !tr_strcmp0( default_value, tr_address_to_string( &bindinfo->addr ) );
return bindinfo ? &bindinfo->addr : NULL;
}
tr_bencDictAddBool( d, TR_PREFS_KEY_USPEED_ENABLED, tr_sessionIsSpeedLimited( s, TR_UP ) );
tr_bencDictAddInt ( d, TR_PREFS_KEY_UMASK, s->umask );
tr_bencDictAddInt ( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, s->uploadSlotsPerTorrent );
- tr_bencDictAddStr ( d, TR_PREFS_KEY_BIND_ADDRESS_IPV4, tr_ntop_non_ts( &s->public_ipv4->addr ) );
- tr_bencDictAddStr ( d, TR_PREFS_KEY_BIND_ADDRESS_IPV6, tr_ntop_non_ts( &s->public_ipv6->addr ) );
+ tr_bencDictAddStr ( d, TR_PREFS_KEY_BIND_ADDRESS_IPV4, tr_address_to_string( &s->public_ipv4->addr ) );
+ tr_bencDictAddStr ( d, TR_PREFS_KEY_BIND_ADDRESS_IPV6, tr_address_to_string( &s->public_ipv6->addr ) );
tr_bencDictAddBool( d, TR_PREFS_KEY_START, !tr_sessionGetPaused( s ) );
tr_bencDictAddBool( d, TR_PREFS_KEY_TRASH_ORIGINAL, tr_sessionGetDeleteSource( s ) );
}
str = TR_PREFS_KEY_BIND_ADDRESS_IPV4;
tr_bencDictFindStr( settings, TR_PREFS_KEY_BIND_ADDRESS_IPV4, &str );
- if( !tr_pton( str, &b.addr ) || ( b.addr.type != TR_AF_INET ) )
+ if( !tr_address_from_string( &b.addr, str ) || ( b.addr.type != TR_AF_INET ) )
b.addr = tr_inaddr_any;
b.socket = -1;
session->public_ipv4 = tr_memdup( &b, sizeof( struct tr_bindinfo ) );
str = TR_PREFS_KEY_BIND_ADDRESS_IPV6;
tr_bencDictFindStr( settings, TR_PREFS_KEY_BIND_ADDRESS_IPV6, &str );
- if( !tr_pton( str, &b.addr ) || ( b.addr.type != TR_AF_INET6 ) )
+ if( !tr_address_from_string( &b.addr, str ) || ( b.addr.type != TR_AF_INET6 ) )
b.addr = tr_in6addr_any;
b.socket = -1;
session->public_ipv6 = tr_memdup( &b, sizeof( struct tr_bindinfo ) );
/* we found a suitable peer, add it to the torrent */
tr_peerMgrAddPex( tor, TR_PEER_FROM_LPD, peer, -1 );
tr_tordbg( tor, "Learned %d local peer from LPD (%s:%u)",
- 1, tr_ntop_non_ts( &peer->addr ), peerPort );
+ 1, tr_address_to_string( &peer->addr ), peerPort );
/* periodic reconnectPulse() deals with the rest... */
}
UTP_GetPeerName(s, from, &fromlen);
- if( !tr_ssToAddr( &addr, &port, &from_storage ) )
+ if( !tr_address_from_sockaddr_storage( &addr, &port, &from_storage ) )
{
tr_nerr("UTP", "Unknown socket family");
UTP_Close(s);
}
bool
-tr_addressIsIP( const char * address )
+tr_addressIsIP( const char * str )
{
- tr_address tempAddr;
- return tr_pton(address, &tempAddr) != NULL;
+ tr_address tmp;
+ return tr_address_from_string( &tmp, str );
}
int
curl_easy_setopt( e, CURLOPT_WRITEFUNCTION, writeFunc );
if((( addr = tr_sessionGetPublicAddress( s, TR_AF_INET, &is_default_value ))) && !is_default_value )
- curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) );
+ curl_easy_setopt( e, CURLOPT_INTERFACE, tr_address_to_string( addr ) );
else if ((( addr = tr_sessionGetPublicAddress( s, TR_AF_INET6, &is_default_value ))) && !is_default_value )
- curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) );
+ curl_easy_setopt( e, CURLOPT_INTERFACE, tr_address_to_string( addr ) );
if( task->cookies != NULL )
curl_easy_setopt( e, CURLOPT_COOKIE, task->cookies );