kns: variable length array IP encoding

This commit is contained in:
bitful-pannul 2024-08-05 20:43:21 +03:00
parent 950c42d909
commit c513dd1db0
3 changed files with 34 additions and 30 deletions

View File

@ -506,15 +506,15 @@ fn decode_routers(data: &[u8], state: &State) -> anyhow::Result<Vec<String>> {
pub fn bytes_to_ip(bytes: &[u8]) -> anyhow::Result<IpAddr> {
match bytes.len() {
4 => {
// IPv4 address
let ip_num = u32::from_be_bytes(bytes.try_into().unwrap());
Ok(IpAddr::V4(Ipv4Addr::from(ip_num)))
}
16 => {
// IPv6 address
let ip_num = u128::from_be_bytes(bytes.try_into().unwrap());
if ip_num < (1u128 << 32) {
// IPv4
Ok(IpAddr::V4(Ipv4Addr::from(ip_num as u32)))
} else {
// IPv6
Ok(IpAddr::V6(Ipv6Addr::from(ip_num)))
}
Ok(IpAddr::V6(Ipv6Addr::from(ip_num)))
}
_ => Err(anyhow::anyhow!("Invalid byte length for IP address")),
}

View File

@ -161,31 +161,35 @@ pub fn namehash(name: &str) -> [u8; 32] {
node.into()
}
pub fn bytes_to_ip(bytes: &[u8]) -> Result<IpAddr, String> {
pub fn bytes_to_ip(bytes: &[u8]) -> Result<IpAddr> {
match bytes.len() {
16 => {
let ip_num = u128::from_be_bytes(bytes.try_into().unwrap());
if ip_num < (1u128 << 32) {
// IPv4
Ok(IpAddr::V4(Ipv4Addr::from(ip_num as u32)))
} else {
// IPv6
Ok(IpAddr::V6(Ipv6Addr::from(ip_num)))
}
4 => {
// IPv4 address
let ip_num = u32::from_be_bytes(bytes.try_into().unwrap());
Ok(IpAddr::V4(Ipv4Addr::from(ip_num)))
}
other => Err(format!("Invalid byte length for IP address: {other}")),
16 => {
// IPv6 address
let ip_num = u128::from_be_bytes(bytes.try_into().unwrap());
Ok(IpAddr::V6(Ipv6Addr::from(ip_num)))
}
_ => Err(anyhow::anyhow!("Invalid byte length for IP address")),
}
}
#[cfg(feature = "simulation-mode")]
pub fn ip_to_bytes(ip: IpAddr) -> [u8; 16] {
pub fn ip_to_bytes(ip: IpAddr) -> Vec<u8> {
match ip {
IpAddr::V4(ipv4) => {
let mut bytes = [0u8; 16];
bytes[12..].copy_from_slice(&ipv4.octets());
let mut bytes = Vec::with_capacity(4);
bytes.extend_from_slice(&ipv4.octets());
bytes
}
IpAddr::V6(ipv6) => {
let mut bytes = Vec::with_capacity(16);
bytes.extend_from_slice(&ipv6.octets());
bytes
}
IpAddr::V6(ipv6) => ipv6.octets(),
}
}

View File

@ -20,24 +20,24 @@ export function bytesToIp(bytes: Uint8Array): string {
}
export function ipToBytes(ip: string): Uint8Array {
const bytes = new Uint8Array(16);
const view = new DataView(bytes.buffer);
if (ip.includes(':')) {
// IPv6
// IPv6: Create a 16-byte array
const bytes = new Uint8Array(16);
const view = new DataView(bytes.buffer);
const parts = ip.split(':');
for (let i = 0; i < 8; i++) {
view.setUint16(i * 2, parseInt(parts[i] || '0', 16));
}
return bytes;
} else {
// IPv4
// IPv4: Create a 4-byte array
const bytes = new Uint8Array(4);
const parts = ip.split('.');
for (let i = 0; i < 4; i++) {
bytes[12 + i] = parseInt(parts[i], 10);
bytes[i] = parseInt(parts[i], 10);
}
return bytes;
}
return bytes;
}
export function bytesToPort(bytes: Uint8Array): number {