@@ -2,7 +2,7 @@ use crate::types::NicType;
2
2
use anyhow:: { Result , anyhow} ;
3
3
use serde:: Deserializer ;
4
4
use serde:: de:: { Unexpected , Visitor } ;
5
- use std:: net:: { IpAddr , Ipv4Addr , Ipv6Addr , SocketAddr } ;
5
+ use std:: net:: { IpAddr , Ipv6Addr } ;
6
6
use std:: os:: fd:: { AsRawFd , FromRawFd , OwnedFd } ;
7
7
use std:: str:: FromStr ;
8
8
@@ -187,11 +187,15 @@ impl Ord for Nic {
187
187
///
188
188
/// Only interfaces matching one of the given names in `filter` will be returned, unless the list
189
189
/// is empty.
190
- pub fn query_nics ( filter : & [ NicFilter ] ) -> Result < Vec < Nic > > {
190
+ pub fn query_nics ( filter : & [ NicFilter ] , use_ipv6 : bool ) -> Result < Vec < Nic > > {
191
191
let mut filtered_nics = vec ! [ ] ;
192
192
193
193
for interface in pnet_datalink:: interfaces ( ) {
194
194
for ip in interface. ips {
195
+ if !use_ipv6 && ip. is_ipv6 ( ) {
196
+ continue ;
197
+ }
198
+
195
199
if let Some ( priority) = nic_priority ( filter, & interface. name , & ip. ip ( ) ) {
196
200
filtered_nics. push ( Nic {
197
201
name : interface. name . clone ( ) ,
@@ -208,17 +212,22 @@ pub fn query_nics(filter: &[NicFilter]) -> Result<Vec<Nic>> {
208
212
Ok ( filtered_nics)
209
213
}
210
214
211
- /// Selects address to bind to for listening: Checks if IPv6 sockets are available on this host
215
+ /// Checks if IPv6 sockets are available on this host
212
216
/// according to our rules: IPv6 must be enabled during boot and at runtime, and IPv6 sockets must
213
- /// be dual stack. Then it returns `::` (IPv6), otherwise `0.0.0.0` (IPv4).
214
- pub fn select_bind_addr ( port : u16 ) -> SocketAddr {
217
+ /// be dual stack.
218
+ pub fn check_ipv6 ( port : u16 , use_ipv6 : bool ) -> bool {
219
+ if !use_ipv6 {
220
+ log:: info!( "IPv6 is disabled by the configuration, falling back to IPv4 sockets" ) ;
221
+ return false ;
222
+ }
223
+
215
224
// SAFETY: Any data used in the libc calls is local only
216
225
unsafe {
217
226
// Check if IPv6 socket can be created
218
227
let sock = libc:: socket ( libc:: AF_INET6 , libc:: SOCK_STREAM , 0 ) ;
219
228
if sock < 0 {
220
229
log:: info!( "IPv6 is unavailable on this host, falling back to IPv4 sockets" ) ;
221
- return SocketAddr :: new ( Ipv4Addr :: UNSPECIFIED . into ( ) , port ) ;
230
+ return false ;
222
231
}
223
232
// Make sure the socket is closed on drop
224
233
let sock = OwnedFd :: from_raw_fd ( sock) ;
@@ -244,7 +253,7 @@ pub fn select_bind_addr(port: u16) -> SocketAddr {
244
253
245
254
if res < 0 && std:: io:: Error :: last_os_error ( ) . raw_os_error ( ) == Some ( libc:: EADDRNOTAVAIL ) {
246
255
log:: info!( "IPv6 is disabled on this host, falling back to IPv4 sockets" ) ;
247
- return SocketAddr :: new ( Ipv4Addr :: UNSPECIFIED . into ( ) , port ) ;
256
+ return false ;
248
257
}
249
258
250
259
// Check if dual stack sockets are enabled by querying the socket option
@@ -263,11 +272,11 @@ pub fn select_bind_addr(port: u16) -> SocketAddr {
263
272
log:: info!(
264
273
"IPv6 dual stack sockets are unavailable on this host, falling back to IPv4 sockets"
265
274
) ;
266
- return SocketAddr :: new ( Ipv4Addr :: UNSPECIFIED . into ( ) , port ) ;
275
+ return false ;
267
276
}
268
277
}
269
278
270
- SocketAddr :: new ( Ipv6Addr :: UNSPECIFIED . into ( ) , port )
279
+ true
271
280
}
272
281
273
282
#[ cfg( test) ]
0 commit comments