Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

Commit

Permalink
dist/tools/vaina: add VAINA client
Browse files Browse the repository at this point in the history
Signed-off-by: Jean Pierre Dudey <[email protected]>
  • Loading branch information
jeandudey committed May 11, 2020
1 parent 603b421 commit 5f5e17a
Show file tree
Hide file tree
Showing 9 changed files with 761 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ targetConfigs/
setenv
.DS_Store
bin/
dist/tools/vaina/target
219 changes: 219 additions & 0 deletions dist/tools/vaina/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions dist/tools/vaina/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "vaina"
version = "0.1.0"
authors = ["Locha Inc"]
edition = "2018"

[dependencies]
clap = { version = "2", features = ["color"] }
bytes = "0.5"
snafu = "0.6"
nix = "0.17"

[patch.crates-io]
nix = { git = "https://github.com/nix-rust/nix" }
79 changes: 79 additions & 0 deletions dist/tools/vaina/src/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::ffi::OsString;
use std::net::{Ipv6Addr, SocketAddr, UdpSocket};
use std::os::unix::io::FromRawFd;
use std::str::FromStr;

use nix::sys::socket::sockopt::{BindToDevice, Ipv6AddMembership};
use nix::sys::socket::{
bind, setsockopt, socket, AddressFamily, InetAddr, Ipv6Addr as NixIpv6Addr,
Ipv6MembershipRequest, SockAddr, SockFlag, SockProtocol, SockType,
};

use snafu::ResultExt;

use crate::msg::Message;
use crate::*;

/// VAINA multicast address
pub const VAINA_MCAST_ADDR: &str = "ff15::42";
pub const VAINA_PORT: u16 = 1337;

#[derive(Debug)]
pub struct VainaClient {
seqno: u8,
pending_acks: Vec<u8>,
sock: UdpSocket,
group: SocketAddr,
}

impl VainaClient {
/// New `VainaClient`
pub fn new(netif: &OsString) -> Result<VainaClient, Error> {
let group = Ipv6Addr::from_str(VAINA_MCAST_ADDR).unwrap();
let stdaddr = SocketAddr::new(group.clone().into(), VAINA_PORT);
let sockaddr = SockAddr::new_inet(InetAddr::from_std(&stdaddr));
let fd = socket(
AddressFamily::Inet6,
SockType::Datagram,
SockFlag::empty(),
SockProtocol::Udp,
)
.context(VainaSocket)?;

setsockopt(fd, BindToDevice, netif).context(VainaSocket)?;
bind(fd, &sockaddr).context(VainaSocket)?;

let group_req = Ipv6MembershipRequest::new(NixIpv6Addr::from_std(&group));
setsockopt(fd, Ipv6AddMembership, &group_req).context(VainaSocket)?;

Ok(VainaClient {
seqno: 0u8,
pending_acks: Vec::new(),
sock: unsafe { UdpSocket::from_raw_fd(fd) },
group: stdaddr,
})
}

/// Craft a new sequence number
pub fn craft_seqno(&mut self) -> u8 {
let seqno = self.seqno;
self.seqno += 1;
seqno
}

/// Send a message
pub fn send_message(&mut self, msg: &Message) -> Result<(), Error> {
// Verify if well wait for an ACK!
if !msg.is_ack() {
self.pending_acks.push(msg.seqno());
}

let bytes = msg.serialize();

self.sock
.send_to(bytes.as_ref(), &self.group)
.context(FailedSend)?;

Ok(())
}
}
Loading

0 comments on commit 5f5e17a

Please sign in to comment.