server

Function server 

Source
pub async fn server(
    listen_addr: &str,
    tap_name: &str,
    mac: MacAddress,
    tap_network_address: IPAddress,
    ipv6_filter: bool,
) -> Result<(), Error>
Expand description

Run ethernet p2mp tunnel over ip server.

§Arguments

  • listen_addr - server listen address:port str.
  • tap_name - name of tap interface that will be created.
  • mac - tap interface mac.
  • tap_network_address - tap interface ip network.
  • ipv6_filter - filter any ipv6 packet at tap interface input path (mainly for unit/doc test purpose)

§Example

use std::net::SocketAddr;
use std::str::FromStr;
use std::time::Duration;

use tokio::runtime::Runtime;
use tokio::time::sleep;
use tokio::net::UdpSocket;

use eui48::MacAddress;
use ipaddress;

use hex;
use nom::{AsBytes, HexDisplay};

use acton::linuxinterface::raw_interface;
use acton::{control, server};
Runtime::new().unwrap().block_on(async {
    let tap_name = "tap-server1";
 
    // start server
    tokio::spawn(async move {
        server::server(
            "127.0.0.1:8080",
            tap_name.clone(),
            MacAddress::from_str("00:01:02:03:04:51").unwrap(),
            ipaddress::ipv4::new("1.2.3.1/24").unwrap(),
            true,
        ).await.unwrap();
    });
 
    // wait for server running...
    sleep(Duration::from_secs(1)).await;
 
    // bind raw interface for tap interface input/output validation
    let (_interface, port_tx, mut port_rx) = raw_interface(tap_name.clone(), true);
 
 
    const NUM_OF_CLIENTS: usize = 100;
 
    let ref mut client_sockets: Vec<UdpSocket> = Vec::new();
 
    //
    // clients -> server: session creation & unicast path check
    //
    println!("[Client to Server path check]");
    let ref mut sent_packets: Vec<bytes::Bytes> = Vec::new();
 
    // client session emulation
    for i in 0..NUM_OF_CLIENTS {
        let remote_addr = "127.0.0.1:8080".parse::<SocketAddr>().unwrap();
        let local_addr = "0.0.0.0:0".parse::<SocketAddr>().unwrap();
 
        let socket = UdpSocket::bind(local_addr).await.unwrap();
        socket.connect(&remote_addr).await.unwrap();
 
        /// the hello packet for client session creation on server
        socket.send(control::HELLO_PACKET).await.unwrap();
 
        client_sockets.push(socket);
    }
 
    // clients -> server: unicast packet sent
    for i in 0..NUM_OF_CLIENTS {
        let packet = hex::decode(format!("0001223344550001aabb{:04x}1234c0ff", i)).unwrap();
        let packet = bytes::Bytes::from(packet);
 
        client_sockets[i].send(packet.clone().as_bytes()).await.unwrap();
        println!("CLIENT TX packet{}:\n{}", i, packet.to_hex(16));
 
        sent_packets.push(packet);
    }
 
    // validate unicast packet arrival @ server
    for i in 0..NUM_OF_CLIENTS {
        let packet = port_rx.recv().await.unwrap();
 
        assert_eq!(packet, sent_packets[i]);
 
        println!("SERVER RX packet{}:\n{}", i, packet.to_hex(16));
    }
 
    //
    // server -> clients: broadcast path check
    //
    println!("[Server to client broadcast path check]");
    let broadcast_packet = hex::decode("ffffffffffff0001aaaaaaff4321c0ff").unwrap();
    let broadcast_packet = bytes::Bytes::from(broadcast_packet);
    let _ = port_tx.send(broadcast_packet.clone()).await;
 
    println!("sent broadcast packet to clients:\n{}", broadcast_packet.to_hex(16));
 
    /// check if broadcast packet arrives at each client?
    let mut buf = [0u8; 2000];
    for i in 0..NUM_OF_CLIENTS {
        let n = client_sockets[i].recv(&mut buf).await.unwrap();
        let packet = &buf[0..n];
 
        assert_eq!(packet, broadcast_packet);
 
        println!("CLIENT RX broadcast packet{}:\n{}", i, packet.to_hex(16));
    }
 
    //
    // server -> clients: unknown destination mac fooding to all clients
    //
    println!("[Server to client broadcast path check]");
    let unknown_mac_packet = hex::decode("000111aa22bb0001aaaaaaff4321c0ff").unwrap();
    let broadcast_packet = bytes::Bytes::from(unknown_mac_packet);
    let _ = port_tx.send(broadcast_packet.clone()).await;
 
    println!("sent broadcast packet to clients:\n{}", broadcast_packet.to_hex(16));
 
    // check if broadcast packet arrives at each client?
    let mut buf = [0u8; 2000];
    for i in 0..NUM_OF_CLIENTS {
        let n = client_sockets[i].recv(&mut buf).await.unwrap();
        let packet = &buf[0..n];
 
        assert_eq!(packet, broadcast_packet);
 
        println!("CLIENT RX broadcast packet{}:\n{}", i, packet.to_hex(16));
    }
 
    //
    // server -> clients: unicast path check
    //
    println!("[Server to client unicast path check]");
    let ref mut sent_packets: Vec<bytes::Bytes> = Vec::new();
 
    // server -> clients: unicast packet sent
    for i in 0..NUM_OF_CLIENTS {
        let unicast_packet = hex::decode(format!("0001aabb{:04x}0001aaaaaaff4321c0ff", i)).unwrap();
        let unicast_packet = bytes::Bytes::from(unicast_packet);
 
        let _ = port_tx.send(unicast_packet.clone()).await;
        println!("SERVER TX packet{}:\n{}", i, unicast_packet.to_hex(16));
 
        sent_packets.push(unicast_packet);
    }
 
    // validate if unicast packet sent from server arrives @ each client
    let mut buf = [0u8; 2000];
    for i in 0..NUM_OF_CLIENTS {
        let n = client_sockets[i].recv(&mut buf).await.unwrap();
        let packet = bytes::Bytes::copy_from_slice(&buf[..n]);
 
        assert_eq!(packet, sent_packets[i]);
 
        println!("CLIENT RX packet{}:\n{}", i, packet.to_hex(16));
    }
 
    println!("...done...");
});