Merge pull request #2019 from embassy-rs/net-hostname
net: add support for dhcp hostname option.
This commit is contained in:
		
							
								
								
									
										7
									
								
								ci.sh
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								ci.sh
									
									
									
									
									
								
							@@ -1,9 +1,12 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
set -euo pipefail
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
export RUSTFLAGS=-Dwarnings
 | 
			
		||||
export DEFMT_LOG=trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info
 | 
			
		||||
if [[ -z "${CARGO_TARGET_DIR}" ]]; then
 | 
			
		||||
    export CARGO_TARGET_DIR=target_ci
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
TARGET=$(rustc -vV | sed -n 's|host: ||p')
 | 
			
		||||
 | 
			
		||||
@@ -36,7 +39,7 @@ cargo batch  \
 | 
			
		||||
    --- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \
 | 
			
		||||
    --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \
 | 
			
		||||
    --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
 | 
			
		||||
    --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \
 | 
			
		||||
    --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly,dhcpv4-hostname \
 | 
			
		||||
    --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
 | 
			
		||||
    --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ieee802154 \
 | 
			
		||||
    --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,medium-ieee802154 \
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ udp = ["smoltcp/socket-udp"]
 | 
			
		||||
tcp = ["smoltcp/socket-tcp"]
 | 
			
		||||
dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"]
 | 
			
		||||
dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"]
 | 
			
		||||
dhcpv4-hostname = ["dhcpv4"]
 | 
			
		||||
proto-ipv4 = ["smoltcp/proto-ipv4"]
 | 
			
		||||
proto-ipv6 = ["smoltcp/proto-ipv6"]
 | 
			
		||||
medium-ethernet = ["smoltcp/medium-ethernet"]
 | 
			
		||||
 
 | 
			
		||||
@@ -56,12 +56,22 @@ const LOCAL_PORT_MIN: u16 = 1025;
 | 
			
		||||
const LOCAL_PORT_MAX: u16 = 65535;
 | 
			
		||||
#[cfg(feature = "dns")]
 | 
			
		||||
const MAX_QUERIES: usize = 4;
 | 
			
		||||
#[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
const MAX_HOSTNAME_LEN: usize = 32;
 | 
			
		||||
 | 
			
		||||
/// Memory resources needed for a network stack.
 | 
			
		||||
pub struct StackResources<const SOCK: usize> {
 | 
			
		||||
    sockets: [SocketStorage<'static>; SOCK],
 | 
			
		||||
    #[cfg(feature = "dns")]
 | 
			
		||||
    queries: [Option<dns::DnsQuery>; MAX_QUERIES],
 | 
			
		||||
    #[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
    hostname: core::cell::UnsafeCell<HostnameResources>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
struct HostnameResources {
 | 
			
		||||
    option: smoltcp::wire::DhcpOption<'static>,
 | 
			
		||||
    data: [u8; MAX_HOSTNAME_LEN],
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const SOCK: usize> StackResources<SOCK> {
 | 
			
		||||
@@ -73,6 +83,11 @@ impl<const SOCK: usize> StackResources<SOCK> {
 | 
			
		||||
            sockets: [SocketStorage::EMPTY; SOCK],
 | 
			
		||||
            #[cfg(feature = "dns")]
 | 
			
		||||
            queries: [INIT; MAX_QUERIES],
 | 
			
		||||
            #[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
            hostname: core::cell::UnsafeCell::new(HostnameResources {
 | 
			
		||||
                option: smoltcp::wire::DhcpOption { kind: 0, data: &[] },
 | 
			
		||||
                data: [0; MAX_HOSTNAME_LEN],
 | 
			
		||||
            }),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -104,6 +119,7 @@ pub struct StaticConfigV6 {
 | 
			
		||||
/// DHCP configuration.
 | 
			
		||||
#[cfg(feature = "dhcpv4")]
 | 
			
		||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
			
		||||
#[non_exhaustive]
 | 
			
		||||
pub struct DhcpConfig {
 | 
			
		||||
    /// Maximum lease duration.
 | 
			
		||||
    ///
 | 
			
		||||
@@ -120,6 +136,9 @@ pub struct DhcpConfig {
 | 
			
		||||
    pub server_port: u16,
 | 
			
		||||
    /// Client port. This is almost always 68. Do not change unless you know what you're doing.
 | 
			
		||||
    pub client_port: u16,
 | 
			
		||||
    /// Our hostname. This will be sent to the DHCP server as Option 12.
 | 
			
		||||
    #[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
    pub hostname: Option<heapless::String<MAX_HOSTNAME_LEN>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "dhcpv4")]
 | 
			
		||||
@@ -131,6 +150,8 @@ impl Default for DhcpConfig {
 | 
			
		||||
            ignore_naks: Default::default(),
 | 
			
		||||
            server_port: smoltcp::wire::DHCP_SERVER_PORT,
 | 
			
		||||
            client_port: smoltcp::wire::DHCP_CLIENT_PORT,
 | 
			
		||||
            #[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
            hostname: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -232,6 +253,8 @@ struct Inner<D: Driver> {
 | 
			
		||||
    dns_socket: SocketHandle,
 | 
			
		||||
    #[cfg(feature = "dns")]
 | 
			
		||||
    dns_waker: WakerRegistration,
 | 
			
		||||
    #[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
    hostname: &'static mut core::cell::UnsafeCell<HostnameResources>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) struct SocketStack {
 | 
			
		||||
@@ -307,6 +330,8 @@ impl<D: Driver> Stack<D> {
 | 
			
		||||
            )),
 | 
			
		||||
            #[cfg(feature = "dns")]
 | 
			
		||||
            dns_waker: WakerRegistration::new(),
 | 
			
		||||
            #[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
            hostname: &mut resources.hostname,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        #[cfg(feature = "proto-ipv4")]
 | 
			
		||||
@@ -673,6 +698,25 @@ impl<D: Driver> Inner<D> {
 | 
			
		||||
                socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp));
 | 
			
		||||
                socket.set_ports(c.server_port, c.client_port);
 | 
			
		||||
                socket.set_retry_config(c.retry_config);
 | 
			
		||||
 | 
			
		||||
                socket.set_outgoing_options(&[]);
 | 
			
		||||
                #[cfg(feature = "dhcpv4-hostname")]
 | 
			
		||||
                if let Some(h) = c.hostname {
 | 
			
		||||
                    // safety: we just did set_outgoing_options([]) so we know the socket is no longer holding a reference.
 | 
			
		||||
                    let hostname = unsafe { &mut *self.hostname.get() };
 | 
			
		||||
 | 
			
		||||
                    // create data
 | 
			
		||||
                    // safety: we know the buffer lives forever, new borrows the StackResources for 'static.
 | 
			
		||||
                    // also we won't modify it until next call to this function.
 | 
			
		||||
                    hostname.data[..h.len()].copy_from_slice(h.as_bytes());
 | 
			
		||||
                    let data: &[u8] = &hostname.data[..h.len()];
 | 
			
		||||
                    let data: &'static [u8] = unsafe { core::mem::transmute(data) };
 | 
			
		||||
 | 
			
		||||
                    // set the option.
 | 
			
		||||
                    hostname.option = smoltcp::wire::DhcpOption { data, kind: 12 };
 | 
			
		||||
                    socket.set_outgoing_options(core::slice::from_ref(&hostname.option));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                socket.reset();
 | 
			
		||||
            }
 | 
			
		||||
            _ => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user