diff --git a/client/src/main/kotlin/org/hso/texturesyncclient/controller/net/AutoConnect.kt b/client/src/main/kotlin/org/hso/texturesyncclient/controller/net/AutoConnect.kt new file mode 100644 index 0000000..8105c6c --- /dev/null +++ b/client/src/main/kotlin/org/hso/texturesyncclient/controller/net/AutoConnect.kt @@ -0,0 +1,48 @@ +package org.hso.texturesyncclient.controller.net + +import java.io.IOException +import java.lang.Exception +import java.net.DatagramPacket +import java.net.DatagramSocket +import java.net.InetAddress + +class AutoConnect { + private constructor() {} + + companion object { + @Throws(IOException::class) + fun search_server(mulicastAddr: String = "ff02::dd42:c0fe", port: Int = 10796, timeoutMs : Int = 4000): Connection { + val sock = DatagramSocket() + try { + sock.soTimeout = timeoutMs + + val bytes = "TextureSync".toByteArray() + + sock.send( + DatagramPacket( + bytes, + 0, + bytes.size, + InetAddress.getByName(mulicastAddr), + port + ) + ) + + // Response is PortNum in BE + val portData = ByteArray(2) + val response = DatagramPacket(portData, portData.size) + + sock.receive(response) + + // 2-Byte BE to Port Number + val port = (portData[0].toInt().shl(8)).or(portData[1].toInt()) + + return Connection(response.address, port) + } catch ( e : Exception) { + throw e + } finally { + sock.close() + } + } + } +} \ No newline at end of file diff --git a/server/texture-sync-server/src/protocol/autoconnect/mod.rs b/server/texture-sync-server/src/protocol/autoconnect/mod.rs new file mode 100644 index 0000000..34d19de --- /dev/null +++ b/server/texture-sync-server/src/protocol/autoconnect/mod.rs @@ -0,0 +1,45 @@ +use super::ProtocolConfig; + +use std::thread; +use std::net::UdpSocket; +use std::io; +use std::net::SocketAddr; +use std::net::ToSocketAddrs; +use std::net::Ipv6Addr; +use std::str::FromStr; + +pub fn start_autoconnect_server_async(cfg : &ProtocolConfig) -> io::Result<()> { + let cfg = cfg.clone(); + + let multi_sock = UdpSocket::bind((cfg.listen_addr.as_str(), cfg.port))?; + + multi_sock.join_multicast_v6( + &Ipv6Addr::from_str(&cfg.autoconnect_multicastv6_addr).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "Configured IPv6 addr. is invalid."))?, + 0)?; + + thread::spawn(move || { + let mut buffer = vec![0u8; 8096]; + loop { + match multi_sock.recv_from(&mut buffer) { + Ok( (pkg_size, sender)) => { + respond(&multi_sock, &buffer[0..pkg_size], &sender, &cfg); + }, + Err( e ) => { + println!("[Autoconnect] failed with : {:?}", e); + break; + } + } + }; + }); + + Ok(()) +} + +fn respond(sock : &UdpSocket, input : &[u8], sender : &SocketAddr, cfg : &ProtocolConfig) -> io::Result<()> { + if input == b"TextureSync" { + println!("[Autoconnect] Got request from : {}", sender); + sock.send_to(&u16::to_be_bytes(cfg.port), sender)?; + } + + Ok(()) +} \ No newline at end of file