I'm binding a socket to a SocketAddrV4, but recv_from returns SocketAddr which covers both V4 or V6. So I'm left wondering, is it safe to ignore the V6 case?
use tokio::net::UdpSocket;
use std::{
io,
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
};
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 8080);
let socket = UdpSocket::bind(&addr).await?;
let mut buf = vec![0u8; 1024];
let (_bytes_read, origin) = socket.recv_from(&mut buf).await?;
match origin {
SocketAddr::V4(addr_v4) => {}
SocketAddr::V6(addr_v6) => {/* Will this ever be reached? */}
}
Ok(())
}
A socket bound to an IPv4 address can only receive data from IPv4 hosts, while a socket bound to an IPv6 address can receive from both IPv6 and IPv4 hosts (It's called a dual-stack socket, and it'll depend on socket/OS configuration)
It's better future proofing to use a IPv6 socket and accept legacy IPv4 hosts, than to use a IPv4 socket and block IPv6 hosts. Another option is to use 2 sockets for IPv6 and IPv4 separately and listen to both, but if this is a "toy" app or something simple that's probably overkill.
Thanks for clarifying. I'm writing a crate for a network protocol (BACnet/IP) that works with IPv4 addresses (mainly in LANs). I'll ignore the V6 case then.