public static IPEndPoint DecodeStunAddress( this byte[] encoded, byte[] transactionId ) { uint cookie = StunMessage.MagicCookie.ToUInt(); bool inTransaction = transactionId != null; using (var ms = new MemoryStream(encoded)) { ms.ReadByte(); StunAf family = (StunAf)ms.ReadByte(); var portBytes = new byte[2]; ms.Read(portBytes, 0, 2); int port = inTransaction ? (int)(portBytes.ToUShort() ^ (cookie >> 16)) : portBytes.ToUShort(); byte[] addrBytes = null; switch (family) { case StunAf.IpV4: addrBytes = new byte[4]; ms.Read(addrBytes, 0, 4); uint addr = inTransaction ? addrBytes.ToUInt() ^ cookie : addrBytes.ToUInt(); addrBytes = addr.ToBytes(); break; case StunAf.IpV6: addrBytes = new byte[16]; ms.Read(addrBytes, 0, 16); foreach (var index in Enumerable.Range(0, 16)) { addrBytes[index] ^= index < 4 ? StunMessage.MagicCookie[index] : transactionId[index - 4]; } break; default: throw new InvalidStunAddressException( $"Unknown address familiy {family}."); } return(new IPEndPoint( new IPAddress(addrBytes), port)); } }
public static IPEndPoint DecodeStunAddress( this byte[] encoded, byte[] transactionId ) { uint cookie = StunMessage.MagicCookie.ToUInt(); bool inTransaction = transactionId != null; using (var ms = new MemoryStream(encoded)) { ms.ReadByte(); StunAf family = (StunAf)ms.ReadByte(); var portBytes = new byte[2]; ms.Read(portBytes, 0, 2); int port = inTransaction ? (int)(portBytes.ToUShort() ^ (cookie >> 16)) : portBytes.ToUShort(); switch (family) { case StunAf.IpV4: var addrBytes = new byte[4]; ms.Read(addrBytes, 0, 4); uint addr = inTransaction ? addrBytes.ToUInt() ^ cookie : addrBytes.ToUInt(); return(new IPEndPoint( new IPAddress(addr.ToBytes()), port)); default: throw new InvalidStunAddressException( $"Unknown address familiy {family}."); } } }