Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Check formatting
run: cargo fmt -- --check
run: cargo +stable fmt -- --check
- name: Check linting
run: cargo +stable clippy -- -Dwarnings
31 changes: 15 additions & 16 deletions .github/workflows/zeroconf_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,25 @@ on: [push, pull_request]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v1

- name: Install our MSRV
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.70"
- name: Install our MSRV
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.74"

- name: Compile example
run: cargo build --example register
- name: Compile example
run: cargo build --example register

- name: Install dependencies
run: |
sudo apt-get -y install python3-setuptools python3-wheel
pip3 install --user zeroconf
- name: Install dependencies
run: |
sudo apt-get -y install python3-setuptools python3-wheel
pip3 install --user zeroconf

- name: Test zeroconf
run: |
timeout 5 cargo run --example register &
python3 examples/zeroconf_test.py
- name: Test zeroconf
run: |
timeout 5 cargo run --example register &
python3 examples/zeroconf_test.py
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
name = "libmdns"
version = "0.9.1"
authors = ["Will Stott <willstott101+libmdns@gmail.com>"]

description = "mDNS Responder library for building discoverable LAN services in Rust"
repository = "https://github.com/librespot-org/libmdns"
readme = "README.md"
license = "MIT"
edition = "2018"
rust-version = "1.74"

[dependencies]
byteorder = "1.5"
Expand All @@ -23,7 +23,7 @@ socket2 = { version = "0.5", features = ["all"] }

[dev-dependencies]
env_logger = { version = "0.10.2", default-features = false, features = [
"color",
"humantime",
"auto-color",
"color",
"humantime",
"auto-color",
] }
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ See the [example](https://github.com/librespot-org/libmdns/blob/stable-0.9.x/exa

## Dependencies

libmdns' oldest supported Rust toolchain is `1.70.0`, _however it may compile fine on older versions of rust._
libmdns' MSRV (oldest supported Rust toolchain) is 1.74.0.

**We hold no strong garantees for sticking to a Minimum Supported Rust Version**. Please open an issue on GitHub if you need support for older compilers or different platforms.

Expand Down
9 changes: 2 additions & 7 deletions examples/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@ pub fn main() {
builder.parse_filters("libmdns=debug");
builder.init();

let responder = libmdns::Responder::new().unwrap();
let _svc = responder.register(
"_http._tcp".to_owned(),
"libmdns Web Server".to_owned(),
80,
&["path=/"],
);
let responder = libmdns::Responder::new();
let _svc = responder.register("_http._tcp", "libmdns Web Server", 80, &["path=/"]);

loop {
::std::thread::sleep(::std::time::Duration::from_secs(10));
Expand Down
7 changes: 1 addition & 6 deletions examples/register_with_ip_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ pub fn main() {
];

let responder = libmdns::Responder::new_with_ip_list(vec).unwrap();
let _svc = responder.register(
"_http._tcp".to_owned(),
"libmdns Web Server".to_owned(),
80,
&["path=/"],
);
let _svc = responder.register("_http._tcp", "libmdns Web Server", 80, &["path=/"]);

loop {
::std::thread::sleep(::std::time::Duration::from_secs(10));
Expand Down
36 changes: 21 additions & 15 deletions src/dns_parser/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl Builder<Questions> {
pub fn new_query(id: u16, recursion: bool) -> Builder<Questions> {
let mut buf = Vec::with_capacity(512);
let head = Header {
id: id,
id,
query: true,
opcode: Opcode::StandardQuery,
authoritative: false,
Expand All @@ -57,7 +57,7 @@ impl Builder<Questions> {
buf.extend([0u8; 12].iter());
head.write(&mut buf[..12]);
Builder {
buf: buf,
buf,
max_size: Some(512),
_state: PhantomData,
}
Expand All @@ -66,10 +66,10 @@ impl Builder<Questions> {
pub fn new_response(id: u16, recursion: bool, authoritative: bool) -> Builder<Questions> {
let mut buf = Vec::with_capacity(512);
let head = Header {
id: id,
id,
query: false,
opcode: Opcode::StandardQuery,
authoritative: authoritative,
authoritative,
truncated: false,
recursion_desired: recursion,
recursion_available: false,
Expand All @@ -82,15 +82,15 @@ impl Builder<Questions> {
buf.extend([0u8; 12].iter());
head.write(&mut buf[..12]);
Builder {
buf: buf,
buf,
max_size: Some(512),
_state: PhantomData,
}
}
}

impl<T> Builder<T> {
fn write_rr(&mut self, name: &Name, cls: QueryClass, ttl: u32, data: &RRData) {
fn write_rr(&mut self, name: &Name<'_>, cls: QueryClass, ttl: u32, data: &RRData<'_>) {
name.write_to(&mut self.buf).unwrap();
self.buf.write_u16::<BigEndian>(data.typ() as u16).unwrap();
self.buf.write_u16::<BigEndian>(cls as u16).unwrap();
Expand All @@ -103,6 +103,12 @@ impl<T> Builder<T> {
data.write_to(&mut self.buf).unwrap();
let data_size = self.buf.len() - data_offset;

assert!(
(data_offset <= 65535),
"{} is too long to write to a RR record",
data_offset
);
#[allow(clippy::cast_possible_truncation)]
BigEndian::write_u16(
&mut self.buf[size_offset..size_offset + 2],
data_size as u16,
Expand Down Expand Up @@ -166,7 +172,7 @@ impl<T: MoveTo<Questions>> Builder<T> {
#[allow(dead_code)]
pub fn add_question(
self,
qname: &Name,
qname: &Name<'_>,
qtype: QueryType,
qclass: QueryClass,
) -> Builder<Questions> {
Expand All @@ -183,10 +189,10 @@ impl<T: MoveTo<Questions>> Builder<T> {
impl<T: MoveTo<Answers>> Builder<T> {
pub fn add_answer(
self,
name: &Name,
name: &Name<'_>,
cls: QueryClass,
ttl: u32,
data: &RRData,
data: &RRData<'_>,
) -> Builder<Answers> {
let mut builder = self.move_to::<Answers>();

Expand All @@ -201,10 +207,10 @@ impl<T: MoveTo<Nameservers>> Builder<T> {
#[allow(dead_code)]
pub fn add_nameserver(
self,
name: &Name,
name: &Name<'_>,
cls: QueryClass,
ttl: u32,
data: &RRData,
data: &RRData<'_>,
) -> Builder<Nameservers> {
let mut builder = self.move_to::<Nameservers>();

Expand All @@ -219,10 +225,10 @@ impl Builder<Additional> {
#[allow(dead_code)]
pub fn add_additional(
self,
name: &Name,
name: &Name<'_>,
cls: QueryClass,
ttl: u32,
data: &RRData,
data: &RRData<'_>,
) -> Builder<Additional> {
let mut builder = self.move_to::<Additional>();

Expand All @@ -243,7 +249,7 @@ mod test {
#[test]
fn build_query() {
let mut bld = Builder::new_query(1573, true);
let name = Name::from_str("example.com").unwrap();
let name = Name::from_str("example.com");
bld = bld.add_question(&name, QT::A, QC::IN);
let result = b"\x06%\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\
\x07example\x03com\x00\x00\x01\x00\x01";
Expand All @@ -253,7 +259,7 @@ mod test {
#[test]
fn build_srv_query() {
let mut bld = Builder::new_query(23513, true);
let name = Name::from_str("_xmpp-server._tcp.gmail.com").unwrap();
let name = Name::from_str("_xmpp-server._tcp.gmail.com");
bld = bld.add_question(&name, QT::SRV, QC::IN);
let result = b"[\xd9\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\
\x0c_xmpp-server\x04_tcp\x05gmail\x03com\x00\x00!\x00\x01";
Expand Down
40 changes: 26 additions & 14 deletions src/dns_parser/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::Error;
///
/// All "EXPERIMENTAL" markers here are from the RFC
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[allow(clippy::upper_case_acronyms)]
pub enum Type {
/// a host addresss
A = 1,
Expand Down Expand Up @@ -55,6 +56,7 @@ pub enum Type {
///
/// All "EXPERIMENTAL" markers here are from the RFC
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[allow(clippy::upper_case_acronyms)]
pub enum QueryType {
/// a host addresss
A = 1,
Expand Down Expand Up @@ -153,7 +155,7 @@ pub enum ResponseCode {

impl From<u16> for Opcode {
fn from(code: u16) -> Opcode {
use self::Opcode::*;
use self::Opcode::{InverseQuery, Reserved, ServerStatusRequest, StandardQuery};
match code {
0 => StandardQuery,
1 => InverseQuery,
Expand All @@ -162,10 +164,10 @@ impl From<u16> for Opcode {
}
}
}
impl Into<u16> for Opcode {
fn into(self) -> u16 {
use self::Opcode::*;
match self {
impl From<Opcode> for u16 {
fn from(val: Opcode) -> Self {
use self::Opcode::{InverseQuery, Reserved, ServerStatusRequest, StandardQuery};
match val {
StandardQuery => 0,
InverseQuery => 1,
ServerStatusRequest => 2,
Expand All @@ -176,7 +178,9 @@ impl Into<u16> for Opcode {

impl From<u8> for ResponseCode {
fn from(code: u8) -> ResponseCode {
use self::ResponseCode::*;
use self::ResponseCode::{
FormatError, NameError, NoError, NotImplemented, Refused, Reserved, ServerFailure,
};
match code {
0 => NoError,
1 => FormatError,
Expand All @@ -189,10 +193,12 @@ impl From<u8> for ResponseCode {
}
}
}
impl Into<u8> for ResponseCode {
fn into(self) -> u8 {
use self::ResponseCode::*;
match self {
impl From<ResponseCode> for u8 {
fn from(val: ResponseCode) -> Self {
use self::ResponseCode::{
FormatError, NameError, NoError, NotImplemented, Refused, Reserved, ServerFailure,
};
match val {
NoError => 0,
FormatError => 1,
ServerFailure => 2,
Expand All @@ -206,7 +212,10 @@ impl Into<u8> for ResponseCode {

impl QueryType {
pub fn parse(code: u16) -> Result<QueryType, Error> {
use self::QueryType::*;
use self::QueryType::{
All, A, AAAA, AXFR, CNAME, HINFO, MAILA, MAILB, MB, MF, MG, MINFO, MR, MX, NS, NULL,
PTR, SOA, SRV, TXT, WKS,
};
match code {
1 => Ok(A),
2 => Ok(NS),
Expand Down Expand Up @@ -236,7 +245,7 @@ impl QueryType {

impl QueryClass {
pub fn parse(code: u16) -> Result<QueryClass, Error> {
use self::QueryClass::*;
use self::QueryClass::{Any, CH, CS, HS, IN};
match code {
1 => Ok(IN),
2 => Ok(CS),
Expand All @@ -250,7 +259,10 @@ impl QueryClass {

impl Type {
pub fn parse(code: u16) -> Result<Type, Error> {
use self::Type::*;
use self::Type::{
A, AAAA, CNAME, DNSKEY, DS, HINFO, MB, MF, MG, MINFO, MR, MX, NS, NSEC, NULL, OPT, PTR,
RRSIG, SOA, SRV, TXT, WKS,
};
match code {
1 => Ok(A),
2 => Ok(NS),
Expand Down Expand Up @@ -281,7 +293,7 @@ impl Type {

impl Class {
pub fn parse(code: u16) -> Result<Class, Error> {
use self::Class::*;
use self::Class::{CH, CS, HS, IN};
match code {
1 => Ok(IN),
2 => Ok(CS),
Expand Down
2 changes: 2 additions & 0 deletions src/dns_parser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ pub enum Error {
LabelIsNotAscii,
#[error("parser is in the wrong state")]
WrongState,
#[error("label length exceeds maximum allowed size")]
LabelTooLong,
}
9 changes: 4 additions & 5 deletions src/dns_parser/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod flag {

/// Represents parsed header of the packet
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(clippy::struct_excessive_bools)]
pub struct Header {
pub id: u16,
pub query: bool,
Expand Down Expand Up @@ -61,12 +62,10 @@ impl Header {
///
/// When buffer size is not exactly 12 bytes
pub fn write(&self, data: &mut [u8]) {
if data.len() != 12 {
panic!("Header size is exactly 12 bytes");
}
assert_eq!(data.len(), 12, "Header size is exactly 12 bytes");
let mut flags = 0u16;
flags |= Into::<u16>::into(self.opcode) << flag::OPCODE_MASK.trailing_zeros();
flags |= Into::<u8>::into(self.response_code) as u16;
flags |= u16::from(self.opcode) << flag::OPCODE_MASK.trailing_zeros();
flags |= u16::from(u8::from(self.response_code));
if !self.query {
flags |= flag::QUERY;
}
Expand Down
2 changes: 1 addition & 1 deletion src/dns_parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ pub use self::header::Header;
mod rrdata;
pub use self::rrdata::RRData;
mod builder;
pub use self::builder::{Answers, Builder, Questions};
pub use self::builder::{Answers, Builder};
Loading