Would I ever receive messages from IPv6 addresses if my socket is bound to a IPv4 address (and vice versa)?

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.

2 Likes

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.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.