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}"); } } }
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)); } }
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}"); } } } }