/// <inheritdoc /> public override async Task <bool> IsAvailableAsync() { var hello = new AnnounceRequest { ClientAddress = LocalEndPoint.Address }; try { var res = await SendAndReceiveAsync(hello); var response = Message.Create <Response>(res); switch (response.ResultCode) { case 0: if (response.Version == ProtocolVersion) { UnavailableReason = ""; return(true); } UnavailableReason = "Protocol version not support."; return(false); case 2: UnavailableReason = "Unathorised"; return(false); default: UnavailableReason = $"Error code {response.ResultCode}."; return(false); } } catch (TimeoutException) { UnavailableReason = "No response received."; return(false); } catch (Exception e) { UnavailableReason = $"Unexpected exception '{e.GetType().FullName}'. {e.Message}."; return(false); } }
/// <summary> /// Create a message from the specified datagram. /// </summary> /// <param name="datagram"> /// The byte array containing the message. /// </param> /// <returns> /// A <see cref="Message"/> that represents the <paramref name="datagram"/>. /// </returns> public static Message Create(byte[] datagram) { if (datagram == null || datagram.Length < 4) { throw new InvalidDataException("NAT-PCP datagram must be at least 4 bytes."); } using (var ms = new MemoryStream(datagram, false)) { // Get the type of message. var reader = new NatReader(ms); var header = new Message(); header.Read(reader); Message msg = null; if (header.IsResponse) { switch (header.Opcode) { case Opcode.Announce: msg = new Response(); // no specific response data break; case Opcode.Map: msg = new MapResponse(); break; case Opcode.Peer: msg = new Response(); // TODO break; default: throw new NotSupportedException($"NAT-PCP response with opcode {header.Opcode}."); } } else { switch (header.Opcode) { case Opcode.Announce: msg = new AnnounceRequest(); break; case Opcode.Map: msg = new MapRequest(); break; case Opcode.Peer: msg = new PeerRequest(); break; default: throw new NotSupportedException($"NAT-PCP request with opcode {header.Opcode}."); } } // Read the message data. reader.Position = 0; msg.Read(reader); return(msg); } }