Changeset 7397
- Timestamp:
- Dec 15, 2008, 12:17:08 AM (12 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/fdlimit.c
r7232 r7397 451 451 452 452 int 453 tr_fdSocketCreate( int type )453 tr_fdSocketCreate( int domain, int type ) 454 454 { 455 455 int s = -1; … … 458 458 459 459 if( gFd->socketCount < getSocketMax( gFd ) ) 460 if( ( s = socket( AF_INET, type, 0 ) ) < 0 ) 460 if( ( s = socket( domain, type, 0 ) ) < 0 ) 461 { 461 462 tr_err( _( "Couldn't create socket: %s" ), 462 463 tr_strerror( sockerrno ) ); 464 s = -sockerrno; 465 } 463 466 464 467 if( s > -1 ) … … 486 489 if( gFd->socketCount < getSocketMax( gFd ) ) 487 490 { 488 len = sizeof( struct sockaddr );491 len = sizeof( struct sockaddr_storage ); 489 492 s = accept( b, (struct sockaddr *) &sock, &len ); 490 493 } … … 504 507 struct sockaddr_in6 * sock6 = (struct sockaddr_in6 *)&sock; 505 508 addr->type = TR_AF_INET6; 506 memcpy( &addr->addr, &sock6->sin6_addr, 507 sizeof( struct sockaddr_in6 ) ); 509 addr->addr.addr6 = sock6->sin6_addr; 508 510 *port = sock6->sin6_port; 509 511 } -
trunk/libtransmission/fdlimit.h
r7231 r7397 86 86 * Sockets 87 87 **********************************************************************/ 88 int tr_fdSocketCreate( int type );88 int tr_fdSocketCreate( int domain, int type ); 89 89 90 90 int tr_fdSocketAccept( int b, -
trunk/libtransmission/net.c
r7232 r7397 27 27 #include <stdlib.h> 28 28 #include <string.h> 29 #include <assert.h> 29 30 30 31 #include <sys/types.h> … … 108 109 dst->type = TR_AF_INET6; 109 110 return dst; 110 } 111 } 112 113 void 114 tr_normalizeV4Mapped( tr_address * const addr ) 115 { 116 if( addr->type == TR_AF_INET6 && IN6_IS_ADDR_V4MAPPED( &addr->addr.addr6 ) ) 117 { 118 addr->type = TR_AF_INET; 119 memcpy( &addr->addr.addr4.s_addr, addr->addr.addr6.s6_addr + 12, 4 ); 120 } 121 } 111 122 112 123 /* … … 141 152 142 153 /*********************************************************************** 154 * Socket list housekeeping 155 **********************************************************************/ 156 struct tr_socketList 157 { 158 int socket; 159 tr_address addr; 160 tr_socketList * next; 161 }; 162 163 tr_socketList * 164 tr_socketListAppend( tr_socketList * const head, 165 const tr_address * const addr ) 166 { 167 tr_socketList * tmp; 168 assert( head ); 169 for( tmp = head; tmp->next; tmp = tmp->next ); 170 tmp->next = tr_socketListNew( addr ); 171 return tmp->next; 172 } 173 174 tr_socketList * 175 tr_socketListNew( const tr_address * const addr ) 176 { 177 tr_socketList * tmp; 178 tmp = tr_new( tr_socketList, 1 ); 179 tmp->socket = -1; 180 tmp->addr = *addr; 181 tmp->next = NULL; 182 return tmp; 183 } 184 185 void 186 tr_socketListFree( tr_socketList * const head ) 187 { 188 assert( head ); 189 if( head->next ) 190 tr_socketListFree( head->next ); 191 tr_free( head ); 192 } 193 194 void 195 tr_socketListRemove( tr_socketList * const head, 196 tr_socketList * const el) 197 { 198 tr_socketList * tmp; 199 assert( head ); 200 assert( el ); 201 for( tmp = head; tmp->next && tmp->next != el; tmp = tmp->next ); 202 tmp->next = el->next; 203 el->next = NULL; 204 tr_socketListFree(el); 205 } 206 207 void 208 tr_socketListTruncate( tr_socketList * const head, 209 tr_socketList * const start ) 210 { 211 tr_socketList * tmp; 212 assert( head ); 213 assert( start ); 214 for( tmp = head; tmp->next && tmp->next != start; tmp = tmp->next ); 215 tr_socketListFree( start ); 216 tmp->next = NULL; 217 } 218 219 int 220 tr_socketListGetSocket( const tr_socketList * const el ) 221 { 222 assert( el ); 223 return el->socket; 224 } 225 226 const tr_address * 227 tr_socketListGetAddress( const tr_socketList * const el ) 228 { 229 assert( el ); 230 return &el->addr; 231 } 232 233 void 234 tr_socketListForEach( tr_socketList * const head, 235 void ( * cb ) ( int * const, 236 tr_address * const, 237 void * const), 238 void * const userData ) 239 { 240 tr_socketList * tmp; 241 for( tmp = head; tmp; tmp = tmp->next ) 242 cb( &tmp->socket, &tmp->addr, userData ); 243 } 244 245 /*********************************************************************** 143 246 * TCP sockets 144 247 **********************************************************************/ … … 162 265 if( evutil_make_socket_nonblocking( fd ) ) 163 266 { 267 int tmperrno; 164 268 tr_err( _( "Couldn't create socket: %s" ), 165 269 tr_strerror( sockerrno ) ); 270 tmperrno = sockerrno; 166 271 tr_netClose( fd ); 167 fd = - 1;272 fd = -tmperrno; 168 273 } 169 274 } … … 173 278 174 279 static int 175 createSocket( int type )176 { 177 return makeSocketNonBlocking( tr_fdSocketCreate( type ) );280 createSocket( int domain, int type ) 281 { 282 return makeSocketNonBlocking( tr_fdSocketCreate( domain, type ) ); 178 283 } 179 284 … … 192 297 } 193 298 194 static void 195 setup_sockaddr( const tr_address * addr, 196 tr_port port, 197 struct sockaddr_storage * sockaddr) 198 { 199 struct sockaddr_in sock4; 200 struct sockaddr_in6 sock6; 201 202 if( addr->type == TR_AF_INET ) 203 { 204 memset( &sock4, 0, sizeof( sock4 ) ); 205 sock4.sin_family = AF_INET; 206 sock4.sin_addr.s_addr = addr->addr.addr4.s_addr; 207 sock4.sin_port = port; 208 memcpy( sockaddr, &sock4, sizeof( sock4 ) ); 209 } 210 else 211 { 212 memset( &sock6, 0, sizeof( sock6 ) ); 213 sock6.sin6_family = AF_INET6; 214 sock6.sin6_port = port; 215 memcpy( &sock6.sin6_addr, &addr->addr, sizeof( struct in6_addr ) ); 216 memcpy( sockaddr, &sock6, sizeof( sock6 ) ); 217 } 218 } 219 220 int 221 tr_netOpenTCP( tr_session * session, 222 const tr_address * addr, 223 tr_port port ) 224 { 225 int s; 226 struct sockaddr_storage sock; 227 const int type = SOCK_STREAM; 228 229 if( ( s = createSocket( type ) ) < 0 ) 230 return -1; 299 static socklen_t 300 setup_sockaddr( const tr_address * addr, 301 tr_port port, 302 struct sockaddr_storage * sockaddr) 303 { 304 struct sockaddr_in sock4; 305 struct sockaddr_in6 sock6; 306 if( addr->type == TR_AF_INET ) 307 { 308 memset( &sock4, 0, sizeof( sock4 ) ); 309 sock4.sin_family = AF_INET; 310 sock4.sin_addr.s_addr = addr->addr.addr4.s_addr; 311 sock4.sin_port = port; 312 memcpy( sockaddr, &sock4, sizeof( sock4 ) ); 313 return sizeof( struct sockaddr_in ); 314 } 315 else 316 { 317 memset( &sock6, 0, sizeof( sock6 ) ); 318 sock6.sin6_family = AF_INET6; 319 sock6.sin6_port = port; 320 sock6.sin6_flowinfo = 0; 321 sock6.sin6_addr = addr->addr.addr6; 322 memcpy( sockaddr, &sock6, sizeof( sock6 ) ); 323 return sizeof( struct sockaddr_in6 ); 324 } 325 } 326 327 int 328 tr_netOpenTCP( tr_session * session, 329 const tr_address * addr, 330 tr_port port ) 331 { 332 int s; 333 struct sockaddr_storage sock; 334 const int type = SOCK_STREAM; 335 socklen_t addrlen; 336 337 if( ( s = createSocket( ( addr->type == TR_AF_INET ? AF_INET : AF_INET6 ), 338 type ) ) < 0 ) 339 return s; 231 340 232 341 setSndBuf( session, s ); 233 342 234 setup_sockaddr( addr, port, &sock );343 addrlen = setup_sockaddr( addr, port, &sock ); 235 344 236 345 if( ( connect( s, (struct sockaddr *) &sock, 237 sizeof( struct sockaddr )) < 0 )346 addrlen ) < 0 ) 238 347 #ifdef WIN32 239 348 && ( sockerrno != WSAEWOULDBLOCK ) … … 241 350 && ( sockerrno != EINPROGRESS ) ) 242 351 { 352 int tmperrno; 243 353 tr_err( _( "Couldn't connect socket %d to %s, port %d (errno %d - %s)" ), 244 354 s, tr_ntop_non_ts( addr ), (int)port, sockerrno, tr_strerror( sockerrno ) ); 355 tmperrno = sockerrno; 245 356 tr_netClose( s ); 246 s = - 1;357 s = -tmperrno; 247 358 } 248 359 … … 254 365 255 366 int 256 tr_netBindTCP( const tr_address * addr, tr_port port ) 257 { 258 int s; 259 struct sockaddr_storage sock; 260 const int type = SOCK_STREAM; 367 tr_netBindTCP( const tr_address * addr, tr_port port, tr_bool suppressMsgs ) 368 { 369 int s; 370 struct sockaddr_storage sock; 371 const int type = SOCK_STREAM; 372 int addrlen; 261 373 262 374 #if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT ) … … 264 376 #endif 265 377 266 if( ( s = createSocket( type ) ) < 0 ) 267 return -1; 378 if( ( s = createSocket( ( addr->type == TR_AF_INET ? AF_INET : AF_INET6 ), 379 type ) ) < 0 ) 380 return s; 268 381 269 382 #ifdef SO_REUSEADDR … … 272 385 #endif 273 386 274 setup_sockaddr( addr, htons( port ), &sock );387 addrlen = setup_sockaddr( addr, htons( port ), &sock ); 275 388 276 389 if( bind( s, (struct sockaddr *) &sock, 277 sizeof( struct sockaddr ) ) ) 278 { 279 tr_err( _( "Couldn't bind port %d on %s: %s" ), port, 280 tr_ntop_non_ts( addr ), tr_strerror( sockerrno ) ); 390 addrlen ) ) 391 { 392 int tmperrno; 393 if( !suppressMsgs ) 394 tr_err( _( "Couldn't bind port %d on %s: %s" ), port, 395 tr_ntop_non_ts( addr ), tr_strerror( sockerrno ) ); 396 tmperrno = sockerrno; 281 397 tr_netClose( s ); 282 return - 1;283 } 284 285 tr_dbg( "Bound socket %d to port %d on %s",286 s, port, tr_ntop_non_ts( addr ) );398 return -tmperrno; 399 } 400 if( !suppressMsgs ) 401 tr_dbg( "Bound socket %d to port %d on %s", 402 s, port, tr_ntop_non_ts( addr ) ); 287 403 return s; 288 404 } -
trunk/libtransmission/net.h
r7232 r7397 56 56 struct tr_session; 57 57 58 #define TR_AF_INET 0 59 #define TR_AF_INET6 1 60 61 typedef struct tr_address { 62 unsigned short type : 1; 63 union { 64 /* The order here is important for tr_in{,6}addr_any initialization, 65 * since we can't use C99 designated initializers */ 66 struct in6_addr addr6; 67 struct in_addr addr4; 68 } addr; 69 } tr_address; 70 71 extern const tr_address tr_inaddr_any; 72 extern const tr_address tr_in6addr_any; 73 74 const char *tr_ntop( const tr_address * src, 75 char * dst, 76 int size ); 77 const char *tr_ntop_non_ts( const tr_address * src ); 78 tr_address *tr_pton( const char * src, 79 tr_address * dst ); 80 int tr_compareAddresses( const tr_address * a, 81 const tr_address * b); 58 #define TR_AF_INET 0 59 #define TR_AF_INET6 1 60 61 typedef struct tr_address { 62 uint8_t type; 63 union { 64 /* The order here is important for tr_in{,6}addr_any initialization, 65 * since we can't use C99 designated initializers */ 66 struct in6_addr addr6; 67 struct in_addr addr4; 68 } addr; 69 } tr_address; 70 71 extern const tr_address tr_inaddr_any; 72 extern const tr_address tr_in6addr_any; 73 74 const char *tr_ntop( const tr_address * src, 75 char * dst, 76 int size ); 77 const char *tr_ntop_non_ts( const tr_address * src ); 78 tr_address *tr_pton( const char * src, 79 tr_address * dst ); 80 int tr_compareAddresses( const tr_address * a, 81 const tr_address * b); 82 void tr_normalizeV4Mapped( tr_address * const addr ); 83 84 /*********************************************************************** 85 * Socket list housekeeping 86 **********************************************************************/ 87 typedef struct tr_socketList tr_socketList; 88 tr_socketList *tr_socketListAppend( tr_socketList * const head, 89 const tr_address * const addr ); 90 tr_socketList *tr_socketListNew( const tr_address * const addr ); 91 void tr_socketListFree( tr_socketList * const head ); 92 void tr_socketListRemove( tr_socketList * const head, 93 tr_socketList * const el); 94 void tr_socketListTruncate( tr_socketList * const head, 95 tr_socketList * const start ); 96 int tr_socketListGetSocket( const tr_socketList * const el ); 97 const tr_address *tr_socketListGetAddress( const tr_socketList * const el ); 98 void tr_socketListForEach( tr_socketList * const head, 99 void ( * cb ) ( int * const, 100 tr_address * const, 101 void * const ), 102 void * const userData); 82 103 83 104 /*********************************************************************** … … 89 110 90 111 int tr_netBindTCP( const tr_address * addr, 91 tr_port port ); 112 tr_port port, 113 tr_bool suppressMsgs ); 92 114 93 115 int tr_netAccept( struct tr_handle * session, -
trunk/libtransmission/peer-mgr.c
r7361 r7397 1347 1347 if( !tr_sessionIsAddressBlocked( t->manager->session, &pex->addr ) ) 1348 1348 ensureAtomExists( t, &pex->addr, pex->port, pex->flags, from ); 1349 1349 1350 1350 managerUnlock( manager ); 1351 1351 } … … 1372 1372 } 1373 1373 1374 *pexCount = n; 1375 return pex; 1376 } 1377 1378 tr_pex * 1379 tr_peerMgrCompact6ToPex( const void * compact, 1380 size_t compactLen, 1381 const uint8_t * added_f, 1382 size_t added_f_len, 1383 size_t * pexCount ) 1384 { 1385 size_t i; 1386 size_t n = compactLen / 18; 1387 const uint8_t * walk = compact; 1388 tr_pex * pex = tr_new0( tr_pex, n ); 1389 1390 for( i = 0; i < n; ++i ) 1391 { 1392 pex[i].addr.type = TR_AF_INET6; 1393 memcpy( &pex[i].addr.addr.addr6.s6_addr, walk, 16 ); walk += 16; 1394 memcpy( &pex[i].port, walk, 2 ); walk += 2; 1395 if( added_f && ( n == added_f_len ) ) 1396 pex[i].flags = added_f[i]; 1397 } 1398 1399 *pexCount = n; 1400 return pex; 1401 } 1402 1403 tr_pex * 1404 tr_peerMgrArrayToPex( const void * array, 1405 size_t arrayLen, 1406 size_t * pexCount ) 1407 { 1408 size_t i; 1409 size_t n = arrayLen / ( sizeof( tr_address ) + 2 ); 1410 /*size_t n = arrayLen / sizeof( tr_peerArrayElement );*/ 1411 const uint8_t * walk = array; 1412 tr_pex * pex = tr_new0( tr_pex, n ); 1413 1414 for( i = 0 ; i < n ; i++ ) { 1415 memcpy( &pex[i].addr, walk, sizeof( tr_address ) ); 1416 memcpy( &pex[i].port, walk + sizeof( tr_address ), 2 ); 1417 pex[i].flags = 0x00; 1418 walk += sizeof( tr_address ) + 2; 1419 } 1420 1374 1421 *pexCount = n; 1375 1422 return pex; … … 1435 1482 1436 1483 int 1437 tr_peerMgrGetPeers( tr_peerMgr *manager,1484 tr_peerMgrGetPeers( tr_peerMgr * manager, 1438 1485 const uint8_t * torrentHash, 1439 tr_pex ** setme_pex ) 1486 tr_pex ** setme_pex, 1487 uint8_t af) 1440 1488 { 1441 1489 int peerCount = 0; 1490 int peersReturning = 0; 1442 1491 const Torrent * t; 1443 1492 … … 1453 1502 int i; 1454 1503 const tr_peer ** peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount ); 1504 /* for now, this will waste memory on torrents that have both 1505 * ipv6 and ipv4 peers */ 1455 1506 tr_pex * pex = tr_new( tr_pex, peerCount ); 1456 1507 tr_pex * walk = pex; … … 1459 1510 { 1460 1511 const tr_peer * peer = peers[i]; 1461 const struct peer_atom * atom = getExistingAtom( t, &peer->addr ); 1462 1463 walk->addr = peer->addr; 1464 walk->port = peer->port; 1465 walk->flags = 0; 1466 if( peerPrefersCrypto( peer ) ) 1467 walk->flags |= ADDED_F_ENCRYPTION_FLAG; 1468 if( ( atom->uploadOnly == UPLOAD_ONLY_YES ) || ( peer->progress >= 1.0 ) ) 1469 walk->flags |= ADDED_F_SEED_FLAG; 1512 if( peer->addr.type == af ) 1513 { 1514 const struct peer_atom * atom = getExistingAtom( t, &peer->addr ); 1515 memcpy( &walk->addr, &peer->addr, sizeof( walk->addr ) ); 1516 walk->port = peer->port; 1517 walk->flags = 0; 1518 if( peerPrefersCrypto( peer ) ) 1519 walk->flags |= ADDED_F_ENCRYPTION_FLAG; 1520 if( ( atom->uploadOnly == UPLOAD_ONLY_YES ) || 1521 ( peer->progress >= 1.0 ) ) 1522 walk->flags |= ADDED_F_SEED_FLAG; 1523 peersReturning++; 1524 } 1470 1525 } 1471 1526 1472 1527 assert( ( walk - pex ) == peerCount ); 1473 qsort( pex, peer Count, sizeof( tr_pex ), tr_pexCompare );1528 qsort( pex, peersReturning, sizeof( tr_pex ), tr_pexCompare ); 1474 1529 *setme_pex = pex; 1475 1530 } 1476 1531 1477 1532 managerUnlock( manager ); 1478 return peer Count;1533 return peersReturning; 1479 1534 } 1480 1535 … … 1786 1841 const struct peer_atom * atom = getExistingAtom( t, &peer->addr ); 1787 1842 tr_peer_stat * stat = ret + i; 1788 1789 tr_ntop( &peer->addr, stat->addr, sizeof(stat->addr) ); 1790 tr_strlcpy( stat->client, (peer->client ? peer->client : ""), sizeof(stat->client) ); 1843 tr_address norm_addr; 1844 1845 memcpy( &norm_addr, &peer->addr, sizeof( tr_address ) ); 1846 tr_normalizeV4Mapped( &norm_addr ); 1847 tr_ntop( &norm_addr, stat->addr, sizeof( stat->addr ) ); 1848 tr_strlcpy( stat->client, ( peer->client ? peer->client : "" ), 1849 sizeof( stat->client ) ); 1791 1850 stat->port = ntohs( peer->port ); 1792 1851 stat->from = atom->from; -
trunk/libtransmission/peer-mgr.h
r7385 r7397 68 68 size_t * setme_pex_count ); 69 69 70 tr_pex * tr_peerMgrCompact6ToPex( const void * compact, 71 size_t compactLen, 72 const uint8_t * added_f, 73 size_t added_f_len, 74 size_t * pexCount ); 75 76 tr_pex * tr_peerMgrArrayToPex( const void * array, 77 size_t arrayLen, 78 size_t * setme_pex_count ); 79 70 80 void tr_peerMgrAddPex( tr_peerMgr * manager, 71 81 const uint8_t * torrentHash, … … 80 90 int tr_peerMgrGetPeers( tr_peerMgr * manager, 81 91 const uint8_t * torrentHash, 82 tr_pex ** setme_pex ); 92 tr_pex ** setme_pex, 93 uint8_t af); 83 94 84 95 void tr_peerMgrStartTorrent( tr_peerMgr * manager, -
trunk/libtransmission/peer-msgs.c
r7361 r7397 283 283 uint8_t ut_pex_id; 284 284 uint16_t pexCount; 285 uint16_t pexCount6; 285 286 uint16_t minActiveRequests; 286 287 uint16_t maxActiveRequests; … … 309 310 tr_timer * pexTimer; 310 311 tr_pex * pex; 312 tr_pex * pex6; 311 313 312 314 time_t clientSentPexAt; … … 1182 1184 1183 1185 if( tr_torrentAllowsPex( tor ) 1184 && (( loaded = !tr_bencLoad( tmp, msglen, &val, NULL ))) 1185 && tr_bencDictFindRaw( &val, "added", &added, &added_len )) 1186 { 1187 const uint8_t * added_f = NULL; 1188 tr_pex * pex; 1189 size_t i, n; 1190 size_t added_f_len = 0; 1191 tr_bencDictFindRaw( &val, "added.f", &added_f, &added_f_len ); 1192 pex = tr_peerMgrCompactToPex( added, added_len, added_f, added_f_len, &n ); 1193 for( i=0; i<n; ++i ) 1194 tr_peerMgrAddPex( msgs->session->peerMgr, tor->info.hash, 1195 TR_PEER_FROM_PEX, pex + i ); 1196 tr_free( pex ); 1186 && ( ( loaded = !tr_bencLoad( tmp, msglen, &val, NULL ) ) ) ) 1187 { 1188 if( tr_bencDictFindRaw( &val, "added", &added, &added_len ) ) 1189 { 1190 const uint8_t * added_f = NULL; 1191 tr_pex * pex; 1192 size_t i, n; 1193 size_t added_f_len = 0; 1194 tr_bencDictFindRaw( &val, "added.f", &added_f, &added_f_len ); 1195 pex = 1196 tr_peerMgrCompactToPex( added, added_len, added_f, added_f_len, 1197 &n ); 1198 for( i = 0; i < n; ++i ) 1199 tr_peerMgrAddPex( msgs->session->peerMgr, tor->info.hash, 1200 TR_PEER_FROM_PEX, pex + i ); 1201 tr_free( pex ); 1202 } 1203 1204 if( tr_bencDictFindRaw( &val, "added6", &added, &added_len ) ) 1205 { 1206 const uint8_t * added_f = NULL; 1207 tr_pex * pex; 1208 size_t i, n; 1209 size_t added_f_len = 0; 1210 tr_bencDictFindRaw( &val, "added6.f", &added_f, &added_f_len ); 1211 pex = 1212 tr_peerMgrCompact6ToPex( added, added_len, added_f, added_f_len, 1213 &n ); 1214 for( i = 0; i < n; ++i ) 1215 tr_peerMgrAddPex( msgs->session->peerMgr, tor->info.hash, 1216 TR_PEER_FROM_PEX, pex + i ); 1217 tr_free( pex ); 1218 } 1219 1197 1220 } 1198 1221 … … 2006 2029 } 2007 2030 2008 /* TODO: ipv6 pex */2009 2031 static void 2010 2032 sendPex( tr_peermsgs * msgs ) … … 2013 2035 { 2014 2036 PexDiffs diffs; 2037 PexDiffs diffs6; 2015 2038 tr_pex * newPex = NULL; 2039 tr_pex * newPex6 = NULL; 2016 2040 const int newCount = tr_peerMgrGetPeers( msgs->session->peerMgr, 2017 2041 msgs->torrent->info.hash, 2018 &newPex ); 2042 &newPex, TR_AF_INET ); 2043 const int newCount6 = tr_peerMgrGetPeers( msgs->session->peerMgr, 2044 msgs->torrent->info.hash, 2045 &newPex6, TR_AF_INET6 ); 2019 2046 2020 2047 /* build the diffs */ … … 2029 2056 tr_pexCompare, sizeof( tr_pex ), 2030 2057 pexDroppedCb, pexAddedCb, pexElementCb, &diffs ); 2058 diffs6.added = tr_new( tr_pex, newCount6 ); 2059 diffs6.addedCount = 0; 2060 diffs6.dropped = tr_new( tr_pex, msgs->pexCount6 ); 2061 diffs6.droppedCount = 0; 2062 diffs6.elements = tr_new( tr_pex, newCount6 + msgs->pexCount6 ); 2063 diffs6.elementCount = 0; 2064 tr_set_compare( msgs->pex6, msgs->pexCount6, 2065 newPex6, newCount6, 2066 tr_pexCompare, sizeof( tr_pex ), 2067 pexDroppedCb, pexAddedCb, pexElementCb, &diffs6 ); 2031 2068 dbgmsg( 2032 2069 msgs, 2033 2070 "pex: old peer count %d, new peer count %d, added %d, removed %d", 2034 msgs->pexCount, newCount, diffs.addedCount, diffs.droppedCount ); 2035 2036 if( !diffs.addedCount && !diffs.droppedCount ) 2071 msgs->pexCount, newCount + newCount6, 2072 diffs.addedCount + diffs6.addedCount, 2073 diffs.droppedCount + diffs6.droppedCount ); 2074 2075 if( !diffs.addedCount && !diffs.droppedCount && !diffs6.addedCount && 2076 !diffs6.droppedCount ) 2037 2077 { 2038 2078 tr_free( diffs.elements ); 2079 tr_free( diffs6.elements ); 2039 2080 } 2040 2081 else … … 2051 2092 msgs->pex = diffs.elements; 2052 2093 msgs->pexCount = diffs.elementCount; 2094 tr_free( msgs->pex6 ); 2095 msgs->pex6 = diffs6.elements; 2096 msgs->pexCount6 = diffs6.elementCount; 2053 2097 2054 2098 /* build the pex payload */ 2055 tr_bencInitDict( &val, 3 ); 2099 tr_bencInitDict( &val, 3 ); /* ipv6 support: left as 3: 2100 * speed vs. likelihood? */ 2056 2101 2057 2102 /* "added" */ 2058 2103 tmp = walk = tr_new( uint8_t, diffs.addedCount * 6 ); 2059 for( i = 0; i < diffs.addedCount; ++i ) { 2104 for( i = 0; i < diffs.addedCount; ++i ) 2105 { 2060 2106 memcpy( walk, &diffs.added[i].addr.addr, 4 ); walk += 4; 2061 2107 memcpy( walk, &diffs.added[i].port, 2 ); walk += 2; … … 2075 2121 /* "dropped" */ 2076 2122 tmp = walk = tr_new( uint8_t, diffs.droppedCount * 6 ); 2077 for( i = 0; i < diffs.droppedCount; ++i ) { 2123 for( i = 0; i < diffs.droppedCount; ++i ) 2124 { 2078 2125 memcpy( walk, &diffs.dropped[i].addr.addr, 4 ); walk += 4; 2079 2126 memcpy( walk, &diffs.dropped[i].port, 2 ); walk += 2; … … 2081 2128 assert( ( walk - tmp ) == diffs.droppedCount * 6 ); 2082 2129 tr_bencDictAddRaw( &val, "dropped", tmp, walk - tmp ); 2130 tr_free( tmp ); 2131 2132 /* "added6" */ 2133 tmp = walk = tr_new( uint8_t, diffs6.addedCount * 18 ); 2134 for( i = 0; i < diffs6.addedCount; ++i ) 2135 { 2136 memcpy( walk, &diffs6.added[i].addr.addr.addr6.s6_addr, 16 ); 2137 walk += 16; 2138 memcpy( walk, &diffs6.added[i].port, 2 ); 2139 walk += 2; 2140 } 2141 assert( ( walk - tmp ) == diffs6.addedCount * 18 ); 2142 tr_bencDictAddRaw( &val, "added6", tmp, walk - tmp ); 2143 tr_free( tmp ); 2144 2145 /* "added6.f" */ 2146 tmp = walk = tr_new( uint8_t, diffs6.addedCount ); 2147 for( i = 0; i < diffs6.addedCount; ++i ) 2148 *walk++ = diffs6.added[i].flags; 2149 assert( ( walk - tmp ) == diffs6.addedCount ); 2150 tr_bencDictAddRaw( &val, "added6.f", tmp, walk - tmp ); 2151 tr_free( tmp ); 2152 2153 /* "dropped6" */ 2154 tmp = walk = tr_new( uint8_t, diffs6.droppedCount * 18 ); 2155 for( i = 0; i < diffs6.droppedCount; ++i ) 2156 { 2157 memcpy( walk, &diffs6.dropped[i].addr.addr.addr6.s6_addr, 16 ); 2158 walk += 16; 2159 memcpy( walk, &diffs6.dropped[i].port, 2 ); 2160 walk += 2; 2161 } 2162 assert( ( walk - tmp ) == diffs6.droppedCount * 18); 2163 tr_bencDictAddRaw( &val, "dropped6", tmp, walk - tmp ); 2083 2164 tr_free( tmp ); 2084 2165 … … 2100 2181 tr_free( diffs.dropped ); 2101 2182 tr_free( newPex ); 2183 tr_free( diffs6.added ); 2184 tr_free( diffs6.dropped ); 2185 tr_free( newPex6 ); 2102 2186 2103 2187 msgs->clientSentPexAt = time( NULL ); … … 2176 2260 evbuffer_free( msgs->incoming.block ); 2177 2261 evbuffer_free( msgs->outMessages ); 2262 tr_free( msgs->pex6 ); 2178 2263 tr_free( msgs->pex ); 2179 2264 -
trunk/libtransmission/port-forwarding.c
r7392 r7397 39 39 tr_port_forwarding upnpStatus; 40 40 41 int bindPort;42 int bindSocket;43 intpublicPort;41 tr_bool shouldChange; 42 tr_socketList * bindSockets; 43 tr_port publicPort; 44 44 45 45 tr_timer * pulseTimer; … … 85 85 natPulse( tr_shared * s ) 86 86 { 87 const int port = s->publicPort;88 const int isEnabled = s->isEnabled && !s->isShuttingDown;89 int oldStatus;90 int newStatus;87 const tr_port port = s->publicPort; 88 const int isEnabled = s->isEnabled && !s->isShuttingDown; 89 int oldStatus; 90 int newStatus; 91 91 92 92 oldStatus = tr_sharedTraversalStatus( s ); … … 101 101 } 102 102 103 static void 104 incomingPeersPulse( tr_shared * s ) 105 { 106 tr_bool allPaused; 107 tr_torrent * tor; 108 109 if( s->bindSocket >= 0 && ( s->bindPort != s->publicPort ) ) 110 { 111 tr_ninf( getKey( ), _( "Closing port %d" ), s->bindPort ); 112 tr_netClose( s->bindSocket ); 113 s->bindSocket = -1; 114 } 115 116 if( ( s->publicPort > 0 ) && ( s->bindPort != s->publicPort ) ) 117 { 118 int socket; 119 errno = 0; 120 socket = tr_netBindTCP( &tr_inaddr_any, s->publicPort ); 121 if( socket >= 0 ) 122 { 123 tr_ninf( getKey( ), 124 _( 125 "Opened port %d to listen for incoming peer connections" ), 126 s->publicPort ); 127 s->bindPort = s->publicPort; 128 s->bindSocket = socket; 129 listen( s->bindSocket, 5 ); 130 } 131 else 132 { 133 tr_nerr( getKey( ), 134 _( 135 "Couldn't open port %d to listen for incoming peer connections (errno %d - %s)" ), 136 s->publicPort, errno, tr_strerror( errno ) ); 137 s->bindPort = -1; 138 s->bindSocket = -1; 139 } 140 } 141 142 /* see if any torrents aren't paused */ 143 allPaused = 1; 144 tor = NULL; 145 while(( tor = tr_torrentNext( s->session, tor ))) { 146 if( TR_STATUS_IS_ACTIVE( tr_torrentGetActivity( tor ))) { 147 allPaused = 0; 148 break; 149 } 150 } 151 152 /* if we have any running torrents, check for new incoming peer connections */ 153 while( !allPaused ) 154 { 155 int socket; 156 tr_port port; 157 tr_address addr; 158 159 if( s->bindSocket < 0 ) 160 break; 161 162 socket = tr_netAccept( s->session, s->bindSocket, &addr, &port ); 163 if( socket < 0 ) 164 break; 165 103 /* 104 * Callbacks for socket list 105 */ 106 static void 107 closeCb( int * const socket, 108 tr_address * const addr, 109 void * const userData ) 110 { 111 tr_shared * s = ( tr_shared * )userData; 112 if( *socket >= 0 ) 113 { 114 tr_ninf( getKey( ), _( "Closing port %d on %s" ), s->publicPort, 115 tr_ntop_non_ts( addr ) ); 116 tr_netClose( *socket ); 117 } 118 } 119 120 static void 121 acceptCb( int * const socket, 122 tr_address * const addr, 123 void * const userData ) 124 { 125 tr_shared * s = ( tr_shared * )userData; 126 tr_address clientAddr; 127 tr_port clientPort; 128 int clientSocket; 129 clientSocket = tr_netAccept( s->session, *socket, &clientAddr, &clientPort ); 130 if( clientSocket > 0 ) 131 { 166 132 tr_deepLog( __FILE__, __LINE__, NULL, 167 133 "New INCOMING connection %d (%s)", 168 socket, tr_peerIoAddrStr( &addr, port ) ); 169 170 tr_peerMgrAddIncoming( s->session->peerMgr, &addr, port, socket ); 171 } 134 clientSocket, tr_peerIoAddrStr( &clientAddr, clientPort ) ); 135 136 tr_peerMgrAddIncoming( s->session->peerMgr, &clientAddr, clientPort, 137 clientSocket ); 138 } 139 } 140 141 static void 142 bindCb( int * const socket, 143 tr_address * const addr, 144 void * const userData ) 145 { 146 tr_shared * s = ( tr_shared * )userData; 147 *socket = tr_netBindTCP( addr, s->publicPort, FALSE ); 148 if( *socket >= 0 ) 149 { 150 tr_ninf( getKey( ), 151 _( "Opened port %d on %s to listen for incoming peer connections" ), 152 s->publicPort, tr_ntop_non_ts( addr ) ); 153 listen( *socket, 10 ); 154 } 155 else 156 { 157 tr_nerr( getKey( ), 158 _( 159 "Couldn't open port %d on %s to listen for incoming peer connections (errno %d - %s)" ), 160 s->publicPort, tr_ntop_non_ts( addr ), errno, tr_strerror( errno ) ); 161 } 162 } 163 164 static void 165 incomingPeersPulse( tr_shared * s ) 166 { 167 int allPaused; 168 tr_torrent * tor; 169 170 if( s->shouldChange ) 171 { 172 tr_socketListForEach( s->bindSockets, &closeCb, s ); 173 s->shouldChange = FALSE; 174 if( s->publicPort > 0 ) 175 tr_socketListForEach( s->bindSockets, &bindCb, s ); 176 } 177 178 /* see if any torrents aren't paused */ 179 allPaused = 1; 180 tor = NULL; 181 while( ( tor = tr_torrentNext( s->session, tor ) ) ) 182 { 183 if( TR_STATUS_IS_ACTIVE( tr_torrentGetActivity( tor ) ) ) 184 { 185 allPaused = 0; 186 break; 187 } 188 } 189 190 /* if we have any running torrents, check for new incoming peer connections */ 191 /* (jhujhiti): 192 * This has been changed from a loop that will end when the listener queue 193 * is exhausted to one that will only check for one connection at a time. 194 * I think it unlikely that we get many more than one connection in the 195 * time between pulses (currently one second). However, just to be safe, 196 * I have increased the length of the listener queue from 5 to 10 197 * (see acceptCb() above). */ 198 if( !allPaused ) 199 tr_socketListForEach( s->bindSockets, &acceptCb, s ); 172 200 } 173 201 … … 188 216 tr_ninf( getKey( ), _( "Stopped" ) ); 189 217 tr_timerFree( &shared->pulseTimer ); 190 tr_ netClose( shared->bindSocket);218 tr_socketListForEach( shared->bindSockets, &closeCb, shared ); 191 219 tr_natpmpClose( shared->natpmp ); 192 220 tr_upnpClose( shared->upnp ); … … 203 231 ***/ 204 232 233 static tr_socketList * 234 setupBindSockets( tr_port port ) 235 { 236 /* Do we care if an address is in use? Probably not, since it will be 237 * caught later. This will only set up the list of sockets to bind. */ 238 int s4, s6; 239 tr_socketList * socks = NULL; 240 s6 = tr_netBindTCP( &tr_in6addr_any, port, TRUE ); 241 if( s6 >= 0 || -s6 != EAFNOSUPPORT ) /* we support ipv6 */ 242 { 243 socks = tr_socketListNew( &tr_in6addr_any ); 244 listen( s6, 1 ); 245 } 246 s4 = tr_netBindTCP( &tr_inaddr_any, port, TRUE ); 247 if( s4 >= 0 ) /* we bound *with* the ipv6 socket bound (need both) 248 * or only have ipv4 */ 249 { 250 if( socks ) 251 tr_socketListAppend( socks, &tr_inaddr_any ); 252 else 253 socks = tr_socketListNew( &tr_inaddr_any ); 254 tr_netClose( s4 ); 255 } 256 if( s6 >= 0 ) 257 tr_netClose( s6 ); 258 return socks; 259 } 260 205 261 tr_shared * 206 262 tr_sharedInit( tr_session * session, … … 212 268 s->session = session; 213 269 s->publicPort = publicPort; 214 s->bindPort = -1; 215 s->bindSocket = -1; 270 s->shouldChange = TRUE; 271 s->bindSockets = setupBindSockets( publicPort ); 272 s->shouldChange = TRUE; 216 273 s->natpmp = tr_natpmpInit( ); 217 274 s->upnp = tr_upnpInit( ); … … 235 292 tr_torrent * tor = NULL; 236 293 237 s->publicPort = port; 294 s->publicPort = port; 295 s->shouldChange = TRUE; 238 296 239 297 while( ( tor = tr_torrentNext( s->session, tor ) ) ) -
trunk/libtransmission/resume.c
r7249 r7397 35 35 #define KEY_PAUSED "paused" 36 36 #define KEY_PEERS "peers" 37 #define KEY_PEERS6 "peers6" 37 38 #define KEY_PRIORITY "priority" 38 39 #define KEY_PROGRESS "progress" … … 62 63 ***/ 63 64 64 /* TODO: resume peers6 */65 65 static void 66 66 savePeers( tr_benc * dict, 67 67 const tr_torrent * tor ) 68 68 { 69 tr_pex * 70 constint count = tr_peerMgrGetPeers( tor->session->peerMgr,71 tor->info.hash, &pex);69 tr_pex * pex = NULL; 70 int count = tr_peerMgrGetPeers( tor->session->peerMgr, 71 tor->info.hash, &pex, TR_AF_INET ); 72 72 73 73 if( count > 0 ) 74 74 tr_bencDictAddRaw( dict, KEY_PEERS, pex, sizeof( tr_pex ) * count ); 75 76 count = tr_peerMgrGetPeers( tor->session->peerMgr, tor->info.hash, &pex, 77 TR_AF_INET6 ); 78 if( count > 0 ) 79 tr_bencDictAddRaw( dict, KEY_PEERS6, pex, sizeof( tr_pex ) * count ); 80 75 81 tr_free( pex ); 76 82 } … … 95 101 tor->info.hash, TR_PEER_FROM_CACHE, &pex ); 96 102 } 97 tr_tordbg( tor, "Loaded %d peers from resume file", count ); 103 tr_tordbg( tor, "Loaded %d IPv4 peers from resume file", count ); 104 ret = TR_FR_PEERS; 105 } 106 107 if( tr_bencDictFindRaw( dict, KEY_PEERS6, &str, &len ) ) 108 { 109 int i; 110 const int count = len / sizeof( tr_pex ); 111 for( i = 0; i < count; ++i ) 112 { 113 tr_pex pex; 114 memcpy( &pex, str + ( i * sizeof( tr_pex ) ), sizeof( tr_pex ) ); 115 tr_peerMgrAddPex( tor->session->peerMgr, 116 tor->info.hash, TR_PEER_FROM_CACHE, &pex ); 117 } 118 tr_tordbg( tor, "Loaded %d IPv6 peers from resume file", count ); 98 119 ret = TR_FR_PEERS; 99 120 } -
trunk/libtransmission/torrent.c
r7385 r7397 223 223 { 224 224 size_t i, n; 225 tr_pex * pex = tr_peerMgrCompactToPex( event->compact, 226 event->compactLen, 227 NULL, 0, &n ); 228 if( event->allAreSeeds ) 225 tr_pex * pex = tr_peerMgrArrayToPex( event->compact, 226 event->compactLen, &n ); 227 if( event->allAreSeeds ) 229 228 tr_tordbg( tor, "Got %d seeds from tracker", (int)n ); 230 229 else -
trunk/libtransmission/tracker.c
r7266 r7397 241 241 } 242 242 243 static void 244 publishNewPeersCompact( tr_tracker * t, 245 int allAreSeeds, 246 void * compact, 247 int compactLen ) 248 { 249 int i; 250 uint8_t *array, *walk, *compactWalk; 251 const int peerCount = compactLen / 6; 252 const int arrayLen = peerCount * ( sizeof( tr_address ) + 2 ); 253 tr_address addr; 254 tr_port port; 255 256 addr.type = TR_AF_INET; 257 memset( &addr.addr, 0x00, sizeof( addr.addr ) ); 258 array = tr_new( uint8_t, arrayLen ); 259 for ( i = 0, walk = array, compactWalk = compact ; i < peerCount ; i++ ) 260 { 261 memcpy( &addr.addr.addr4, compactWalk, 4 ); 262 memcpy( &port, compactWalk + 4, 2 ); 263 264 memcpy( walk, &addr, sizeof( addr ) ); 265 memcpy( walk + sizeof( addr ), &port, 2 ); 266 267 walk += sizeof( tr_address ) + 2; 268 compactWalk += 6; 269 } 270 publishNewPeers( t, allAreSeeds, array, arrayLen ); 271 tr_free( array ); 272 } 273 274 static void 275 publishNewPeersCompact6( tr_tracker * t, 276 int allAreSeeds, 277 void * compact, 278 int compactLen ) 279 { 280 int i; 281 uint8_t *array, *walk, *compactWalk; 282 const int peerCount = compactLen / 18; 283 const int arrayLen = peerCount * ( sizeof( tr_address ) + 2 ); 284 tr_address addr; 285 tr_port port; 286 287 addr.type = TR_AF_INET6; 288 memset( &addr.addr, 0x00, sizeof( addr.addr ) ); 289 array = tr_new( uint8_t, arrayLen ); 290 for ( i = 0, walk = array, compactWalk = compact ; i < peerCount ; i++ ) 291 { 292 memcpy( &addr.addr.addr6, compactWalk, 16 ); 293 memcpy( &port, compactWalk + 16, 2 ); 294 295 memcpy( walk, &addr, sizeof( addr ) ); 296 memcpy( walk + sizeof( addr ), &port, 2 ); 297 298 walk += sizeof( tr_address ) + 2; 299 compactWalk += 6; 300 } 301 publishNewPeers( t, allAreSeeds, array, arrayLen ); 302 tr_free( array ); 303 } 304 243 305 /*** 244 306 **** … … 277 339 } 278 340 279 /* Convert to compact form */280 341 static uint8_t * 281 342 parseOldPeers( tr_benc * bePeers, 282 343 size_t * byteCount ) 283 344 { 284 /* TODO: IPv6 wtf */285 345 int i; 286 uint8_t * compact, *walk;346 uint8_t * array, *walk; 287 347 const int peerCount = bePeers->val.l.count; 288 348 289 349 assert( bePeers->type == TYPE_LIST ); 290 350 291 compact = tr_new( uint8_t, peerCount * 6 ); 292 293 for( i = 0, walk = compact; i < peerCount; ++i ) 294 { 295 const char * s; 296 int64_t itmp; 297 tr_address addr; 298 tr_port port; 299 tr_benc * peer = &bePeers->val.l.vals[i]; 300 301 if( tr_bencDictFindStr( peer, "ip", &s ) ) 302 { 303 if( tr_pton( s, &addr ) == NULL ) 304 continue; 305 if( addr.type != TR_AF_INET ) 306 continue; 307 } 308 309 memcpy( walk, &addr.addr.addr4.s_addr, 4 ); 310 walk += 4; 311 351 array = tr_new( uint8_t, peerCount * ( sizeof( tr_address ) + 2 ) ); 352 353 for( i = 0, walk = array; i < peerCount; ++i ) 354 { 355 const char * s; 356 int64_t itmp; 357 tr_address addr; 358 tr_port port; 359 tr_benc * peer = &bePeers->val.l.vals[i]; 360 361 if( tr_bencDictFindStr( peer, "ip", &s ) ) 362 { 363 if( tr_pton( s, &addr ) == NULL ) 364 continue; 365 } 312 366 if( !tr_bencDictFindInt( peer, "port", 313 367 &itmp ) || itmp < 0 || itmp > 0xffff ) 314 368 continue; 315 369 370 memcpy( walk, &addr, sizeof( tr_address ) ); 316 371 port = htons( itmp ); 317 memcpy( walk , &port, 2 );318 walk += 2;319 } 320 321 *byteCount = peerCount * 6;322 return compact;372 memcpy( walk + sizeof( tr_address ), &port, 2 ); 373 walk += sizeof( tr_address ) + 2; 374 } 375 376 *byteCount = peerCount * sizeof( tr_address ) + 2; 377 return array; 323 378 } 324 379 … … 433 488 if( tmp->type == TYPE_STR ) /* "compact" extension */ 434 489 { 435 publishNewPeers ( t, allAreSeeds, tmp->val.s.s,436 tmp->val.s.i );490 publishNewPeersCompact( t, allAreSeeds, tmp->val.s.s, 491 tmp->val.s.i ); 437 492 } 438 493 else if( tmp->type == TYPE_LIST ) /* original protocol */ 439 494 { 440 495 size_t byteCount = 0; 441 uint8_t * compact = parseOldPeers( tmp, &byteCount ); 442 publishNewPeers( t, allAreSeeds, compact, byteCount ); 443 tr_free( compact ); 496 uint8_t * array = parseOldPeers( tmp, &byteCount ); 497 publishNewPeers( t, allAreSeeds, array, byteCount ); 498 tr_free( array ); 499 } 500 } 501 502 if( ( tmp = tr_bencDictFind( &benc, "peers6" ) ) ) 503 { 504 const int allAreSeeds = incomplete == 0; 505 506 if( tmp->type == TYPE_STR ) /* "compact" extension */ 507 { 508 publishNewPeersCompact6( t, allAreSeeds, tmp->val.s.s, 509 tmp->val.s.i ); 444 510 } 445 511 }
Note: See TracChangeset
for help on using the changeset viewer.