//! call into the provided message handlers (probably a ChannelManager and NetGraphmsgHandler) with messages
//! they should handle, and encoding/sending response messages.
-use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+use bitcoin::secp256k1::{SecretKey,PublicKey};
use ln::features::InitFeatures;
use ln::msgs;
-use ln::msgs::{ChannelMessageHandler, LightningError, RoutingMessageHandler};
+use ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, RoutingMessageHandler};
use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager};
use util::ser::{VecWriter, Writeable, Writer};
use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) ->
Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> { Vec::new() }
fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<msgs::NodeAnnouncement> { Vec::new() }
- fn sync_routing_table(&self, _their_node_id: &PublicKey, _init: &msgs::Init) {}
+ fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init) {}
fn handle_reply_channel_range(&self, _their_node_id: &PublicKey, _msg: msgs::ReplyChannelRange) -> Result<(), LightningError> { Ok(()) }
fn handle_reply_short_channel_ids_end(&self, _their_node_id: &PublicKey, _msg: msgs::ReplyShortChannelIdsEnd) -> Result<(), LightningError> { Ok(()) }
fn handle_query_channel_range(&self, _their_node_id: &PublicKey, _msg: msgs::QueryChannelRange) -> Result<(), LightningError> { Ok(()) }
/// Thus, to avoid needlessly disconnecting a peer, we allow a peer to take this many timer ticks
/// per connected peer to respond to a ping, as long as they send us at least one message during
/// each tick, ensuring we aren't actually just disconnected.
-/// With a timer tick interval of five seconds, this translates to about 30 seconds per connected
+/// With a timer tick interval of ten seconds, this translates to about 40 seconds per connected
/// peer.
///
/// When we improve parallelism somewhat we should reduce this to e.g. this many timer ticks per
/// two connected peers, assuming most LDK-running systems have at least two cores.
-const MAX_BUFFER_DRAIN_TICK_INTERVALS_PER_PEER: i8 = 6;
+const MAX_BUFFER_DRAIN_TICK_INTERVALS_PER_PEER: i8 = 4;
/// This is the minimum number of messages we expect a peer to be able to handle within one timer
/// tick. Once we have sent this many messages since the last ping, we send a ping right away to
channel_encryptor: PeerChannelEncryptor,
their_node_id: Option<PublicKey>,
their_features: Option<InitFeatures>,
+ their_net_address: Option<NetAddress>,
pending_outbound_buffer: LinkedList<Vec<u8>>,
pending_outbound_buffer_first_msg_offset: usize,
/// lifetimes). Other times you can afford a reference, which is more efficient, in which case
/// SimpleRefPeerManager is the more appropriate type. Defining these type aliases prevents
/// issues such as overly long function definitions.
+///
+/// (C-not exported) as Arcs don't make sense in bindings
pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<NetGraphMsgHandler<Arc<NetworkGraph>, Arc<C>, Arc<L>>>, Arc<L>, Arc<IgnoringMessageHandler>>;
/// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference
/// usage of lightning-net-tokio (since tokio::spawn requires parameters with static lifetimes).
/// But if this is not necessary, using a reference is more efficient. Defining these type aliases
/// helps with issues such as long function definitions.
+///
+/// (C-not exported) as Arcs don't make sense in bindings
pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L>, &'e NetGraphMsgHandler<&'g NetworkGraph, &'h C, &'f L>, &'f L, IgnoringMessageHandler>;
/// A PeerManager manages a set of peers, described by their [`SocketDescriptor`] and marshalls
}
}
+/// A function used to filter out local or private addresses
+/// https://www.iana.org./assignments/ipv4-address-space/ipv4-address-space.xhtml
+/// https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
+fn filter_addresses(ip_address: Option<NetAddress>) -> Option<NetAddress> {
+ match ip_address{
+ // For IPv4 range 10.0.0.0 - 10.255.255.255 (10/8)
+ Some(NetAddress::IPv4{addr: [10, _, _, _], port: _}) => None,
+ // For IPv4 range 0.0.0.0 - 0.255.255.255 (0/8)
+ Some(NetAddress::IPv4{addr: [0, _, _, _], port: _}) => None,
+ // For IPv4 range 100.64.0.0 - 100.127.255.255 (100.64/10)
+ Some(NetAddress::IPv4{addr: [100, 64..=127, _, _], port: _}) => None,
+ // For IPv4 range 127.0.0.0 - 127.255.255.255 (127/8)
+ Some(NetAddress::IPv4{addr: [127, _, _, _], port: _}) => None,
+ // For IPv4 range 169.254.0.0 - 169.254.255.255 (169.254/16)
+ Some(NetAddress::IPv4{addr: [169, 254, _, _], port: _}) => None,
+ // For IPv4 range 172.16.0.0 - 172.31.255.255 (172.16/12)
+ Some(NetAddress::IPv4{addr: [172, 16..=31, _, _], port: _}) => None,
+ // For IPv4 range 192.168.0.0 - 192.168.255.255 (192.168/16)
+ Some(NetAddress::IPv4{addr: [192, 168, _, _], port: _}) => None,
+ // For IPv4 range 192.88.99.0 - 192.88.99.255 (192.88.99/24)
+ Some(NetAddress::IPv4{addr: [192, 88, 99, _], port: _}) => None,
+ // For IPv6 range 2000:0000:0000:0000:0000:0000:0000:0000 - 3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff (2000::/3)
+ Some(NetAddress::IPv6{addr: [0x20..=0x3F, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _], port: _}) => ip_address,
+ // For remaining addresses
+ Some(NetAddress::IPv6{addr: _, port: _}) => None,
+ Some(..) => ip_address,
+ None => None,
+ }
+}
+
impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> PeerManager<Descriptor, CM, RM, L, CMH> where
CM::Target: ChannelMessageHandler,
RM::Target: RoutingMessageHandler,
SecretKey::from_slice(&Sha256::from_engine(ephemeral_hash).into_inner()).expect("You broke SHA-256!")
}
- /// Indicates a new outbound connection has been established to a node with the given node_id.
+ /// Indicates a new outbound connection has been established to a node with the given node_id
+ /// and an optional remote network address.
+ ///
+ /// The remote network address adds the option to report a remote IP address back to a connecting
+ /// peer using the init message.
+ /// The user should pass the remote network address of the host they are connected to.
+ ///
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// [`socket_disconnected()`].
///
/// [`socket_disconnected()`]: PeerManager::socket_disconnected
- pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
+ pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor, remote_network_address: Option<NetAddress>) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
let pending_read_buffer = [0; 50].to_vec(); // Noise act two is 50 bytes
channel_encryptor: peer_encryptor,
their_node_id: None,
their_features: None,
+ their_net_address: remote_network_address,
pending_outbound_buffer: LinkedList::new(),
pending_outbound_buffer_first_msg_offset: 0,
Ok(res)
}
- /// Indicates a new inbound connection has been established.
+ /// Indicates a new inbound connection has been established to a node with an optional remote
+ /// network address.
+ ///
+ /// The remote network address adds the option to report a remote IP address back to a connecting
+ /// peer using the init message.
+ /// The user should pass the remote network address of the host they are connected to.
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// [`socket_disconnected()`].
///
/// [`socket_disconnected()`]: PeerManager::socket_disconnected
- pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
+ pub fn new_inbound_connection(&self, descriptor: Descriptor, remote_network_address: Option<NetAddress>) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
channel_encryptor: peer_encryptor,
their_node_id: None,
their_features: None,
+ their_net_address: remote_network_address,
pending_outbound_buffer: LinkedList::new(),
pending_outbound_buffer_first_msg_offset: 0,
self.enqueue_message(peer, &msg);
continue;
},
+ msgs::ErrorAction::SendWarningMessage { msg, log_level } => {
+ log_given_level!(self.logger, log_level, "Error handling message{}; sending warning message with: {}", OptionalFromDebugger(&peer.their_node_id), e.err);
+ self.enqueue_message(peer, &msg);
+ continue;
+ },
}
}
}
peer.their_node_id = Some(their_node_id);
insert_node_id!();
let features = InitFeatures::known();
- let resp = msgs::Init { features };
+ let resp = msgs::Init { features, remote_network_address: filter_addresses(peer.their_net_address.clone())};
self.enqueue_message(peer, &resp);
peer.awaiting_pong_timer_tick_intervals = 0;
},
peer.their_node_id = Some(their_node_id);
insert_node_id!();
let features = InitFeatures::known();
- let resp = msgs::Init { features };
+ let resp = msgs::Init { features, remote_network_address: filter_addresses(peer.their_net_address.clone())};
self.enqueue_message(peer, &resp);
peer.awaiting_pong_timer_tick_intervals = 0;
},
Ok(x) => x,
Err(e) => {
match e {
- msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }),
- msgs::DecodeError::UnknownRequiredFeature => {
+ // Note that to avoid recursion we never call
+ // `do_attempt_write_data` from here, causing
+ // the messages enqueued here to not actually
+ // be sent before the peer is disconnected.
+ (msgs::DecodeError::UnknownRequiredFeature, Some(ty)) if is_gossip_msg(ty) => {
log_gossip!(self.logger, "Got a channel/node announcement with an unknown required feature flag, you may want to update!");
continue;
}
- msgs::DecodeError::InvalidValue => {
+ (msgs::DecodeError::UnsupportedCompression, _) => {
+ log_gossip!(self.logger, "We don't support zlib-compressed message fields, sending a warning and ignoring message");
+ self.enqueue_message(peer, &msgs::WarningMessage { channel_id: [0; 32], data: "Unsupported message compression: zlib".to_owned() });
+ continue;
+ }
+ (_, Some(ty)) if is_gossip_msg(ty) => {
+ log_gossip!(self.logger, "Got an invalid value while deserializing a gossip message");
+ self.enqueue_message(peer, &msgs::WarningMessage { channel_id: [0; 32], data: "Unreadable/bogus gossip message".to_owned() });
+ continue;
+ }
+ (msgs::DecodeError::UnknownRequiredFeature, ty) => {
+ log_gossip!(self.logger, "Received a message with an unknown required feature flag or TLV, you may want to update!");
+ self.enqueue_message(peer, &msgs::WarningMessage { channel_id: [0; 32], data: format!("Received an unknown required feature/TLV in message type {:?}", ty) });
+ return Err(PeerHandleError { no_connection_possible: false });
+ }
+ (msgs::DecodeError::UnknownVersion, _) => return Err(PeerHandleError { no_connection_possible: false }),
+ (msgs::DecodeError::InvalidValue, _) => {
log_debug!(self.logger, "Got an invalid value while deserializing message");
return Err(PeerHandleError { no_connection_possible: false });
}
- msgs::DecodeError::ShortRead => {
+ (msgs::DecodeError::ShortRead, _) => {
log_debug!(self.logger, "Deserialization failed due to shortness of message");
return Err(PeerHandleError { no_connection_possible: false });
}
- msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }),
- msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }),
- msgs::DecodeError::UnsupportedCompression => {
- log_gossip!(self.logger, "We don't support zlib-compressed message fields, ignoring message");
- continue;
- }
+ (msgs::DecodeError::BadLengthDescriptor, _) => return Err(PeerHandleError { no_connection_possible: false }),
+ (msgs::DecodeError::Io(_), _) => return Err(PeerHandleError { no_connection_possible: false }),
}
}
};
return Err(PeerHandleError{ no_connection_possible: true }.into());
}
- self.message_handler.route_handler.sync_routing_table(&peer.their_node_id.unwrap(), &msg);
+ self.message_handler.route_handler.peer_connected(&peer.their_node_id.unwrap(), &msg);
self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg);
peer.their_features = Some(msg.features);
return Err(PeerHandleError{ no_connection_possible: true }.into());
}
},
+ wire::Message::Warning(msg) => {
+ let mut data_is_printable = true;
+ for b in msg.data.bytes() {
+ if b < 32 || b > 126 {
+ data_is_printable = false;
+ break;
+ }
+ }
+
+ if data_is_printable {
+ log_debug!(self.logger, "Got warning message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data);
+ } else {
+ log_debug!(self.logger, "Got warning message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap()));
+ }
+ },
wire::Message::Ping(msg) => {
if msg.ponglen < 65532 {
msg.data);
self.enqueue_message(get_peer_for_forwarding!(node_id), msg);
},
+ msgs::ErrorAction::SendWarningMessage { ref msg, ref log_level } => {
+ log_given_level!(self.logger, *log_level, "Handling SendWarningMessage HandleError event in peer_handler for node {} with message {}",
+ log_pubkey!(node_id),
+ msg.data);
+ self.enqueue_message(get_peer_for_forwarding!(node_id), msg);
+ },
}
},
MessageSendEvent::SendChannelRangeQuery { ref node_id, ref msg } => {
msg.sync_complete);
self.enqueue_message(get_peer_for_forwarding!(node_id), msg);
}
+ MessageSendEvent::SendGossipTimestampFilter { ref node_id, ref msg } => {
+ self.enqueue_message(get_peer_for_forwarding!(node_id), msg);
+ }
}
}
/// Send pings to each peer and disconnect those which did not respond to the last round of
/// pings.
///
- /// This may be called on any timescale you want, however, roughly once every five to ten
- /// seconds is preferred. The call rate determines both how often we send a ping to our peers
- /// and how much time they have to respond before we disconnect them.
+ /// This may be called on any timescale you want, however, roughly once every ten seconds is
+ /// preferred. The call rate determines both how often we send a ping to our peers and how much
+ /// time they have to respond before we disconnect them.
///
/// May call [`send_data`] on all [`SocketDescriptor`]s. Thus, be very careful with reentrancy
/// issues!
match type_id {
msgs::ChannelAnnouncement::TYPE |
msgs::ChannelUpdate::TYPE |
- msgs::NodeAnnouncement::TYPE => true,
+ msgs::NodeAnnouncement::TYPE |
+ msgs::QueryChannelRange::TYPE |
+ msgs::ReplyChannelRange::TYPE |
+ msgs::QueryShortChannelIds::TYPE |
+ msgs::ReplyShortChannelIdsEnd::TYPE => true,
_ => false
}
}
#[cfg(test)]
mod tests {
- use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler};
+ use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler, filter_addresses};
use ln::msgs;
+ use ln::msgs::NetAddress;
use util::events;
use util::test_utils;
use bitcoin::secp256k1::Secp256k1;
- use bitcoin::secp256k1::key::{SecretKey, PublicKey};
+ use bitcoin::secp256k1::{SecretKey, PublicKey};
use prelude::*;
use sync::{Arc, Mutex};
let a_id = PublicKey::from_secret_key(&secp_ctx, &peer_a.our_node_secret);
let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
let mut fd_b = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
- let initial_data = peer_b.new_outbound_connection(a_id, fd_b.clone()).unwrap();
- peer_a.new_inbound_connection(fd_a.clone()).unwrap();
+ let initial_data = peer_b.new_outbound_connection(a_id, fd_b.clone(), None).unwrap();
+ peer_a.new_inbound_connection(fd_a.clone(), None).unwrap();
assert_eq!(peer_a.read_event(&mut fd_a, &initial_data).unwrap(), false);
peer_a.process_events();
assert_eq!(peer_b.read_event(&mut fd_b, &fd_a.outbound_data.lock().unwrap().split_off(0)).unwrap(), false);
let a_id = PublicKey::from_secret_key(&secp_ctx, &peers[0].our_node_secret);
let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
let mut fd_b = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
- let initial_data = peers[1].new_outbound_connection(a_id, fd_b.clone()).unwrap();
- peers[0].new_inbound_connection(fd_a.clone()).unwrap();
+ let initial_data = peers[1].new_outbound_connection(a_id, fd_b.clone(), None).unwrap();
+ peers[0].new_inbound_connection(fd_a.clone(), None).unwrap();
// If we get a single timer tick before completion, that's fine
assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1);
assert!(peers[0].read_event(&mut fd_a, &fd_b.outbound_data.lock().unwrap().split_off(0)).is_err());
}
+
+ #[test]
+ fn test_filter_addresses(){
+ // Tests the filter_addresses function.
+
+ // For (10/8)
+ let ip_address = NetAddress::IPv4{addr: [10, 0, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [10, 0, 255, 201], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [10, 255, 255, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For (0/8)
+ let ip_address = NetAddress::IPv4{addr: [0, 0, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [0, 0, 255, 187], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [0, 255, 255, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For (100.64/10)
+ let ip_address = NetAddress::IPv4{addr: [100, 64, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [100, 78, 255, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [100, 127, 255, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For (127/8)
+ let ip_address = NetAddress::IPv4{addr: [127, 0, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [127, 65, 73, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [127, 255, 255, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For (169.254/16)
+ let ip_address = NetAddress::IPv4{addr: [169, 254, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [169, 254, 221, 101], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [169, 254, 255, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For (172.16/12)
+ let ip_address = NetAddress::IPv4{addr: [172, 16, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [172, 27, 101, 23], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [172, 31, 255, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For (192.168/16)
+ let ip_address = NetAddress::IPv4{addr: [192, 168, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [192, 168, 205, 159], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [192, 168, 255, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For (192.88.99/24)
+ let ip_address = NetAddress::IPv4{addr: [192, 88, 99, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [192, 88, 99, 140], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv4{addr: [192, 88, 99, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For other IPv4 addresses
+ let ip_address = NetAddress::IPv4{addr: [188, 255, 99, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+ let ip_address = NetAddress::IPv4{addr: [123, 8, 129, 14], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+ let ip_address = NetAddress::IPv4{addr: [2, 88, 9, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+
+ // For (2000::/3)
+ let ip_address = NetAddress::IPv6{addr: [32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+ let ip_address = NetAddress::IPv6{addr: [45, 34, 209, 190, 0, 123, 55, 34, 0, 0, 3, 27, 201, 0, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+ let ip_address = NetAddress::IPv6{addr: [63, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+
+ // For other IPv6 addresses
+ let ip_address = NetAddress::IPv6{addr: [24, 240, 12, 32, 0, 0, 0, 0, 20, 97, 0, 32, 121, 254, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv6{addr: [68, 23, 56, 63, 0, 0, 2, 7, 75, 109, 0, 39, 0, 0, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+ let ip_address = NetAddress::IPv6{addr: [101, 38, 140, 230, 100, 0, 30, 98, 0, 26, 0, 0, 57, 96, 0, 0], port: 1000};
+ assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+ // For (None)
+ assert_eq!(filter_addresses(None), None);
+ }
}