diff --git a/src/client/options.rs b/src/client/options.rs index bac3a0c67..6c0aa165a 100644 --- a/src/client/options.rs +++ b/src/client/options.rs @@ -11,7 +11,7 @@ use std::{ convert::TryFrom, fmt::{self, Display, Formatter, Write}, hash::{Hash, Hasher}, - net::Ipv6Addr, + net::{Ipv4Addr, Ipv6Addr}, path::PathBuf, str::FromStr, time::Duration, @@ -277,6 +277,14 @@ impl ServerAddress { .into()); } + let normalized_hostname = if let Ok(v4) = hostname.parse::() { + v4.to_string() + } else if let Ok(v6) = hostname.parse::() { + v6.to_string() + } else { + hostname.to_lowercase() + }; + let port = if let Some(port) = port { match u16::from_str(port) { Ok(0) | Err(_) => { @@ -296,7 +304,7 @@ impl ServerAddress { }; Ok(Self::Tcp { - host: hostname.to_lowercase(), + host: normalized_hostname, port, }) } diff --git a/src/sdam/description/server.rs b/src/sdam/description/server.rs index 87f200589..40a1502dc 100644 --- a/src/sdam/description/server.rs +++ b/src/sdam/description/server.rs @@ -338,7 +338,7 @@ impl ServerDescription { pub(crate) fn invalid_me(&self) -> Result { if let Some(ref reply) = self.reply.as_ref().map_err(Clone::clone)? { if let Some(ref me) = reply.command_response.me { - return Ok(&self.address.to_string() != me); + return Ok(self.address != ServerAddress::parse(me)?); } } diff --git a/src/sdam/test.rs b/src/sdam/test.rs index eedaceb34..abc7c8a99 100644 --- a/src/sdam/test.rs +++ b/src/sdam/test.rs @@ -335,3 +335,27 @@ async fn removed_server_monitor_stops() -> crate::error::Result<()> { Ok(()) } + +#[test] +fn ipv6_invalid_me() { + let addr = ServerAddress::Tcp { + host: "::1".to_string(), + port: Some(8191), + }; + let desc = ServerDescription { + address: addr.clone(), + server_type: super::ServerType::RsSecondary, + last_update_time: None, + average_round_trip_time: None, + reply: Ok(Some(crate::hello::HelloReply { + server_address: addr.clone(), + command_response: crate::hello::HelloCommandResponse { + me: Some("[::1]:8191".to_string()), + ..Default::default() + }, + raw_command_response: bson::RawDocumentBuf::new(), + cluster_time: None, + })), + }; + assert!(!desc.invalid_me().unwrap()); +}