Esempio n. 1
0
 public void SafeDnsLabel()
 {
     Assert.AreEqual("a", MdnsNext.SafeLabel("a", 2));
     Assert.AreEqual("ab", MdnsNext.SafeLabel("ab", 2));
     Assert.AreEqual("ab.c", MdnsNext.SafeLabel("abc", 2));
     Assert.AreEqual("ab.cd", MdnsNext.SafeLabel("abcd", 2));
     Assert.AreEqual("ab.cd.e", MdnsNext.SafeLabel("abcde", 2));
     Assert.AreEqual("ab.cd.ef", MdnsNext.SafeLabel("abcdef", 2));
     Assert.AreEqual("ab.cd.ef.g", MdnsNext.SafeLabel("abcdefg", 2));
 }
Esempio n. 2
0
        public async Task DiscoveryNext()
        {
            var serviceName = $"_{Guid.NewGuid()}._udp";
            var peer1       = new Peer
            {
                Id        = "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
                Addresses = new MultiAddress[] { "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ" }
            };
            var peer2 = new Peer
            {
                Id        = "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuK",
                Addresses = new MultiAddress[] { "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuK" }
            };
            var done  = new ManualResetEvent(false);
            var mdns1 = new MdnsNext
            {
                MulticastService = new MulticastService(),
                ServiceName      = serviceName,
                LocalPeer        = peer1
            };
            var mdns2 = new MdnsNext
            {
                MulticastService = new MulticastService(),
                ServiceName      = serviceName,
                LocalPeer        = peer2
            };

            mdns1.PeerDiscovered += (s, e) =>
            {
                if (e.Id == peer2.Id)
                {
                    done.Set();
                }
            };
            await mdns1.StartAsync();

            mdns1.MulticastService.Start();
            await mdns2.StartAsync();

            mdns2.MulticastService.Start();
            try
            {
                Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(2)), "timeout");
            }
            finally
            {
                await mdns1.StopAsync();

                await mdns2.StopAsync();

                mdns1.MulticastService.Stop();
                mdns2.MulticastService.Stop();
            }
        }
Esempio n. 3
0
        /// <summary>
        ///   Starts the network services.
        /// </summary>
        /// <returns>
        ///   A task that represents the asynchronous operation.
        /// </returns>
        /// <remarks>
        ///   Starts the various IPFS and PeerTalk network services.  This should
        ///   be called after any configuration changes.
        /// </remarks>
        /// <exception cref="Exception">
        ///   When the engine is already started.
        /// </exception>
        public async Task StartAsync()
        {
            if (stopTasks.Count > 0)
            {
                throw new Exception("IPFS engine is already started.");
            }

            var localPeer = await LocalPeer.ConfigureAwait(false);

            log.Debug("starting " + localPeer.Id);

            // Everybody needs the swarm.
            var swarm = await SwarmService.ConfigureAwait(false);

            stopTasks.Add(async() =>
            {
                await swarm.StopAsync().ConfigureAwait(false);
            });
            await swarm.StartAsync().ConfigureAwait(false);

            // Start the primary services.
            var tasks = new List <Func <Task> >
            {
                async() =>
                {
                    var bitswap = await BitswapService.ConfigureAwait(false);

                    stopTasks.Add(async() => await bitswap.StopAsync().ConfigureAwait(false));
                    await bitswap.StartAsync().ConfigureAwait(false);
                },
                async() =>
                {
                    var dht = await DhtService.ConfigureAwait(false);

                    stopTasks.Add(async() => await dht.StopAsync().ConfigureAwait(false));
                    await dht.StartAsync().ConfigureAwait(false);
                },
                async() =>
                {
                    var pubsub = await PubSubService.ConfigureAwait(false);

                    stopTasks.Add(async() => await pubsub.StopAsync().ConfigureAwait(false));
                    await pubsub.StartAsync().ConfigureAwait(false);
                },
            };

            log.Debug("waiting for services to start");
            await Task.WhenAll(tasks.Select(t => t())).ConfigureAwait(false);

            // Starting listening to the swarm.
            var json = await Config.GetAsync("Addresses.Swarm").ConfigureAwait(false);

            var numberListeners = 0;

            foreach (string a in json)
            {
                try
                {
                    await swarm.StartListeningAsync(a).ConfigureAwait(false);

                    ++numberListeners;
                }
                catch (Exception e)
                {
                    log.Warn($"Listener failure for '{a}'", e);
                    // eat the exception
                }
            }
            if (numberListeners == 0)
            {
                log.Error("No listeners were created.");
            }

            // Now that the listener addresses are established, the discovery
            // services can begin.
            MulticastService multicast = null;

            if (!Options.Discovery.DisableMdns)
            {
                multicast = new MulticastService();
#pragma warning disable CS1998
                stopTasks.Add(async() => multicast.Dispose());
#pragma warning restore CS1998
            }

            var autodialer = new AutoDialer(swarm)
            {
                MinConnections = Options.Swarm.MinConnections
            };
#pragma warning disable CS1998
            stopTasks.Add(async() => autodialer.Dispose());
#pragma warning restore CS1998

            tasks = new List <Func <Task> >
            {
                // Bootstrap discovery
                async() =>
                {
                    var bootstrap = new PeerTalk.Discovery.Bootstrap
                    {
                        Addresses = await this.Bootstrap.ListAsync()
                    };
                    bootstrap.PeerDiscovered += OnPeerDiscovered;
                    stopTasks.Add(async() => await bootstrap.StopAsync().ConfigureAwait(false));
                    await bootstrap.StartAsync().ConfigureAwait(false);
                },
                // New multicast DNS discovery
                async() =>
                {
                    if (Options.Discovery.DisableMdns)
                    {
                        return;
                    }
                    var mdns = new PeerTalk.Discovery.MdnsNext
                    {
                        LocalPeer        = localPeer,
                        MulticastService = multicast
                    };
                    if (Options.Swarm.PrivateNetworkKey != null)
                    {
                        mdns.ServiceName = $"_p2p-{Options.Swarm.PrivateNetworkKey.Fingerprint().ToHexString()}._udp";
                    }
                    mdns.PeerDiscovered += OnPeerDiscovered;
                    stopTasks.Add(async() => await mdns.StopAsync().ConfigureAwait(false));
                    await mdns.StartAsync().ConfigureAwait(false);
                },
                // Old style JS multicast DNS discovery
                async() =>
                {
                    if (Options.Discovery.DisableMdns || Options.Swarm.PrivateNetworkKey != null)
                    {
                        return;
                    }
                    var mdns = new PeerTalk.Discovery.MdnsJs
                    {
                        LocalPeer        = localPeer,
                        MulticastService = multicast
                    };
                    mdns.PeerDiscovered += OnPeerDiscovered;
                    stopTasks.Add(async() => await mdns.StopAsync().ConfigureAwait(false));
                    await mdns.StartAsync().ConfigureAwait(false);
                },
                // Old style GO multicast DNS discovery
                async() =>
                {
                    if (Options.Discovery.DisableMdns || Options.Swarm.PrivateNetworkKey != null)
                    {
                        return;
                    }
                    var mdns = new PeerTalk.Discovery.MdnsGo
                    {
                        LocalPeer        = localPeer,
                        MulticastService = multicast
                    };
                    mdns.PeerDiscovered += OnPeerDiscovered;
                    stopTasks.Add(async() => await mdns.StopAsync().ConfigureAwait(false));
                    await mdns.StartAsync().ConfigureAwait(false);
                },
                async() =>
                {
                    if (Options.Discovery.DisableRandomWalk)
                    {
                        return;
                    }
                    var randomWalk = new RandomWalk {
                        Dht = Dht
                    };
                    stopTasks.Add(async() => await randomWalk.StopAsync().ConfigureAwait(false));
                    await randomWalk.StartAsync().ConfigureAwait(false);
                }
            };
            log.Debug("waiting for discovery services to start");
            await Task.WhenAll(tasks.Select(t => t())).ConfigureAwait(false);

            multicast?.Start();

            log.Debug("started");
        }
Esempio n. 4
0
        /// <summary>
        ///   Starts the network services.
        /// </summary>
        /// <returns>
        ///   A task that represents the asynchronous operation.
        /// </returns>
        /// <remarks>
        ///   Starts the various IPFS and PeerTalk network services.  This should
        ///   be called after any configuration changes.
        /// </remarks>
        /// <exception cref="Exception">
        ///   When the engine is already started.
        /// </exception>
        public async Task StartAsync()
        {
            if (stopTasks.Count > 0)
            {
                throw new Exception("IPFS engine is already started.");
            }

            var localPeer = await LocalPeer;

            log.Debug("starting " + localPeer.Id);

            // Everybody needs the swarm.
            var swarm = await SwarmService;

            stopTasks.Add(async() => await swarm.StopAsync());
            await swarm.StartAsync();

            var multicast = new MulticastService();

#pragma warning disable CS1998
            stopTasks.Add(async() => multicast.Dispose());
#pragma warning restore CS1998

            var tasks = new List <Func <Task> >
            {
                async() =>
                {
                    var bootstrap = new PeerTalk.Discovery.Bootstrap
                    {
                        Addresses = await this.Bootstrap.ListAsync()
                    };
                    bootstrap.PeerDiscovered += OnPeerDiscovered;
                    stopTasks.Add(async() => await bootstrap.StopAsync());
                    await bootstrap.StartAsync();
                },
                async() =>
                {
                    var mdns = new PeerTalk.Discovery.MdnsNext
                    {
                        LocalPeer        = localPeer,
                        MulticastService = multicast
                    };
                    mdns.PeerDiscovered += OnPeerDiscovered;
                    stopTasks.Add(async() => await mdns.StopAsync());
                    await mdns.StartAsync();
                },
                async() =>
                {
                    var mdns = new PeerTalk.Discovery.MdnsJs
                    {
                        LocalPeer        = localPeer,
                        MulticastService = multicast
                    };
                    mdns.PeerDiscovered += OnPeerDiscovered;
                    stopTasks.Add(async() => await mdns.StopAsync());
                    await mdns.StartAsync();
                },
                async() =>
                {
                    var mdns = new PeerTalk.Discovery.MdnsGo
                    {
                        LocalPeer        = localPeer,
                        MulticastService = multicast
                    };
                    mdns.PeerDiscovered += OnPeerDiscovered;
                    stopTasks.Add(async() => await mdns.StopAsync());
                    await mdns.StartAsync();
                },
                async() =>
                {
                    var bitswap = await BitswapService;
                    stopTasks.Add(async() => await bitswap.StopAsync());
                    await bitswap.StartAsync();
                },
                async() =>
                {
                    var dht = await DhtService;
                    stopTasks.Add(async() => await dht.StopAsync());
                    await dht.StartAsync();
                },
            };

            log.Debug("waiting for services to start");
            await Task.WhenAll(tasks.Select(t => t()));

            // TODO: Would be nice to make this deterministic.
            //await Task.Delay(TimeSpan.FromMilliseconds(100));
            //log.Debug("all service started");

            // Starting listening to the swarm.
            var json = await Config.GetAsync("Addresses.Swarm");

            var numberListeners = 0;
            foreach (string a in json)
            {
                try
                {
                    await swarm.StartListeningAsync(a);

                    ++numberListeners;
                }
                catch (Exception e)
                {
                    log.Warn($"Listener failure for '{a}'", e);
                    // eat the exception
                }
            }
            if (numberListeners == 0)
            {
                log.Error("No listeners were created.");
            }

            // Now that the listener addresses are established, the mdns discovery can begin.
            // TODO: Maybe all discovery services should be start here.
            multicast.Start();

            log.Debug("started");
        }