X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fmsgs.rs;h=6c04636a4355c96fb0f5158887f855a93977e7b7;hb=1b3249a1929929170bba9d2553d7a9c8670193e5;hp=87944ccae639027da172e120ea83ea8b4d06411a;hpb=4d6c26248d85abe9a3c8aeefe31b4ebafd3b5bee;p=rust-lightning diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 87944cca..6c04636a 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -80,12 +80,29 @@ pub struct Init { /// An error message to be sent or received from a peer #[derive(Clone, Debug, PartialEq)] pub struct ErrorMessage { - /// The channel ID involved in the error + /// The channel ID involved in the error. + /// + /// All-0s indicates a general error unrelated to a specific channel, after which all channels + /// with the sending peer should be closed. pub channel_id: [u8; 32], /// A possibly human-readable error description. - /// The string should be sanitized before it is used (e.g. emitted to logs - /// or printed to stdout). Otherwise, a well crafted error message may trigger a security - /// vulnerability in the terminal emulator or the logging subsystem. + /// The string should be sanitized before it is used (e.g. emitted to logs or printed to + /// stdout). Otherwise, a well crafted error message may trigger a security vulnerability in + /// the terminal emulator or the logging subsystem. + pub data: String, +} + +/// A warning message to be sent or received from a peer +#[derive(Clone, Debug, PartialEq)] +pub struct WarningMessage { + /// The channel ID involved in the warning. + /// + /// All-0s indicates a warning unrelated to a specific channel. + pub channel_id: [u8; 32], + /// A possibly human-readable warning description. + /// The string should be sanitized before it is used (e.g. emitted to logs or printed to + /// stdout). Otherwise, a well crafted error message may trigger a security vulnerability in + /// the terminal emulator or the logging subsystem. pub data: String, } @@ -394,12 +411,10 @@ pub enum NetAddress { port: u16, }, /// An old-style Tor onion address/port on which the peer is listening. - OnionV2 { - /// The bytes (usually encoded in base32 with ".onion" appended) - addr: [u8; 10], - /// The port on which the node is listening - port: u16, - }, + /// + /// This field is deprecated and the Tor network generally no longer supports V2 Onion + /// addresses. Thus, the details are not parsed here. + OnionV2([u8; 12]), /// A new-style Tor onion address/port on which the peer is listening. /// To create the human-readable "hostname", concatenate ed25519_pubkey, checksum, and version, /// wrap as base32 and append ".onion". @@ -421,7 +436,7 @@ impl NetAddress { match self { &NetAddress::IPv4 {..} => { 1 }, &NetAddress::IPv6 {..} => { 2 }, - &NetAddress::OnionV2 {..} => { 3 }, + &NetAddress::OnionV2(_) => { 3 }, &NetAddress::OnionV3 {..} => { 4 }, } } @@ -431,7 +446,7 @@ impl NetAddress { match self { &NetAddress::IPv4 { .. } => { 6 }, &NetAddress::IPv6 { .. } => { 18 }, - &NetAddress::OnionV2 { .. } => { 12 }, + &NetAddress::OnionV2(_) => { 12 }, &NetAddress::OnionV3 { .. } => { 37 }, } } @@ -453,10 +468,9 @@ impl Writeable for NetAddress { addr.write(writer)?; port.write(writer)?; }, - &NetAddress::OnionV2 { ref addr, ref port } => { + &NetAddress::OnionV2(bytes) => { 3u8.write(writer)?; - addr.write(writer)?; - port.write(writer)?; + bytes.write(writer)?; }, &NetAddress::OnionV3 { ref ed25519_pubkey, ref checksum, ref version, ref port } => { 4u8.write(writer)?; @@ -486,12 +500,7 @@ impl Readable for Result { port: Readable::read(reader)?, })) }, - 3 => { - Ok(Ok(NetAddress::OnionV2 { - addr: Readable::read(reader)?, - port: Readable::read(reader)?, - })) - }, + 3 => Ok(Ok(NetAddress::OnionV2(Readable::read(reader)?))), 4 => { Ok(Ok(NetAddress::OnionV3 { ed25519_pubkey: Readable::read(reader)?, @@ -715,10 +724,23 @@ pub enum ErrorAction { /// The peer did something harmless that we weren't able to meaningfully process. /// If the error is logged, log it at the given level. IgnoreAndLog(logger::Level), + /// The peer provided us with a gossip message which we'd already seen. In most cases this + /// should be ignored, but it may result in the message being forwarded if it is a duplicate of + /// our own channel announcements. + IgnoreDuplicateGossip, /// The peer did something incorrect. Tell them. SendErrorMessage { /// The message to send. - msg: ErrorMessage + msg: ErrorMessage, + }, + /// The peer did something incorrect. Tell them without closing any channels. + SendWarningMessage { + /// The message to send. + msg: WarningMessage, + /// The peer may have done something harmless that we weren't able to meaningfully process, + /// though we should still tell them about it. + /// If this event is logged, log it at the given level. + log_level: logger::Level, }, } @@ -1519,6 +1541,32 @@ impl Readable for ErrorMessage { } } +impl Writeable for WarningMessage { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + self.channel_id.write(w)?; + (self.data.len() as u16).write(w)?; + w.write_all(self.data.as_bytes())?; + Ok(()) + } +} + +impl Readable for WarningMessage { + fn read(r: &mut R) -> Result { + Ok(Self { + channel_id: Readable::read(r)?, + data: { + let mut sz: usize = ::read(r)? as usize; + let data = read_to_end(r)?; + sz = cmp::min(data.len(), sz); + match String::from_utf8(data[..sz as usize].to_vec()) { + Ok(s) => s, + Err(_) => return Err(DecodeError::InvalidValue), + } + } + }) + } +} + impl Writeable for UnsignedNodeAnnouncement { fn write(&self, w: &mut W) -> Result<(), io::Error> { self.features.write(w)?; @@ -1922,10 +1970,9 @@ mod tests { }); } if onionv2 { - addresses.push(msgs::NetAddress::OnionV2 { - addr: [255, 254, 253, 252, 251, 250, 249, 248, 247, 246], - port: 9735 - }); + addresses.push(msgs::NetAddress::OnionV2( + [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 38, 7] + )); } if onionv3 { addresses.push(msgs::NetAddress::OnionV3 { @@ -2410,6 +2457,17 @@ mod tests { assert_eq!(encoded_value, target_value); } + #[test] + fn encoding_warning() { + let error = msgs::WarningMessage { + channel_id: [2; 32], + data: String::from("rust-lightning"), + }; + let encoded_value = error.encode(); + let target_value = hex::decode("0202020202020202020202020202020202020202020202020202020202020202000e727573742d6c696768746e696e67").unwrap(); + assert_eq!(encoded_value, target_value); + } + #[test] fn encoding_ping() { let ping = msgs::Ping {