views:

794

answers:

6

I'm looking to obtain my own IP Address in order to publish that information in to a Peer-to-Peer network. In POSIX/C we have getaddrinfo(NULL, ...), but this always seems to returns INADDR_ANY or INADDR_LOOPBACK, which is useless to me.

Any suggestions?

A: 

Create a UDP socket, bind() to INADDR_ANY, connect() to some address on the internet, then use getsockname() on the socket to find out what address it was assigned.

Another good solution, if the network's protocol supports it, is to just ask your bootstrapping peers what they think your IP is. This takes care of NATs automatically.

bdonlan
Tried your first method. With a UDP socket, it gives me 0.0.0.0 (INADDR_ANY).I might consider the second method.
Nick
Hmm... might be necessary to use a TCP socket then, I guess...
bdonlan
There are several traps when "ask your bootstrapping peers what they think your IP is". Better to avoid reinventing the wheel and using an existing protocol like STUN.
bortzmeyer
A: 

Did you check ai_next field of returned structure?

getaddrinfo() returns linked list of addresses.

qrdl
"but this always seems to returns INADDR_ANY or INADDR_LOOPBACK"I was traversing the list.. so yes.
Nick
+1  A: 

By public address, you're saying, an address that your application's peers can contact you with. The only full-proof way is to connect to a known "external" peer and have it send your address back to you.

Andy
http://checkip.dyndns.org will always return your current valid external IP address
Chris Thompson
A: 

If you know the name your host, you can use gethostbyname to get the ip address.

chappar
gethostbyname is deprecated for many years (replaced by getaddrinfo). Among its problems, it is IPv4-specific.
bortzmeyer
+4  A: 

One of the problems is that, even if you get the local IP address, the IP address seen by the rest of the Internet may be different, because of the kludge of NAT which is unfortunately very common. Using IPv6 probably will suppress this problem but it may not be an option for you, now.

To get the public IP address, you will need a protocol made for that purpose such as STUN (RFC 5389). There are public STUN servers and already existing STUN clients in C.

All the peer-to-peer programs have similar issues, so learn what others are doing, I strongly recommend reading RFC 5128, "State of Peer-to-Peer (P2P) Communication across Network Address Translators (NATs)".

bortzmeyer
+1  A: 

I'm not trying to make things more complicated though I should point out that a single computer can have several IP addresses. typically each network card will have one.

a more specific way to ask would be "how do I find the IP address that will be used as the source address when I connect to foo.com.org" I like bortzmeyer's answer for this :)

Arthur Ulfeldt