Bug 798512

Summary: getaddrinfo() with hints.ai_family = AF_UNSPEC changes behavior in glibc
Product: Red Hat Enterprise Linux 6 Reporter: Hangbin Liu <haliu>
Component: glibcAssignee: Jeff Law <law>
Status: CLOSED NOTABUG QA Contact: qe-baseos-tools-bugs
Severity: medium Docs Contact:
Priority: medium    
Version: 6.3CC: fweimer, mfranc
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-03-01 07:07:22 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Hangbin Liu 2012-02-29 05:58:17 UTC
Description of problem:
When use getaddrinfo to write ipv4/ipv6 programs, res->ai_family should be set to zero if hints.ai_family = AF_UNSPEC and host set to NULL

Version-Release number of selected component (if applicable):
glibc-2.12

How reproducible:
every time

Steps to Reproduce:

reproducer : 
#include	<stdio.h> 
#include	<sys/socket.h> 
#include	<sys/types.h> 
#include	<string.h> 
#include	<netdb.h>
#include	<errno.h>
#include	<stdlib.h>

int main(int argc, char** argv)
{
	int errno;
	struct addrinfo hints, *res;
	
	bzero(&hints, sizeof(struct addrinfo));
	hints.ai_family = PF_UNSPEC;    /* Allow IPv4 or IPv6 */
	hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
	hints.ai_flags = AI_PASSIVE;    /* For wildcard IP address */
	hints.ai_protocol = 0;          /* Any protocol */
	hints.ai_canonname = NULL;
	hints.ai_addr = NULL;
	hints.ai_next = NULL;

	if ((errno = getaddrinfo(NULL, "12345", &hints, &res)) != 0) {
			printf("getaddrinfo error %s\n", gai_strerror(errno));
			exit(1);
	}

	printf("family type is %d\n", res->ai_family);
	
	freeaddrinfo(res);
	return 0;
}

  
Actual results:
family type is 2

Expected results:
family type is 3

Additional info:

Comment 1 Hangbin Liu 2012-02-29 06:00:34 UTC
Sorry, Expected results should be :
family type is 0

Comment 2 Jeff Law 2012-03-01 07:07:22 UTC
What makes you think the family type for the result should be zero?

The result is going to be a linked list of addrinfo structures.  Some of those addrinfo structures will be suitable for IPV4, others for IPV6.  Those suitable for IPV4 will the IPV4 family (2); those suitable for IPV6 will have the IPV6 family (10).

If you put a breakpoint after the call to getaddrinfo you can look at the linked list of structures:

(gdb) p *res
$1 = {ai_flags = 1, ai_family = 2, ai_socktype = 1, ai_protocol = 6, ai_addrlen = 16, ai_addr = 0x6010a0, ai_canonname = 0x0, ai_next = 0x601010}
(gdb) p *res->ai_next
$2 = {ai_flags = 1, ai_family = 10, ai_socktype = 1, ai_protocol = 6, ai_addrlen = 28, ai_addr = 0x601040, ai_canonname = 0x0, ai_next = 0x0}

The first one is the AF_INET addrinfo structure, the second is the AF_INET6 addrinfo structure.

This implementation is rfc3493 compliant as far as I know.  If you disagree, can you please be more specific about why you think getaddrinfo should be returning AF_UNSPEC values?

Comment 3 Hangbin Liu 2012-03-02 03:38:13 UTC
It turned out what I thought was wrong. 

I thought this function will create a list which ai_family = 0, then we can create a socket by socket(res->ai_family, res->ai_socktype,0), which can handle both IPv4 and IPv6 connections. Now I known we can't create socket with family = 0 ....

But if we set hints.ai_family = PF_UNSPEC and got a linked list with family equal to 2 and 10, then we have to create 2 sockets to handle IPv4/IPv6 connections. I can't see the difference with 2 programs/processes manage IPv4/IPv6 separately. Because we can use a single socket to connect both IPv4/IPv6 servers on client, although we can only use one family at a time.

I know I made a mistake on "same time" and "single time". this comment is only to explain why I thought the family type for the result should be zero before. Sorry for disturbing you

Comment 4 Jeff Law 2012-03-02 17:59:33 UTC
No worries.  I've been looking closely at the rfcs related to getaddrinfo recently, so it was already fresh in my mind.  You didn't disturb me at all.

If anything else comes up, don't hesitate to file a report.