alanmcgovern / monotorrent

The official repository for MonoTorrent, a bittorrent library for .NET
https://github.com/alanmcgovern/monotorrent
MIT License
1.15k stars 397 forks source link

DHT initialize failed. #669

Closed peerlessDJ closed 3 months ago

peerlessDJ commented 3 months ago
var dl = new DhtListener(new IPEndPoint(IPAddress.Any, 54123));
var de = new DhtEngine();
await de.SetListenerAsync(dl);
de.StateChanged += (object sender, EventArgs e) =>
{
    Debug.WriteLine($"dht state:{de.State}, node count:{de.NodeCount}");
};
await de.StartAsync();

The log is

dht state:Initialising, node count:0
dht state:NotReady, node count:0
alanmcgovern commented 3 months ago

As of the time of writing, both router.bittorrent.com and router.utorrent.com are offline. These are supposed to be DHT nodes which can be queried if you have no other source of dht node information. If these nodes are non-responsive, you'll need an alternate way to bootstrap into the DHT swarm.

The folks who develop Transmission also host a bootstrap node, dht.transmissionbt.com, which is online. It's not part of the fallback set used by monotorrent, but it can be added.

The other standard way to bootstrap into the DHT swarm is to download a torrent and fetch information from one of the peers who is part of the swarm. If you're creating a dht engine manually, then you'll likely be relying exclusively on these freely hosted routers.

You can host your own router ( https://github.com/bittorrent/bootstrap-dht ) if you really depend on these being online, or you could potentially build an alternative mechanism to share node information. I reckon hosting your own router would be the simplest and most stable :)

alanmcgovern commented 3 months ago

An awful hacky way to get around this is to do something like this in your code:

var nodes = ReadOnlyMemory<byte>.Empty;
if (File.Exists ("mynodes")) {
    nodes = File.ReadAllBytes ("mynodes");
} else {
    var addresses = await Dns.GetHostAddressesAsync ("dht.transmissionbt.com");
    nodes = addresses
        .Distinct ()
        .Select (t => {
            byte[] array = new byte[26];
            Span<byte> buffer = array.AsSpan(20);
            Message.Write (ref buffer, t.GetAddressBytes ());
            Message.Write (ref buffer, (ushort) 6881);
            return array;
        })
        .SelectMany (t => t)
        .ToArray ();
}

// Listen to some events
engine.PeersFound += (o, e) => {
    Console.WriteLine ("Found peers: {0}", e.Peers.Count);
};

engine.StateChanged += async (o, e) => {
    Console.WriteLine ("Current state: {0}", engine.State);
    if (engine.State == DhtState.Ready)
        File.WriteAllBytes ("mynodes", (await engine.SaveNodesAsync ()).ToArray ());
};

// Bootstrap into the DHT engine using previously saved nodes, or the working router
await engine.StartAsync (nodes);
alanmcgovern commented 3 months ago

This patch makes custom routers easier to use: https://github.com/alanmcgovern/monotorrent/pull/670

It also adds transmissions bootstrap router

peerlessDJ commented 3 months ago

Resolved! Thanks.

alanmcgovern commented 3 months ago

+1

Merged those changes to the lib as well so additional default bootstrap routers are supported, and custom ones can be added too