diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 110 | 
1 files changed, 104 insertions, 6 deletions
| @@ -1,16 +1,114 @@ +// TODO: logging (dropped errors) +#![allow(unused_must_use)] +use std::{ +    net::{IpAddr, SocketAddr}, +    str::FromStr, +}; + +use tokio::net::TcpStream; +  mod jid; -pub fn add(left: usize, right: usize) -> usize { -    left + right +pub struct Jabber { +    connection: Option<TcpStream>, +    login: jid::JID, +    password: String, +} + +impl Jabber { +    fn new(login: jid::JID, password: String) -> Self { +        Self { +            connection: None, +            login, +            password, +        } +    } +    async fn resolve_client(&self) -> Vec<SocketAddr> { +        let mut socket_addrs = Vec::new(); + +        // if it's a socket/ip then just return that + +        // socket +        if let Ok(socket_addr) = SocketAddr::from_str(&self.login.domainpart) { +            socket_addrs.push(socket_addr); +            return socket_addrs; +        } +        // ip +        if let Ok(ip) = IpAddr::from_str(&self.login.domainpart) { +            socket_addrs.push(SocketAddr::new(ip, 5222)); +            socket_addrs.push(SocketAddr::new(ip, 5223)); +            return socket_addrs; +        } + +        // if port specified return name resolutions with specified port + +        // otherwise resolve +        if let Ok(resolver) = trust_dns_resolver::AsyncResolver::tokio_from_system_conf() { +            if let Ok(lookup) = resolver +                .srv_lookup(format!("_xmpp-client._tcp.{}", self.login.domainpart)) +                .await +            { +                for srv in lookup { +                    resolver +                        .lookup_ip(srv.target().to_owned()) +                        .await +                        .map(|ips| { +                            for ip in ips { +                                socket_addrs.push(SocketAddr::new(ip, srv.port())) +                            } +                        }); +                } +            } +            if let Ok(lookup) = resolver +                .srv_lookup(format!("_xmpps-client._tcp.{}", self.login.domainpart)) +                .await +            { +                for srv in lookup { +                    resolver +                        .lookup_ip(srv.target().to_owned()) +                        .await +                        .map(|ips| { +                            for ip in ips { +                                socket_addrs.push(SocketAddr::new(ip, srv.port())) +                            } +                        }); +                } +            } + +            // in case cannot connect through SRV records +            resolver.lookup_ip(&self.login.domainpart).await.map(|ips| { +                for ip in ips { +                    socket_addrs.push(SocketAddr::new(ip, 5222)); +                    socket_addrs.push(SocketAddr::new(ip, 5223)); +                } +            }); +        } + +        socket_addrs +    } + +    async fn connect(&mut self) { +        for socket_addr in self.resolve_client().await { +            println!("trying {}", socket_addr); +            if let Ok(stream) = TcpStream::connect(socket_addr).await { +                println!("connected to {}", socket_addr); +                self.connection = Some(stream); +                return; +            } +        } +        println!("could not connect") +    }  }  #[cfg(test)]  mod tests { +    use crate::jid::JID; +      use super::*; -    #[test] -    fn it_works() { -        let result = add(2, 2); -        assert_eq!(result, 4); +    #[tokio::test] +    async fn get_sockets() { +        let client = Jabber::new(JID::from_str("cel@blos.sm").unwrap(), "password".to_owned()); +        println!("{:?}", client.resolve_client().await)      }  } | 
