ToSocketAddrs giving me every SocketAddr 3 times. Why?

I noticed that whenever I iterate over the socket addresses via a ToSocketAddrs iterator that involves turning names into IP addresses (even "localhost"), I see every socket address three times. Is this intentional? Is this a bug? Where does the redundancy come in? Is it part of the Rust stdlib implementation or does my OS (GNU/Linux) already give me this redundancy?

Try for yourself:

use std::io;
use std::net::ToSocketAddrs;

fn foo<S: ToSocketAddrs>(s: S) -> Result<(), io::Error> {
    for (idx, sockaddr) in (1..).zip(try!(s.to_socket_addrs())) {
        println!("{}. {}", idx, sockaddr);
    }
    Ok(())
}

fn main() {
    match foo("localhost:80") {
        Err(x) => println!("{}", x),
        _ => (),
    }
}

(It won't work in playpen due to some OS API calls being blocked)

Running it on Windows, I get:

1. [::1]:80
2. 127.0.0.1:80

Which means it's either platform-specific, or just a consequence of your configuration.

1 Like

That's interesting. I get

1. 127.0.0.1:80
2. 127.0.0.1:80
3. 127.0.0.1:80

and for google.com I get

1. 173.194.113.142:80
2. 173.194.113.142:80
3. 173.194.113.142:80
4. 173.194.113.134:80
5. 173.194.113.134:80
6. 173.194.113.134:80
...
31. 173.194.113.137:80
32. 173.194.113.137:80
33. 173.194.113.137:80
34. [2a00:1450:4005:808::1009]:80
35. [2a00:1450:4005:808::1009]:80
36. [2a00:1450:4005:808::1009]:80

(every entry 3 times).

I'm running Ubuntu 14.04.2 LTS (3.13.0-57-generic #95-Ubuntu SMP Fri Jun 19 09:28:15 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux).

This is normal behaviour.
to_socket_addrs internally just calls getaddrinfo without hints, which in turn means that it will return resolved addresses for each socket type (SOCK_STREAM, SOCK_DGRAM, SOCK_RAW).
ToSocketAddrs later drops all other information, so Rust could be a bit smarter here and set a SOCK_STREAM hint.