Stash
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use tokio::net::UdpSocket;
|
||||
use tracing::debug;
|
||||
use socket2::{Socket, Domain, Type, Protocol};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::topology::DeviceCapabilities;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct DiscoveryMessage {
|
||||
#[serde(rename = "type")]
|
||||
message_type: String,
|
||||
node_id: String,
|
||||
grpc_port: u16,
|
||||
device_capabilities: DeviceCapabilities,
|
||||
priority: u32,
|
||||
interface_name: String,
|
||||
interface_type: String,
|
||||
}
|
||||
|
||||
async fn broadcast(address: SocketAddr) {
|
||||
let socket = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
|
||||
socket.set_broadcast(true).unwrap();
|
||||
socket.set_reuse_address(true).unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
socket.set_reuse_port(true).unwrap();
|
||||
|
||||
socket.bind(&address.into()).unwrap();
|
||||
let udp: UdpSocket = UdpSocket::from_std(socket.into()).unwrap();
|
||||
//
|
||||
// loop {
|
||||
// udp.send_to()
|
||||
// }
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
mod topology;
|
||||
mod orchestration;
|
||||
mod discovery;
|
||||
mod network;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
use network_interface::{Addr, NetworkInterface, NetworkInterfaceConfig};
|
||||
use socket2::{Domain, Protocol, Socket, Type};
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::time::Duration;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::net::UdpSocket;
|
||||
use crate::topology::DeviceCapabilities;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum InterfaceType {
|
||||
ContainerVirtual,
|
||||
Loopback,
|
||||
Thunderbolt,
|
||||
Ethernet,
|
||||
WiFi,
|
||||
ExternalVirtual,
|
||||
Other,
|
||||
}
|
||||
|
||||
impl InterfaceType {
|
||||
fn priority(&self) -> u8 {
|
||||
match self {
|
||||
InterfaceType::ContainerVirtual => 7,
|
||||
InterfaceType::Loopback => 6,
|
||||
InterfaceType::Thunderbolt => 5,
|
||||
InterfaceType::Ethernet => 4,
|
||||
InterfaceType::WiFi => 3,
|
||||
InterfaceType::ExternalVirtual => 1,
|
||||
InterfaceType::Other => 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for InterfaceType {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
InterfaceType::ContainerVirtual => "Container Virtual".to_string(),
|
||||
InterfaceType::Loopback => "Loopback".to_string(),
|
||||
InterfaceType::Thunderbolt => "Thunderbolt".to_string(),
|
||||
InterfaceType::Ethernet => "Ethernet".to_string(),
|
||||
InterfaceType::WiFi => "WiFi".to_string(),
|
||||
InterfaceType::ExternalVirtual => "External Virtual".to_string(),
|
||||
InterfaceType::Other => "Other".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct BroadcastCreationInfo {
|
||||
interface_name: String,
|
||||
interface_type: InterfaceType,
|
||||
|
||||
bind_address: Ipv4Addr,
|
||||
broadcast_address: Ipv4Addr,
|
||||
}
|
||||
|
||||
fn get_broadcast_creation_info() -> Vec<BroadcastCreationInfo> {}
|
||||
|
||||
struct NodeInfo {
|
||||
node_id: String,
|
||||
node_port: u16,
|
||||
device_capabilities: DeviceCapabilities,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct DiscoveryMessage {
|
||||
#[serde(rename = "type")]
|
||||
message_type: String,
|
||||
node_id: String,
|
||||
grpc_port: u16,
|
||||
device_capabilities: DeviceCapabilities,
|
||||
priority: u8,
|
||||
interface_name: String,
|
||||
interface_type: String,
|
||||
}
|
||||
|
||||
async fn listen(broadcast_creation_info: BroadcastCreationInfo, node_info: NodeInfo, broadcast_port: u16, broadcast_interval: Duration) {
|
||||
let socket_addr = SocketAddr::new(
|
||||
IpAddr::V4(broadcast_creation_info.bind_address),
|
||||
0,
|
||||
);
|
||||
|
||||
let socket = bind_to_address(socket_addr);
|
||||
|
||||
let message = serde_json::to_vec(&DiscoveryMessage {
|
||||
message_type: "discovery".to_string(),
|
||||
node_id: node_info.node_id,
|
||||
grpc_port: node_info.node_port,
|
||||
device_capabilities: node_info.device_capabilities,
|
||||
priority: broadcast_creation_info.interface_type.priority(),
|
||||
interface_name: broadcast_creation_info.interface_name,
|
||||
interface_type: broadcast_creation_info.interface_type.to_string(),
|
||||
}).unwrap();
|
||||
|
||||
loop {
|
||||
socket.send_to(
|
||||
&message,
|
||||
SocketAddr::new(IpAddr::V4(broadcast_creation_info.broadcast_address), broadcast_port),
|
||||
).await.unwrap();
|
||||
|
||||
tokio::time::sleep(broadcast_interval).await;
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_to_address(address: SocketAddr) -> UdpSocket {
|
||||
let socket = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
|
||||
socket.set_broadcast(true).unwrap();
|
||||
socket.set_reuse_address(true).unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
socket.set_reuse_port(true).unwrap();
|
||||
|
||||
socket.bind(&address.into()).unwrap();
|
||||
UdpSocket::from_std(socket.into()).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_interfaces() {
|
||||
let raw = NetworkInterface::show().unwrap();
|
||||
let names_and_addrs = raw
|
||||
.iter()
|
||||
.flat_map(|network_interface| {
|
||||
let v4_addrs = network_interface
|
||||
.addr
|
||||
.iter()
|
||||
.filter(|addr: &&Addr| matches!(addr, Addr::V4(..)))
|
||||
.map(|addr: &Addr| (network_interface.name.clone(), *addr));
|
||||
|
||||
v4_addrs
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
Reference in New Issue
Block a user