public bool SetI2P(string address) { address = address.ToLowerInvariant(); if (!address.EndsWith(".b32.i2p", StringComparison.Ordinal)) { return(false); } var encoded = address.Substring(0, address.Length - ".b32.i2p".Length); if (encoded.Length != 52) { return(false); } byte[] bytes; try { bytes = Encoders.Base32.DecodeData(encoded + "===="); } catch (FormatException) { return(false); } if (bytes.Length != ADDR_I2P_SIZE + 3) { return(false); } network = NetworkAddressType.I2P; addr = bytes.SafeSubarray(0, ADDR_I2P_SIZE); return(true); }
public void SetLegacyIpv6(byte[] ipv6) { if (ipv6.Length != ADDR_IPV6_SIZE) { throw new ArgumentException("The received value is not a valid IPv6 byte array.", nameof(ipv6)); } var skip = 0; if (HasPrefix(ipv6, IPV4_IN_IPV6_PREFIX)) { network = NetworkAddressType.IPv4; skip = IPV4_IN_IPV6_PREFIX.Length; } else if (HasPrefix(ipv6, TORV2_IN_IPV6_PREFIX)) { // TORv2-in-IPv6 network = NetworkAddressType.Onion; skip = TORV2_IN_IPV6_PREFIX.Length; } else { // IPv6 network = NetworkAddressType.IPv6; } addr = ipv6.SafeSubarray(skip); }
private bool SetTor(string address) { if (!address.EndsWith(".onion", StringComparison.Ordinal)) { return(false); } byte[] bytes; try { bytes = Encoders.Base32.DecodeData(address.Substring(0, address.Length - ".onion".Length)); } catch (FormatException) { return(false); } if (bytes.Length == ADDR_TORV2_SIZE) { network = NetworkAddressType.Onion; addr = bytes; return(true); } else if (bytes.Length == ADDR_TORV3_SIZE + TORV3_ADDR_CHECKSUM_LEN + TORV3_ADDR_VERSION_LEN) { var version = bytes[bytes.Length - 1]; if (version != 3) { return(false); } var pubkey = bytes.SafeSubarray(0, ADDR_TORV3_SIZE); var chksum = bytes.SafeSubarray(ADDR_TORV3_SIZE, TORV3_ADDR_CHECKSUM_LEN); var calculatedChecksum = CalculateChecksum(pubkey); if (!Utils.ArrayEqual(chksum, calculatedChecksum)) { return(false); } network = NetworkAddressType.Onion; addr = pubkey; return(true); } return(false); }
private bool SetNetFromBIP155Network(BIP155Network bip155Network, int length) { NetworkAddressType AssignIfCorrectSize(NetworkAddressType net, int expectedSize) { if (length != expectedSize) { throw new ArgumentException($"BIP155 {(BIP155Network)bip155Network} address is {length} bytes long. Expected length is {expectedSize} bytes."); } return(net); } switch (bip155Network) { case BIP155Network.IPv4: network = AssignIfCorrectSize(NetworkAddressType.IPv4, ADDR_IPV4_SIZE); break; case BIP155Network.IPv6: network = AssignIfCorrectSize(NetworkAddressType.IPv6, ADDR_IPV6_SIZE); break; case BIP155Network.TORv2: network = AssignIfCorrectSize(NetworkAddressType.Onion, ADDR_TORV2_SIZE); break; case BIP155Network.TORv3: network = AssignIfCorrectSize(NetworkAddressType.Onion, ADDR_TORV3_SIZE); break; case BIP155Network.I2P: network = AssignIfCorrectSize(NetworkAddressType.I2P, ADDR_I2P_SIZE); break; case BIP155Network.Cjdns: network = AssignIfCorrectSize(NetworkAddressType.Cjdns, ADDR_CJDNS_SIZE); break; default: return(false); } return(true); }
public NetworkAddress(EndPoint endPoint) { if (endPoint == null) { throw new ArgumentNullException(nameof(endPoint)); } Endpoint = endPoint; if (endPoint.IsTor()) { network = NetworkAddressType.Onion; } else if (endPoint is IPEndPoint ip) { SetIp(ip.Address); } else { throw new NotSupportedException($"Unsupported endpoint of type {endPoint.GetType()}"); } }
public virtual void ReadWrite(BitcoinStream stream) { var version = stream.ProtocolVersion ?? 0; if (stream.Type == SerializationType.Disk) { stream.ReadWrite(ref version); } if ( stream.Type == SerializationType.Disk || (stream.ProtocolCapabilities.SupportTimeAddress && stream.Type != SerializationType.Hash)) { // The only time we serialize a CAddress object without nTime is in // the initial VERSION messages which contain two CAddress records. // At that point, the serialization version is INIT_PROTO_VERSION. // After the version handshake, serialization version is >= // MIN_PEER_PROTO_VERSION and all ADDR messages are serialized with // nTime. stream.ReadWrite(ref nTime); } if ((version & AddrV2Format) != 0) { stream.ReadWriteAsVarInt(ref services); } else { stream.ReadWrite(ref services); } var useV2Format = stream.ProtocolVersion is {} protcocolVersion&& (protcocolVersion & AddrV2Format) != 0; if (useV2Format) { if (stream.Serializing) { var bip155net = (byte)GetBIP155Network(); stream.ReadWrite(bip155net); stream.ReadWriteAsVarString(ref addr); } else { byte n = 0; stream.ReadWrite(ref n); stream.ReadWriteAsVarString(ref addr); if (SetNetFromBIP155Network((BIP155Network)n, addr.Length)) { if (network == NetworkAddressType.IPv6) { if (HasPrefix(addr, IPV4_IN_IPV6_PREFIX) || HasPrefix(addr, TORV2_IN_IPV6_PREFIX)) { // set to invalid because IPv4 and Torv2 should not be embeded in IPv6. addr = IPV6_NONE; network = NetworkAddressType.IPv6; } } } else { // set to invalid because IPv4 and Torv2 should not be embeded in IPv6. addr = IPV6_NONE; network = NetworkAddressType.IPv6; } } } else { if (stream.Serializing) { var localAddr = IsAddrV1Compatible ? SerializeV1Array() : IPV6_NONE; stream.ReadWrite(ref localAddr); } else { var localAddr = new byte[ADDR_IPV6_SIZE]; stream.ReadWrite(ref localAddr); SetLegacyIpv6(localAddr); } } using (stream.BigEndianScope()) { stream.ReadWrite(ref port); } }