[squeak-dev] NetNameResolver/ifconfig/interfaces

John M McIntosh johnmci at smalltalkconsulting.com
Sat Mar 13 20:21:47 UTC 2010


Ok, well I spent the evening looking into this. It's unclear if reverting the new/old socket stuff in Pharo is a good idea,
or if we just adjust things a bit in the name lookup that would solve things. There are two questions to resolve

(1) Do we want to return an IPV4 address from the network lookup? or an IPV6 address? 
(2) What do we do when we have 2 or more active IP interfaces on the machine, prompt for which one to use? Pick one at random, use the first or last one? 

If the community can decide what to do, then we can propose a solution. 

So how it works. 

NetNameResolver localHostAddress

fe80::21c:42ff:fe00:9%en5(otter-2.local),0(0)
 
Gah... what's that? 

Well the interface is:

en5: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
	inet6 fe80::21c:42ff:fe00:9%en5 prefixlen 64 scopeid 0x8 
	inet 10.37.129.2 netmask 0xffffff00 broadcast 10.37.129.255
	ether 00:1c:42:00:00:09 
	media: autoselect status: active
	supported media: autoselect

Thus it's giving me an IPV6 address.

The chore is more complicated that one would care to see. I see Microsoft had a hand in defining the spec. 

So it first asks the gethostname for the name of the host.  As an example my macbook pro has 
Otter-2.local

which is what
[otter-2:~] johnmci% hostname
Otter-2.local

That's a bonjour assigned name since if I do
[otter-2:~] johnmci% nslookup Otter-2.local
Server:		192.168.1.7
Address:	192.168.1.7#53

** server can't find Otter-2.local: NXDOMAIN


Then we are off to: 

getnameinfo

which returns a chain of  IPV4 and IPV6  address that Otter-2.local would resolve to. 
In this case there are six address, broken in to IPV6 and IPV4

fe80::21c:42ff:fe00:8%en4(otter-2.local),0(0)-inet6-stream-tcp 
fe80::21c:42ff:fe00:9%en5(otter-2.local),0(0)-inet6-stream-tcp 
fe80::21b:63ff:fe02:d2db%en1(otter-2.local),0(0)-inet6-stream-tcp 
10.211.55.2(10.211.55.2),0(0)-inet4-stream-tcp 
10.37.129.2(10.37.129.2),0(0)-inet4-stream-tcp 
192.168.1.141(192.168.1.141),0(0)-inet4-stream-tcp

So looks kinda random, but it's not. It's defined by Microsoft & committee etc. in 
http://www.faqs.org/rfcs/rfc3484.html

The objective is to sort the list into some order. I must say you can't actually tell from reading the docs, and things over 
the past decade have changed. So I refer to some cheat sheets that *might* be correct. 

Now the macbook pro in this case uses 192.168.1.141 as the assigned tcp/ip address from our internal DHCP server. 
The 10.211.55.2  is a parallels shared network adaptor and
10.37.129.2 is the parallels host-only network adaptor. 

All three interfaces show as active, and if you consider the 'ifconfig -a'  below you would be hard pressed to determine which interface is the one facing the 
company intranet. 


[otter-2:~] johnmci% ifconfig -a
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	inet 127.0.0.1 netmask 0xff000000 
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 00:17:f2:d9:57:35 
	media: autoselect status: inactive
	supported media: autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 10baseT/UTP <full-duplex,flow-control> 100baseTX <half-duplex> 100baseTX <full-duplex> 100baseTX <full-duplex,hw-loopback> 100baseTX <full-duplex,flow-control> 1000baseT <full-duplex> 1000baseT <full-duplex,hw-loopback> 1000baseT <full-duplex,flow-control> none
fw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 2030
	lladdr 00:19:e3:ff:fe:93:92:7c 
	media: autoselect <full-duplex> status: inactive
	supported media: autoselect <full-duplex>
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	inet6 fe80::21b:63ff:fe02:d2db%en1 prefixlen 64 scopeid 0x6 
	inet 192.168.1.141 netmask 0xffffff00 broadcast 192.168.1.255
	ether 00:1b:63:02:d2:db 
	media: autoselect status: active
	supported media: autoselect
en4: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
	inet6 fe80::21c:42ff:fe00:8%en4 prefixlen 64 scopeid 0x7 
	inet 10.211.55.2 netmask 0xffffff00 broadcast 10.211.55.255
	ether 00:1c:42:00:00:08 
	media: autoselect status: active
	supported media: autoselect
en5: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
	inet6 fe80::21c:42ff:fe00:9%en5 prefixlen 64 scopeid 0x8 
	inet 10.37.129.2 netmask 0xffffff00 broadcast 10.37.129.255
	ether 00:1c:42:00:00:09 
	media: autoselect status: active
	supported media: autoselect


Where en0 is ethernet jack, fw0 is firewire, en1 is wireless, en4 & en5 are virtual. 

Now the bias from the committee is 

precedence  ::1/128       50
precedence  ::/0          40
precedence  2002::/16     30
precedence ::/96          20
precedence ::ffff:0:0/96  10
scopev4 ::ffff:169.254.0.0/112  2
scopev4 ::ffff:127.0.0.0/104    2
scopev4 ::ffff:10.0.0.0/104     5
scopev4 ::ffff:172.16.0.0/108   5
scopev4 ::ffff:192.168.0.0/112  5
scopev4 ::ffff:0.0.0.0/96       14

This means of course the 10.0.0.0 address sorts before the 192.168.0.0 address. How helpful. 

So how do we know *which* is the proper address to use? Well no idea!

However let's see what the API does. 

NetNameResolver class>> addressesForName: hostName
	| adresses |
	adresses := SocketAddressInformation
		forHost: hostName
		service: ''
		flags: 0
		addressFamily:  0
		socketType: SocketAddressInformation socketTypeStream
		protocol: SocketAddressInformation protocolTCP.
	^adresses


Now I can make it return just IPV4 address by doing: 

NetNameResolver class>> addressesForName: hostName
	| adresses |
	adresses := SocketAddressInformation
		forHost: hostName
		service: ''
		flags: 0
		addressFamily:  SocketAddressInformation addressFamilyINET4
		socketType: SocketAddressInformation socketTypeStream
		protocol: SocketAddressInformation protocolTCP.
	^adresses

which then NetNameResolver localHostAddress gives: 
10.37.129.2(10.37.129.2),0(0)

I can also supply a service number string  say SSH  '22' 
that give back 
10.37.129.2(10.37.129.2),22(ssh)
since ssh is binding on all interfaces that's valid. 

Technically the getnameinfo gives back three address but again the code below grabs the first one which according to the rfc3484 is more likely to be the correct answer. 

addressForName: hostName
	"NetNameResolver addressForName: 'impara.de' "
	"NetNameResolver addressForName: 'localhost' "
	"NetNameResolver addressForName: '127.0.0.1' "
	| addresses |
	self useOldNetwork
		ifTrue: [^self oldAddressForName: hostName].
	addresses := self addressesForName: hostName.
	^addresses
		ifEmpty: [nil]
		ifNotEmpty: [addresses first socketAddress]

But grabbing the first one doesn't meet people's expectations of correctness, however we just don't have enough information to decide *what* is correct. 

Now some people say OH let's return the en0 one because that is correct? Really how do you know? 
On my computer en0 is ethernet, but since I'm using wireless then en1 is the correct one. 

Obviously I could look in the list of IPV6 address find the LOWEST en# value, then grab the IPV4 entry.  This would assume I check for the fact that the IPV6
interface has an IPV4 address and the sort order for the IPV6 is the same as for the IPV4.

Gee that sounds ok? 

Well it's not, when for example I tether my MacBook Pro to my iPhone and abuse my privilege to move data over the cellular carrier, ah sorry you USA ATT folks, 
then the interface is: 

en6: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	inet6 fe80::226:8ff:fe72:5aa%en6 prefixlen 64 scopeid 0x9 
	inet 192.168.20.2 netmask 0xffffff00 broadcast 192.168.20.255
	ether 00:26:08:72:05:aa 
	media: 10baseT/UTP status: active
	supported media: 10baseT/UTP


which fails the test that the lowest active en# is the one we want to use. 

10.37.129.2(10.37.129.2),0(0)-inet4-stream-tcp 
10.211.55.2(10.211.55.2),0(0)-inet4-stream-tcp 
192.168.20.2(192.168.20.2),0(0)-inet4-stream-tcp)


So the question is what would the community like to see happen. Well other than hide under a rock and see if the problem goes away... 


On 2010-03-12, at 8:41 AM, Chris Cunnington wrote:

> How is NetNameResolver choosing the interface to return an IP address from? 
> 
> In Cobalt this is a problem. You need the right address to connect to other spaces. Cobalt won't let you enter it by hand, so you are at the mercy of its guessing the correct interface. 
> 
> NetNameResolver localAddressString 
> 
> executed in Workspace produces the IP from my fw0 interface, which is useless. I need it to look at ppp0. 
> 
> Can it be told which interface to look at?
> How does it choose? 
> 
> Chris 
> 

--
===========================================================================
John M. McIntosh <johnmci at smalltalkconsulting.com>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================




-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20100313/3cbc0743/attachment.htm


More information about the Squeak-dev mailing list