#dns #protocol #protocols

no-std dns-protocol

A DNS protocol implementation in Rust

2 releases

0.1.1 Sep 21, 2022
0.1.0 Sep 12, 2022
Download history 47/week @ 2023-08-02 13/week @ 2023-08-09 14/week @ 2023-08-16 10/week @ 2023-08-23 7/week @ 2023-08-30 17/week @ 2023-09-06 13/week @ 2023-09-13 7/week @ 2023-09-20 13/week @ 2023-09-27 8/week @ 2023-10-04 20/week @ 2023-10-11 25/week @ 2023-10-18 21/week @ 2023-10-25 19/week @ 2023-11-01 18/week @ 2023-11-08 18/week @ 2023-11-15

76 downloads per month
Used in async-dns




This crate provides a no_std implementation of the DNS protocol.

In order to make it trivial for others to build implementations of the DNS protocol, this crate provides a sans-I/O implementation of the protocol. This means that it doesn't provide any I/O functionality, but instead provides a way to parse and serialize DNS messages.

In addition, this crate is not only no_std, but also alloc-free. This means that it can be used in environments where alloc is not available, such as embedded systems. It also has no unsafe code.

However, there is a catch. Since this system does not allocate, the user is responsible for providing a buffer to parse DNS messages into. This means that the user must know the maximum size of a DNS message that they will be parsing. This is a reasonable assumption, since DNS messages are limited to 512 bytes in the common case.


Dual licensed under the MIT and Apache 2.0 licenses.


An implementation of the DNS protocol, sans I/O.

This crate implements the Domain System Protocol, used for namespace lookups among other things. It is intended to be used in conjunction with a transport layer, such as UDP, TCP or HTTPS The goal of this crate is to provide a runtime and protocol-agnostic implementation of the DNS protocol, so that it can be used in a variety of contexts.

This crate is not only no_std, it does not use an allocator as well. This means that it can be used on embedded systems that do not have allocators, and that it does no allocation of its own. However, this comes with a catch: the user is expected to provide their own buffers for the various operations. This is done to avoid the need for an allocator, and to allow the user to control the memory usage of the library.

This crate is also #![forbid(unsafe_code)], and is intended to remain so.


use dns_protocol::{Message, Question, ResourceRecord, ResourceType, Flags};
use std::net::UdpSocket;

// Allocate a buffer for the message.
let mut buf = vec![0; 1024];

// Create a message. This is a query for the A record of example.com.
let mut questions = [
let mut answers = [ResourceRecord::default()];
let message = Message::new(0x42, Flags::default(), &mut questions, &mut answers, &mut [], &mut []);

// Serialize the message into the buffer
assert!(message.space_needed() <= buf.len());
let len = message.write(&mut buf)?;

// Write the buffer to the socket.
let socket = UdpSocket::bind("localhost:0")?;
socket.send_to(&buf[..len], "")?;

// Read new data from the socket.
let data_len = socket.recv(&mut buf)?;

// Parse the data as a message.
let message = Message::read(
    &mut questions,
    &mut answers,
    &mut [],
    &mut [],

// Read the answer from the message.
let answer = message.answers()[0];
println!("Answer Data: {:?}", answer.data());


  • std (enabled by default) - Enables the std library for use in Error types. Disable this feature to use on no_std targets.