diff options
author | cel 🌸 <cel@blos.sm> | 2023-06-16 14:49:20 +0100 |
---|---|---|
committer | cel 🌸 <cel@blos.sm> | 2023-06-16 14:49:20 +0100 |
commit | bcacf42decf91cbdda6a24a3164717fda46f34cf (patch) | |
tree | cad1d2cf2924b99af3d55de1f8b6355da74b51c7 /src | |
parent | e9c742f4a9bade2020e34e32f3daf021d6c61448 (diff) | |
download | luz-bcacf42decf91cbdda6a24a3164717fda46f34cf.tar.gz luz-bcacf42decf91cbdda6a24a3164717fda46f34cf.tar.bz2 luz-bcacf42decf91cbdda6a24a3164717fda46f34cf.zip |
implement client socket resolution
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) } } |