public void Listen(int maxIncoming = 8) { if (this.socket != null) { throw new InvalidOperationException("Already listening"); } using (this.trace.Open()) { try { this.socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); this.socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); this.socket.Bind(this.LocalEndpoint); this.socket.Listen(maxIncoming); NodeServerTrace.Information("Listening..."); this.BeginAccept(); } catch (Exception ex) { NodeServerTrace.Error("Error while opening the Protocol server", ex); throw; } } }
public async Task <bool> EnsureMapping() { NodeServerTrace.Information("EnsureMapping"); var device = await GetNatDeviceAsync(); return(device == null ? false : await device.GetSpecificMappingAsync(Protocol.Tcp, _ServerPort).ContinueWith(t => { if (t.IsFaulted) { NodeServerTrace.Error("GetExternalIP", t.Exception); return false; } var mapping = t.Result; try { if (mapping != null && !mapping.PrivateIP.Equals(InternalIPAddress)) { NodeServerTrace.Information($"existing mapping mismatch. got: {mapping.PrivateIP}, need: {InternalIPAddress}"); _NatDevice.DeletePortMapAsync(mapping).Wait(); mapping = null; } if (mapping == null) { NodeServerTrace.Information($"creaing mapping with IP: {InternalIPAddress}"); _NatDevice.CreatePortMapAsync( new Mapping( Protocol.Tcp, InternalIPAddress, _ServerPort, _ServerPort, 0, //TODO: session lifetime? MAPPING_DESC ) ).Wait(); } IEnumerable <Mapping> exisingMappings = _NatDevice.GetAllMappingsAsync().Result; return exisingMappings.Count(exisintMapping => exisintMapping.PublicPort == _ServerPort) == 1; } catch (Exception e) { NodeServerTrace.Error("Mapping", e); return false; } })); }
public bool Start() { try { _Server.Listen(); NodeServerTrace.Information("Server listening"); return(true); } catch (Exception e) { NodeServerTrace.Error("Listen", e); } return(false); }
private void FireCallbacks(List <Operation> operations) { foreach (var operation in operations) { var newOperation = this.NewOperation; if (newOperation != null) { foreach (var handler in newOperation.GetInvocationList().Cast <NewTrackerOperation>()) { try { handler.DynamicInvoke(this, operation); } catch (TargetInvocationException ex) { NodeServerTrace.Error("Error while calling Tracker callback", ex.InnerException); } } } } }
public async Task <NatDevice> GetNatDeviceAsync() { var nat = new NatDiscoverer(); var cts = new CancellationTokenSource(TIMEOUT); if (_NatDevice != null) { return(_NatDevice); } await _SemaphoreSlim.WaitAsync(); NodeServerTrace.Information("NAT Device discovery started"); return(await nat.DiscoverDeviceAsync(PortMapper.Upnp, cts).ContinueWith(t => { _SemaphoreSlim.Release(); DeviceFound = t.Status != TaskStatus.Faulted; if (!DeviceFound) { NodeServerTrace.Information("NAT Device not found"); HasError = !(t.Exception.InnerException is NatDeviceNotFoundException); if (HasError) { NodeServerTrace.Error("NAT Device discovery", t.Exception); } return null; } else { _NatDevice = t.Result; } return _NatDevice; })); }
public async Task <bool> VerifyExternalIP() { NodeServerTrace.Information("VerifyExternalIP"); var device = await GetNatDeviceAsync(); return(device == null ? false : await device.GetExternalIPAsync().ContinueWith(t => { if (t.IsFaulted) { NodeServerTrace.Error("GetExternalIP", t.Exception); return false; } ExternalIPAddress = t.Result; if (ExternalIPAddress == null) { return false; } //try //{ // IPAddress ipAddress = ExternalTestingServicesHelper.GetExternalIPAsync().Result; // bool match = ipAddress.Equals(ExternalIPAddress); // Trace.Information("External IP " + (match ? "match" : "do not match")); // return match; //} //catch (Exception e) //{ // Trace.Error("GetExternalIP", e); // return false; //} return ExternalIPAddress.IsRoutable(false); })); }
private void ProcessMessageCore(IncomingMessage message) { if (message.Message.Payload is VersionPayload) { VersionPayload version = message.AssertPayload <VersionPayload>(); bool connectedToSelf = version.Nonce == this.Nonce; if ((message.NetworkPeer != null) && connectedToSelf) { NodeServerTrace.ConnectionToSelfDetected(); message.NetworkPeer.DisconnectAsync(); return; } if (message.NetworkPeer == null) { IPEndPoint remoteEndpoint = version.AddressFrom; if (!remoteEndpoint.Address.IsRoutable(this.AllowLocalPeers)) { // Send his own endpoint. remoteEndpoint = new IPEndPoint(((IPEndPoint)message.Socket.RemoteEndPoint).Address, this.Network.DefaultPort); } var peerAddress = new NetworkAddress() { Endpoint = remoteEndpoint, Time = DateTimeOffset.UtcNow }; NetworkPeer networkPeer = this.networkPeerFactory.CreateNetworkPeer(peerAddress, this.Network, CreateNetworkPeerConnectionParameters(), message.Socket, version); if (connectedToSelf) { networkPeer.SendMessage(CreateNetworkPeerConnectionParameters().CreateVersion(networkPeer.PeerAddress.Endpoint, this.Network)); NodeServerTrace.ConnectionToSelfDetected(); networkPeer.Disconnect(); return; } CancellationTokenSource cancel = new CancellationTokenSource(); cancel.CancelAfter(TimeSpan.FromSeconds(10.0)); try { this.ConnectedNetworkPeers.Add(networkPeer); networkPeer.StateChanged += Peer_StateChanged; networkPeer.RespondToHandShake(cancel.Token); } catch (OperationCanceledException ex) { NodeServerTrace.Error("The remote peer did not respond fast enough (10 seconds) to the handshake completion, dropping connection", ex); networkPeer.DisconnectAsync(); throw; } catch (Exception) { networkPeer.DisconnectAsync(); throw; } } } this.MessageReceived?.Invoke(this, message); }
private void EndAccept(SocketAsyncEventArgs args) { using (this.trace.Open()) { Socket client = null; try { if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } client = args.AcceptSocket; if (this.cancel.IsCancellationRequested) { return; } NodeServerTrace.Information("Client connection accepted : " + client.RemoteEndPoint); var cancel = CancellationTokenSource.CreateLinkedTokenSource(this.cancel.Token); cancel.CancelAfter(TimeSpan.FromSeconds(10)); var stream = new NetworkStream(client, false); while (true) { if (this.ConnectedNetworkPeers.Count >= this.MaxConnections) { NodeServerTrace.Information("MaxConnections limit reached"); Utils.SafeCloseSocket(client); break; } cancel.Token.ThrowIfCancellationRequested(); PerformanceCounter counter; Message message = Message.ReadNext(stream, this.Network, this.Version, cancel.Token, out counter); this.messageProducer.PushMessage(new IncomingMessage() { Socket = client, Message = message, Length = counter.ReadBytes, NetworkPeer = null, }); if (message.Payload is VersionPayload) { break; } NodeServerTrace.Error("The first message of the remote peer did not contained a Version payload", null); } } catch (OperationCanceledException) { Utils.SafeCloseSocket(client); if (!this.cancel.Token.IsCancellationRequested) { NodeServerTrace.Error("The remote connecting failed to send a message within 10 seconds, dropping connection", null); } } catch (Exception ex) { if (this.cancel.IsCancellationRequested) { return; } if (client == null) { NodeServerTrace.Error("Error while accepting connection ", ex); Thread.Sleep(3000); } else { Utils.SafeCloseSocket(client); NodeServerTrace.Error("Invalid message received from the remote connecting peer", ex); } } this.BeginAccept(); } }