void tr_dhtUninit (tr_session *ss) { if (session != ss) return; tr_logAddNamedDbg ("DHT", "Uninitializing DHT"); if (dht_timer != NULL) { event_free (dht_timer); dht_timer = NULL; } /* Since we only save known good nodes, avoid erasing older data if we don't know enough nodes. */ if ((tr_dhtStatus (ss, AF_INET, NULL) < TR_DHT_FIREWALLED) && (tr_dhtStatus (ss, AF_INET6, NULL) < TR_DHT_FIREWALLED)) { tr_logAddNamedInfo ("DHT", "Not saving nodes, DHT not ready"); } else { tr_variant benc; struct sockaddr_in sins[300]; struct sockaddr_in6 sins6[300]; char compact[300 * 6], compact6[300 * 18]; char *dat_file; int i, j, num = 300, num6 = 300; int n = dht_get_nodes (sins, &num, sins6, &num6); tr_logAddNamedInfo ("DHT", "Saving %d (%d + %d) nodes", n, num, num6); j = 0; for (i=0; i<num; ++i) { memcpy (compact + j, &sins[i].sin_addr, 4); memcpy (compact + j + 4, &sins[i].sin_port, 2); j += 6; } j = 0; for (i=0; i<num6; ++i) { memcpy (compact6 + j, &sins6[i].sin6_addr, 16); memcpy (compact6 + j + 16, &sins6[i].sin6_port, 2); j += 18; } tr_variantInitDict (&benc, 3); tr_variantDictAddRaw (&benc, TR_KEY_id, myid, 20); if (num > 0) tr_variantDictAddRaw (&benc, TR_KEY_nodes, compact, num * 6); if (num6 > 0) tr_variantDictAddRaw (&benc, TR_KEY_nodes6, compact6, num6 * 18); dat_file = tr_buildPath (ss->configDir, "dht.dat", NULL); tr_variantToFile (&benc, TR_VARIANT_FMT_BENC, dat_file); tr_variantFree (&benc); tr_free (dat_file); } dht_uninit (); tr_logAddNamedDbg ("DHT", "Done uninitializing DHT"); session = NULL; }
static int bootstrap_done( tr_session *session, int af ) { int status; if(af == 0) return bootstrap_done(session, AF_INET) && bootstrap_done(session, AF_INET6); status = tr_dhtStatus(session, af, NULL); return status == TR_DHT_STOPPED || status >= TR_DHT_FIREWALLED; }
int tr_dhtAddNode( tr_session * ss, const tr_address * address, tr_port port, tr_bool bootstrap ) { int af = address->type == TR_AF_INET ? AF_INET : AF_INET6; if( !tr_dhtEnabled( ss ) ) return 0; /* Since we don't want to abuse our bootstrap nodes, * we don't ping them if the DHT is in a good state. */ if(bootstrap) { if(tr_dhtStatus(ss, af, NULL) >= TR_DHT_FIREWALLED) return 0; } if( address->type == TR_AF_INET ) { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; memcpy(&sin.sin_addr, &address->addr.addr4, 4); sin.sin_port = htons(port); dht_ping_node((struct sockaddr*)&sin, sizeof(sin)); return 1; } else if( address->type == TR_AF_INET6 ) { struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; memcpy(&sin6.sin6_addr, &address->addr.addr6, 16); sin6.sin6_port = htons(port); dht_ping_node((struct sockaddr*)&sin6, sizeof(sin6)); return 1; } return 0; }
void tr_dhtUninit(tr_session *ss) { if(session != ss) return; tr_ndbg( "DHT", "Uninitializing DHT" ); event_free( dht_event ); dht_event = NULL; if( dht6_event ) { event_free( dht6_event ); dht6_event = NULL; } /* Since we only save known good nodes, avoid erasing older data if we don't know enough nodes. */ if(tr_dhtStatus(ss, AF_INET, NULL) < TR_DHT_FIREWALLED) tr_ninf( "DHT", "Not saving nodes, DHT not ready" ); else { tr_benc benc; struct sockaddr_in sins[300]; struct sockaddr_in6 sins6[300]; char compact[300 * 6], compact6[300 * 18]; char *dat_file; int i, j, num = 300, num6 = 300; int n = dht_get_nodes(sins, &num, sins6, &num6); tr_ninf( "DHT", "Saving %d (%d + %d) nodes", n, num, num6 ); j = 0; for( i=0; i<num; ++i ) { memcpy( compact + j, &sins[i].sin_addr, 4 ); memcpy( compact + j + 4, &sins[i].sin_port, 2 ); j += 6; } j = 0; for( i=0; i<num6; ++i ) { memcpy( compact6 + j, &sins6[i].sin6_addr, 16 ); memcpy( compact6 + j + 16, &sins6[i].sin6_port, 2 ); j += 18; } tr_bencInitDict( &benc, 3 ); tr_bencDictAddRaw( &benc, "id", myid, 20 ); if(num > 0) tr_bencDictAddRaw( &benc, "nodes", compact, num * 6 ); if(num6 > 0) tr_bencDictAddRaw( &benc, "nodes6", compact6, num6 * 18 ); dat_file = tr_buildPath( ss->configDir, "dht.dat", NULL ); tr_bencToFile( &benc, TR_FMT_BENC, dat_file ); tr_bencFree( &benc ); tr_free( dat_file ); } dht_uninit( 1 ); tr_netCloseSocket( dht_socket ); dht_socket = -1; if(dht6_socket > 0) { tr_netCloseSocket( dht6_socket ); dht6_socket = -1; } tr_ndbg("DHT", "Done uninitializing DHT"); session = NULL; }