opslag
opslag is an mDNS library that is Sans-IO and no_std.
The library has generic types for parsing/serializing mDNS messages,
but the main functionality is [Server].
[Server] has two functions:
- It advertises a local host/port under a service name.
- It discovers other instances of the same service name.
The idea is that [Server] is used to create multiple nodes on the same
network that discover each other.
Setup
use ;
// Declaration of what I want to advertise via mDNS.
// Expecting at most 4 segments to a DNS label.
let info = new;
// The mDNS server.
// - max 4 queries per request
// - max 4 ansers per response
// - max 4 segments in a DNS label
// - 1 single service to announce
// - max 10 entries for DNS label compression
let mut server: = new;
Sans-IO and time
opslag is Sans-IO. That means sending and receiving data is an external
concern from the library. The [Server] can receive incoming data via
[Input::Packet] and instruct the user of the library to send something
via [Output::Packet].
The same goes for time. opslag has nothing driving time forwards internally.
It has timers that will trigger the periodic broadcast the handled services,
but driving time forwards is done via [Input::Timeout].
Milliseconds
Conceptually when the [Server] is created, it is at time 0. Any [Time]
in [Input::Timeout], moves the internal clock forward. Each [Time] is
a millisecond offset from that time 0.
If we are using std, this is an example of how to create a now()
function that will give us an increasing time from a 0-point.
use Instant;
use ;
// Instant at time 0
let start_time = now;
// Millisecond distance to time 0
let now = ;
let input = Timeout;
The Loop
Below follows an example of how to construct a loop that handles
the IO and time. See examples/myservice.rs for a full working
example.
use ;
use Duration;
use ErrorKind;
use ;
// See above how to declare the server.
let server: = todo!;
// Opening the UdpSocket is out of scope for this doc.
// See examples/myservice.rs for an example of how to do this.
let sock: UdpSocket = todo!;
// See above for a possible now() function.
let now: &dyn Fn = &|| todo!;
// Buffers for receiving packets and writing output into.
let mut packet = vec!;
let mut output = vec!;
// This will be set to the next timeout the server expects below.
let mut next_timeout = now;
// Next input to the server.
let mut input = Timeout;
loop
Multihome support
opslag can handle having services on multiple interfaces. Each service is
declared with an [ip_address][ServiceInfo::ip_address()] and
[netmask][`ServiceInfo::netmask()]. This is how opslag keeps the interfaces
apart. When advertising the local services, or querying for remote services,
it will send one packet for each distinct ip/netmask pair it finds.
When sending a packet, [Cast::Multi] and [Cast::Uni] both contain a
from address. This address is used to determine which socket to send the packet
from. For incoming requests, the ip/netmask pair is used to determine which services
are relevant to consider.
If you want the same service to appear on two separate interfaces/ip, you declare
the same [ServiceInfo] twice, with different ip/netmasks.
License: MIT OR Apache-2.0