private async Task StartInternal()
        {
            while (!cancel.IsCancellationRequested)
            {
                var rec = await client.ReceiveAsync().WithCancellation(cancel.Token);

                Debug.Assert(rec.Buffer.Length > 0);
                try
                {
                    DiscoveryAnnounceMessage messageReq;
                    messageReq = settings.MessageSerializer.Deserialize <DiscoveryAnnounceMessage>(rec.Buffer);

                    var endpoint = new IPEndPoint(rec.RemoteEndPoint.Address, messageReq.ServicePort);
                    if (!compatibilityChecker.IsCompatibleWith(endpoint, messageReq.Version))
                    {
                        continue;
                    }
                    PeerDiscoveryMode mode = PeerDiscoveryMode.UdpDiscovery;
                    bool isLoopback        = messageReq.PeerId.Equals(announce.PeerId);
                    if (isLoopback)
                    {
                        mode |= PeerDiscoveryMode.Loopback;
                    }
                    registry.UpdatePeers(new PeerUpdateInfo[] { new PeerUpdateInfo(endpoint, mode, TimeSpan.Zero) });

                    logger.LogTrace($"Received request from {rec.RemoteEndPoint.Address}.");
                }
                catch (OperationCanceledException)
                {
                    return;
                }
                catch (Exception e)
                {
                    logger.LogDebug($"Cannot read message from {rec.RemoteEndPoint}. Reason: {e.Message}");
                    continue;
                }

                try
                {
                    await client.SendAsync(announceBytes, announceBytes.Length, rec.RemoteEndPoint).WithCancellation(cancel.Token);
                }
                catch (OperationCanceledException)
                {
                    return;
                }
                catch (SocketException)
                {
                    logger.LogTrace($"Client {rec.RemoteEndPoint} closed connection befory reply.");
                }
                catch (Exception e)
                {
                    logger.LogDebug($"Error sending response to client {rec.RemoteEndPoint}: {e.Message}");
                }
            }
        }
Exemple #2
0
        public PeerInfo(PeerClusterStatus clusterStatus, IPEndPoint endPoint, PeerDiscoveryMode discoveryMode)
        {
            Status          = clusterStatus ?? throw new ArgumentNullException(nameof(clusterStatus));
            ServiceEndPoint = endPoint ?? throw new ArgumentNullException(nameof(endPoint));
            DiscoveryMode   = discoveryMode;
            KnownPackages   = new Dictionary <Hash, PackageStatus>(0);

            if (endPoint.Port == 0)
            {
                throw new ArgumentException("Zero port is not allowed.", nameof(endPoint));
            }
        }
Exemple #3
0
        public async Task Discover()
        {
            using (client = new UdpClient())
            {
                var ip = new IPEndPoint(IPAddress.Broadcast, settings.UdpAnnouncePort);

                Debug.Assert(announceBytes.Length > 0);
                var lengthSent = await client.SendAsync(announceBytes, announceBytes.Length, ip);

                if (lengthSent != announceBytes.Length)
                {
                    throw new InvalidOperationException("Cannot send discovery datagram.");
                }

                var timeout = new CancellationTokenSource(settings.UdpDiscoveryTimeout);
                while (!timeout.IsCancellationRequested)
                {
                    DiscoveryAnnounceMessage response = null;
                    try
                    {
                        var responseData = await client.ReceiveAsync().WithCancellation(timeout.Token);

                        response = settings.MessageSerializer.Deserialize <DiscoveryAnnounceMessage>(responseData.Buffer);
                        var endpoint = new IPEndPoint(responseData.RemoteEndPoint.Address, response.ServicePort);
                        if (!compatibilityChecker.IsCompatibleWith(endpoint, response.Version))
                        {
                            continue;
                        }
                        PeerDiscoveryMode mode = PeerDiscoveryMode.UdpDiscovery;
                        bool isLoopback        = response.PeerId.Equals(announce.PeerId);
                        if (isLoopback)
                        {
                            mode |= PeerDiscoveryMode.Loopback;
                        }
                        registry.UpdatePeers(new PeerUpdateInfo[] { new PeerUpdateInfo(endpoint, mode, TimeSpan.Zero) });
                    }
                    catch (OperationCanceledException)
                    {
                        break;
                    }
                    catch (Exception e)
                    {
                        logger.LogDebug($"Cannot deserialize discovery response: {e}");
                    }
                }
            }
        }