In nsslib (and possibly other places) we try to influence ip family selection. This is wrong. We should always use getaddrinfo (or one of it's wrappers) and iterate over the address list returned trying to connect the socket. The returned address list is sorted according to what the system networking configuration believes are the preferred selections. We should respect the system network configuration.
Ticket has been cloned to Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=817865
This is a part of the python-nss work.
no, I don't believe this is part of the python-nss work, not if you mean the updates to python-nss. Rather this is improper use of the python-nss API strictly within IPA
Replying to [comment:4 jdennis]:
Ok thanks for correction, sorry for confusion.
I can look at this.
The doc, which can be found here shows correct usage:
http://jdennis.fedorapeople.org/doc/python-nss/api/html/nss.io.AddrInfo-class.html
FWIW, whoever did the first implementation copied code from one of the examples that had a command line arg to force an address family, that's not normal and it shouldn't have been followed.
The idea behind getaddrinfo is that it returns an ordered list of addresses to try. It's ordered by the system according to rules established in the network stack. You're supposed to iterate through the address list in order and attempt to connect to see if the address is valid. If you can connect then use that address, else continue. BTW, this all explained in Steven's UNIX networking book.
Right, when I was looking in Python socket doc and accompanied examples, this was their recommended use.
attachment freeipa-mkosek-283-improve-address-family-handling-in-sockets.patch
Patch freeipa-mkosek-283-improve-address-family-handling-in-sockets.patch sent for review
master: 4879c68
Huh?
try: addr_info = io.AddrInfo(host, family=self.family) except Exception: raise NSPRError(error.PR_ADDRESS_NOT_SUPPORTED_ERROR, "Cannot resolve %s using family %s" % (host, io.addr_family_name(self.family)))
Why are we forcing the family? The whole point of using addr_info is to let it return an ordered list of addresses to attempt.
This is because NSSConnection allows forcing a family:
NSSConnection
class NSSConnection(httplib.HTTPConnection, NSSAddressFamilyFallback): default_port = httplib.HTTPSConnection.default_port def __init__(self, host, port=None, strict=None, dbdir=None, family=socket.AF_UNSPEC, no_init=False): """ :param host: the server to connect to :param port: the port to use (default is set in HTTPConnection) :param dbdir: the NSS database directory :param family: network family to use (default AF_UNSPEC) :param no_init: do not initialize the NSS database. This requires that the database has already been initialized or the request will fail. """ httplib.HTTPConnection.__init__(self, host, port, strict) NSSAddressFamilyFallback.__init__(self, family)
This selection is saved in NSSConnection class and used later in NSSAddressFamilyFallback (your example). However, the family is set by default to socket.AF_UNSPEC, i.e. io.PR_AF_UNSPEC when translated to NSS language.
NSSAddressFamilyFallback
io.PR_AF_UNSPEC
Thus, by default, no forcing should happen. Or am I wrong with this one?
NSSConnection should not offer a family.
The nss.io.AddrInfo class is a wrapper around the familiar getaddrinfo() call. The idea behind getaddrinfo is uses information from the host system configuration to build an ordered list of addresses to try. You're supposed to iterate through the list in order attempting to connect with the supplied address until you successfully connect (usually that will happen on the first try). See Stevens book "UNIX Network Programming" for a more thorough discussion.
The reason we don't want to influence the family selection is we are ignorant of how the host networking is configured. If they prefer IPv6 over IPv4 we should not be subverting their choice. getaddrinfo() also utilizes information it has about routing, available interfaces etc. It attempts to pick the optimal address on the optimal interface for the supplied target address. But it doesn't have perfect information therefore it returns an ordered list of "suggestions" to try. Does this make more sense now?
You may point out that getaddrinfo does provide a mechanism to select only a subset of possible addresses (including the family), but in general that's only for when you have very specific a prori knowledge about your connection requirements. We don't have that knowledge and in general most apps don't, so they should allow getaddrinfo() to do it's job.
closing again, opened new ticket #3443 to cover the issue.
Moving back to appropriate Milestone.
Metadata Update from @jdennis: - Issue assigned to mkosek - Issue set to the milestone: FreeIPA 3.0 Beta 2
Login to comment on this ticket.