[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#441857: libc6: resolver is broken for local IPv6 networking due to patch from #435646



Package: libc6
Version: 2.6.1-2
Severity: important

As the title implies, IPv6 networking is now broken when the system
does not have a globally scoped IPv6 address.  As I discovered a few
weeks ago, this has a nasty side effect of breaking all local IPv6
services, because they are not longer considered.

I have written a test program (addrtest, attached) to demonstrate.
Compile with

    c99 -o addrtest addrtest.c

and run with no arguments.  To demonstrate the problem with a
Leafnode NNTP server running via openbsd-inetd on the localhost:

% grep nntp /etc/inetd.conf
nntp  stream  tcp6  nowait  news  /usr/sbin/tcpd /usr/sbin/leafnode

% netstat --tcp -l | grep nntp
tcp6       0      0 *:nntp                  *:*                    LISTEN

% /sbin/ifconfig
eth0      Link encap:Ethernet  HWaddr 00:11:24:75:6D:56
          inet addr:192.168.156.21  Bcast:192.168.156.255  Mask:255.255.255.0
          inet6 addr: fe80::211:24ff:fe75:6d56/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:244661 errors:0 dropped:0 overruns:0 frame:0
          TX packets:170326 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:268682462 (256.2 MiB)  TX bytes:16191957 (15.4 MiB)
          Interrupt:41 Base address:0xa400

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1200579 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1200579 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:362353281 (345.5 MiB)  TX bytes:362353281 (345.5 MiB)

% ./addrtest

Addrinfo for 0x100120c0
Flags:          32
Family:         2
Socket Type:    1
Protocol:       6 (tcp)
Canonical name: (null)
Socket Address (len=16):
  Port:         119
  IPv4 Address: 127.0.0.1

Addrinfo for 0x100120f8
Flags:          32
Family:         2
Socket Type:    2
Protocol:       17 (udp)
Canonical name: (null)
Socket Address (len=16):
  Port:         119
  IPv4 Address: 127.0.0.1

% sudo /etc/init.d/aiccu start
Starting SixXS Automatic IPv6 Connectivity Client Utility (aiccu)...Tunnel Information for T11225:
POP Id      : iedub01
IPv6 Local  : 2001:770:100:ca::2/64
IPv6 Remote : 2001:770:100:ca::1/64
Tunnel Type : 6in4-heartbeat
Adminstate  : enabled
Userstate   : enabled
.

% /sbin/ifconfig
eth0      Link encap:Ethernet  HWaddr 00:11:24:75:6D:56
          inet addr:192.168.156.21  Bcast:192.168.156.255  Mask:255.255.255.0
          inet6 addr: fe80::211:24ff:fe75:6d56/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:244762 errors:0 dropped:0 overruns:0 frame:0
          TX packets:170366 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:268691686 (256.2 MiB)  TX bytes:16195883 (15.4 MiB)
          Interrupt:41 Base address:0xa400

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1200584 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1200584 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:362354897 (345.5 MiB)  TX bytes:362354897 (345.5 MiB)

sixxs     Link encap:IPv6-in-IPv4
          inet6 addr: 2001:770:100:ca::2/64 Scope:Global
          inet6 addr: fe80::c0a8:9c15/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP  MTU:1280  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

% ./addrtest

Addrinfo for 0x10012140
Flags:          32
Family:         2
Socket Type:    1
Protocol:       6 (tcp)
Canonical name: (null)
Socket Address (len=16):
  Port:         119
  IPv4 Address: 127.0.0.1

Addrinfo for 0x100128b0
Flags:          32
Family:         2
Socket Type:    2
Protocol:       17 (udp)
Canonical name: (null)
Socket Address (len=16):
  Port:         119
  IPv4 Address: 127.0.0.1

Addrinfo for 0x100128e8
Flags:          32
Family:         2
Socket Type:    3
Protocol:       0 (ip)
Canonical name: (null)
Socket Address (len=16):
  Port:         119
  IPv4 Address: 127.0.0.1

Addrinfo for 0x100120c0
Flags:          32
Family:         10
Socket Type:    1
Protocol:       6 (tcp)
Canonical name: (null)
Socket Address (len=28):
  Port:         119
  IPv6 Address: ::1

Addrinfo for 0x10012100
Flags:          32
Family:         10
Socket Type:    2
Protocol:       17 (udp)
Canonical name: (null)
Socket Address (len=28):
  Port:         119
  IPv6 Address: ::1


As the above demonstrates, the service is not actually accessible
when the SiXXS link is down, due to only (invalid) IPv4 results
being returned.  Even if they were valid, TCP wrappers would not
allow the connection.  This means clients like slrn and Gnus can
not connect.  It is reasonable to expect a service running on
the localhost to be accessible whether or not other unrelated
interfaces are up or down.


Regards,
Roger

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (990, 'unstable')
Architecture: powerpc (ppc)

Kernel: Linux 2.6.22-2-powerpc
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libc6 depends on:
ii  libgcc1                       1:4.2.1-5  GCC support library

libc6 recommends no packages.

-- no debconf information
/* Copyright © 2007  Roger Leigh <rleigh@debian.org>
 *
 * addrtest is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * addrtest is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA  02111-1307  USA
 *
 *********************************************************************/

#define _GNU_SOURCE
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

#include <arpa/inet.h>
#include <netinet/in.h>

void
fail (const char *msg)
{
  fprintf(stderr, "E: %s: %s\n", msg, strerror(errno));
  exit(EXIT_FAILURE);
}

void
gaifail (const char *msg, int code)
{
  fprintf(stderr, "E: %s: %s\n", msg, gai_strerror(code));
  exit(EXIT_FAILURE);
}

int
main (void)
{
  int status;
  struct addrinfo hints;
  hints.ai_flags = AI_ADDRCONFIG;
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = 0;
  hints.ai_protocol = 0;

  struct addrinfo *result = NULL;
  if((status = getaddrinfo("ip6-localhost", "119", &hints, &result)) != 0)
  //if((status = getaddrinfo("noc.sixxs.net", "https", NULL, &result)) != 0)
    gaifail("Failed to get addrinfo", status);

  {
    struct addrinfo *cur = result;
    while (cur->ai_next)
      {
	// Dump addrinfo
	printf("\nAddrinfo for %p\n", (void *) cur);
	printf("Flags:\t\t%d\n", cur->ai_flags);
	printf("Family:\t\t%d\n", cur->ai_family);
	printf("Socket Type:\t%d\n", cur->ai_socktype);

	struct protoent *protocol = getprotobynumber(cur->ai_protocol);
	if (protocol)
	  printf("Protocol:\t%d (%s)\n", cur->ai_protocol, protocol->p_name);
	else
	  printf("Protocol:\t%d (Unknown)\n", cur->ai_protocol);

	printf("Canonical name:\t%s\n", cur->ai_canonname);


	if (cur->ai_addr)
	  {
	    printf("Socket Address (len=%d):\n", cur->ai_addrlen);

	    switch(cur->ai_family)
	      {
	      case AF_INET:
		{
		  struct sockaddr_in *addr = (struct sockaddr_in *)cur->ai_addr;
		  printf("  Port:\t\t%d\n", ntohs(addr->sin_port));
		  char paddr[INET_ADDRSTRLEN];
		  if (inet_ntop(AF_INET, &addr->sin_addr, &paddr[0], cur->ai_addrlen) == NULL)
		    fail("Converting IPv4 address to readable form");
		  else
		    printf("  IPv4 Address:\t%s\n", &paddr[0]);
		}
		break;
	      case AF_INET6:
		{
		  struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)cur->ai_addr;
		  printf("  Port:\t\t%d\n", ntohs(addr6->sin6_port));
		  char paddr[INET6_ADDRSTRLEN];
		  if (inet_ntop(AF_INET6, &addr6->sin6_addr, &paddr[0], cur->ai_addrlen) == NULL)
		    fail("Converting IPv6 address to readable form");
		  else
		    printf("  IPv6 Address:\t%s\n", &paddr[0]);
		}
		break;
	      default:
		printf("  Unknown address family\n");
		break;
	      }

	  }
	cur = cur->ai_next;
      }
  }

  freeaddrinfo(result);

  return 0;
}

Reply to: