Skip to content

Commit afadc61

Browse files
committed
add enum for error handling netaddress fromstr
1 parent 0c549b7 commit afadc61

File tree

1 file changed

+46
-31
lines changed

1 file changed

+46
-31
lines changed

lightning/src/ln/msgs.rs

+46-31
Original file line numberDiff line numberDiff line change
@@ -904,9 +904,23 @@ impl Readable for NetAddress {
904904
}
905905
}
906906

907+
/// NetAddress error variants
908+
#[cfg(feature = "std")]
909+
#[derive(Debug)]
910+
pub enum NetAddressError {
911+
/// Socket address(IPv4/IPv6) parsing error
912+
SocketAdrrParseError(std::net::AddrParseError),
913+
/// Invalid input format
914+
InvalidInput(String),
915+
/// Invalid port
916+
InvalidPort,
917+
/// Invalid onion v3 address
918+
InvalidOnionV3,
919+
}
920+
907921
#[cfg(feature = "std")]
908922
impl FromStr for NetAddress {
909-
type Err = std::net::AddrParseError;
923+
type Err = NetAddressError;
910924

911925
fn from_str(s: &str) -> Result<Self, Self::Err> {
912926
match std::net::SocketAddr::from_str(s) {
@@ -924,41 +938,42 @@ impl FromStr for NetAddress {
924938
}
925939
},
926940
Err(e) => {
927-
let trimmed_input = match s.rfind(":") {
928-
Some(pos) => pos,
929-
None => return Err(e),
930-
};
931-
let host = &s[..trimmed_input];
932-
let port: u16 = match s[trimmed_input + 1..].parse() {
933-
Ok(port) => port,
934-
Err(_) => return Err(e),
935-
};
936-
if host.ends_with(".onion") {
937-
let onion = match host.split(".onion").nth(0) {
938-
Some(onion) => onion,
939-
None => return Err(e),
940-
};
941-
let decoded_onion = base32::Alphabet::RFC4648 { padding: false }.decode(&onion);
942-
let onion = match decoded_onion {
943-
Ok(onion) => onion,
944-
Err(_) => return Err(e)
945-
};
946-
let version = match onion.get(0) {
947-
Some(version) => version,
948-
None => return Err(e),
949-
};
950-
let checksum = u16::from_be_bytes([onion[1], onion[2]]);
951-
let ed25519_pubkey = match onion[3..35].try_into() {
952-
Ok(ed25519_pubkey) => ed25519_pubkey,
953-
Err(_) => return Err(e),
954-
};
955-
return Ok(NetAddress::OnionV3 { ed25519_pubkey, checksum, version: *version, port });
941+
let trimmed_input = match s.rfind(":") {
942+
Some(pos) => pos,
943+
None => return Err(NetAddressError::InvalidInput("Invalid input. Expected format: \"<host>:<port>\"" .to_string())),
944+
};
945+
let host = &s[..trimmed_input];
946+
let port: u16 = match s[trimmed_input + 1..].parse() {
947+
Ok(port) => port,
948+
Err(_) => return Err(NetAddressError::InvalidPort),
949+
};
950+
if host.ends_with(".onion") {
951+
let onion = match host.split(".onion").nth(0) {
952+
Some(onion) => onion,
953+
None => return Err(NetAddressError::InvalidOnionV3),
954+
};
955+
let onion = match (base32::Alphabet::RFC4648 { padding: false }.decode(&onion)) {
956+
Ok(onion) => onion,
957+
Err(_) => return Err(NetAddressError::InvalidOnionV3),
958+
};
959+
match (onion.get(0), onion.get(1), onion.get(2)) {
960+
(Some(version), Some(first_checksum_flag), Some(second_checksum_flag)) => {
961+
let checksum = u16::from_be_bytes([*first_checksum_flag, *second_checksum_flag]);
962+
let ed25519_pubkey = match onion[3..35].try_into() {
963+
Ok(ed25519_pubkey) => ed25519_pubkey,
964+
Err(_) => return Err(NetAddressError::InvalidOnionV3),
965+
};
966+
return Ok(NetAddress::OnionV3 { ed25519_pubkey, checksum, version: *version, port });
967+
968+
},
969+
_ => return Err(NetAddressError::InvalidOnionV3),
970+
}
956971
}
957972

958973
if let Ok(hostname) = Hostname::try_from(host.to_string()) {
959974
return Ok(NetAddress::Hostname { hostname, port });
960975
}
961-
return Err(e)
976+
return Err(NetAddressError::SocketAdrrParseError(e))
962977
},
963978
}
964979
}

0 commit comments

Comments
 (0)