Bug 27939

Summary: rlogin uses wrong IP address for remote host
Product: Base System Reporter: Jim.Pirzyk <Jim.Pirzyk>
Component: binAssignee: Jim Pirzyk <pirzyk>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.3-RELEASE   
Hardware: Any   
OS: Any   

Description Jim.Pirzyk 2001-06-07 18:50:00 UTC
	We have two hosts that are both multi homed.  Snoopy and quasar.
	Snoopy is a FreeBSD 4.3-RELEASE system and quasar is a Sun Solaris 8
	system.  Snoopy has IPs 172.30.228.110, 153.7.117.170, quasar has
	172.30.28.114, 153.7.117.112

	/etc/resolv.conf looks like this:

search fan.fa.disney.com fas.fa.disney.com fa.disney.com faf.fa.disney.com fap.fa.disney.com dqimages.com
sortlist  153.7.112.0/255.255.248.0 172.30.224.0/255.255.248.0 172.30.0.0/255.255.128.0 157.23.0.0
nameserver 172.30.224.2
nameserver 172.30.224.6
nameserver 172.30.50.1

	So we want to use the 153.7 subnet to communicate between the two
	machines (since 153.7 is atm, the 172.30.228 subnet is 100Mb enet 
	and the 172.30.28 subnet is 10Mb enet).

	Snoopy's routing has this:

Jim.Pirzyk@snoopy:~
72>netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags     Refs     Use     Netif Expire
default            172.30.231.254     UGSc        3      180      xl0
127.0.0.1          127.0.0.1          UH          5    28634      lo0
153.7.112/21       153.7.117.170      Uc         10        9      fa0
172.30.224/21      link#1             UC          0        0      xl0 =>

quasar's has this:

Jim.Pirzyk@quasar:~
1>netstat -rnnetstat -rn

Routing Table: IPv4
  Destination           Gateway           Flags  Ref   Use   Interface
-------------------- -------------------- ----- ----- ------ ---------
172.30.28.0          172.30.28.114         U        1      7  hme0
153.7.112.0          153.7.117.112         U        1     22  fa0
224.0.0.0            172.30.28.114         U        1      0  hme0
default              172.30.28.254         UG       1      6  
127.0.0.1            127.0.0.1             UH      16   3653  lo0


But when rlogin'g to quasar from snoopy, it uses the 172.30 subnets,
ignoring the sortlist in the /etc/resolv.conf file.
This is because the DNS server is sending out the 172.30 subnets
first, but we have a subnet in common that should be used.

Ping does work correctly though and uses the 153.7 subnet:

Jim.Pirzyk@snoopy:~
74>ping quasar
PING quasar.fan.fa.disney.com (153.7.117.112): 56 data bytes
64 bytes from 153.7.117.112: icmp_seq=0 ttl=255 time=0.288 ms

Fix: 

use gethostsbyname2 instead of getaddrinfo in rcmd_af.
How-To-Repeat: 	have a site similar to above and then do this

	rsh quasar
	netstat | grep snoopy # to get port number
	netstat -n | grep <PORT NUMBER> # check to see which subnet is being used.
Comment 1 Sheldon Hearn 2001-08-08 20:44:53 UTC
------- Forwarded Message

Return-path: <ume@mahoroba.org>
Envelope-to: sheldonh@starjuice.net
Delivery-date: Wed, 08 Aug 2001 15:36:55 -0400
Received: from mail.gambling.com [216.123.44.10]
	by localhost with POP3 (fetchmail-5.8.11)
	for sheldonh@localhost (single-drop); Wed, 08 Aug 2001 21:39:33 +0200 (SAST)
Received: from [202.227.26.34] (helo=peace.mahoroba.org)
	by mail.gambling.com with esmtp (Exim 3.31 #1)
	id 15UZ8P-000LFa-00
	for sheldonh@starjuice.net; Wed, 08 Aug 2001 15:36:54 -0400
Received: from localhost (IDENT:3xW4eK4qA1PHHtbsWVNBUur33jE35NdkIuKbIjyeoy2AA8GYoPKM/wBMCyoR0m+a@localhost [::1])
	(authenticated as ume with CRAM-MD5)
	by peace.mahoroba.org (8.11.5/8.11.5/peace) with ESMTP/inet6 id f78JZwU68669;
	Thu, 9 Aug 2001 04:35:58 +0900 (JST)
	(envelope-from ume@mahoroba.org)
Date: Thu, 09 Aug 2001 04:35:55 +0900 (JST)
Message-Id: <20010809.043555.104064272.ume@mahoroba.org>
To: ru@FreeBSD.org
Cc: Jim.Pirzyk@disney.com, sheldonh@starjuice.net, cvs-committers@FreeBSD.org,
   cvs-all@FreeBSD.org
Subject: Re: cvs commit: src/lib/libc/net gethostbyname.3
From: Hajimu UMEMOTO <ume@mahoroba.org>
In-Reply-To: <20010808191242.C10516@sunbay.com>
References: <55998.997269012@axl.seasidesoftware.co.za>
	<01080808322800.22597@snoopy>
	<20010808191242.C10516@sunbay.com>
X-Mailer: xcite1.38> Mew version 1.95b119 on Emacs 20.7 / Mule 4.0
 =?iso-2022-jp?B?KBskQjJWMWMbKEIp?=
X-PGP-Public-Key: http://www.imasy.org/~ume/publickey.asc
X-PGP-Fingerprint: 6B 0C 53 FC 5D D0 37 91  05 D0 B3 EF 36 9B 6A BC
X-URL: http://www.imasy.org/~ume/
X-Operating-System: FreeBSD 5.0-CURRENT
Mime-Version: 1.0
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

>>>>> On Wed, 8 Aug 2001 19:12:42 +0300
>>>>> Ruslan Ermilov <ru@FreeBSD.org> said:

ru> On Wed, Aug 08, 2001 at 08:32:28AM -0700, Jim Pirzyk wrote:
> On Wednesday 08 August 2001 04:10 am, Sheldon Hearn wrote:
> > On Wed, 08 Aug 2001 04:05:47 MST, Ruslan Ermilov wrote:
> > >   Modified files:
> > >     lib/libc/net         gethostbyname.3
> > >   Log:
> > >   Urge the reader to start using getaddrinfo(3) and getnameinfo(3)
> > >   protocol-independant functions that don't use static memory area.
> >
> > And which _rock_!
> 
> Err, not quite.  They do not use the DNS sortlist functionallity,
> nor do they check to see what subnet the host and remote host
> has in common to use that address first. 
> This would be the #1 reason I would not use them.  See PR bin/27939.
> 
ru> This is the implementation bug that should ideally be fixed.  But
ru> this does not mean that this interface is bad, because DNS is one
ru> of the possible back ends, and the latest POSIX draft says:

Okay, how about this patch?  It supports sortlist.  It affects only
IPv4 address.

Index: lib/libc/net/getaddrinfo.c
diff -u lib/libc/net/getaddrinfo.c.orig lib/libc/net/getaddrinfo.c
--- lib/libc/net/getaddrinfo.c.orig	Sat Jun 16 07:08:28 2001
+++ lib/libc/net/getaddrinfo.c	Thu Aug  9 04:32:56 2001
@@ -99,6 +99,9 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
+
+#include "res_config.h"
+
 #ifdef DEBUG
 #include <syslog.h>
 #endif
@@ -1194,6 +1197,72 @@
 }
 #endif
 
+#ifdef RESOLVSORT
+struct addr_ptr {
+	struct addrinfo *ai;
+	int aval;
+};
+
+static int
+addr4sort(struct addrinfo *sentinel)
+{
+	struct addrinfo *ai;
+	struct addr_ptr *addrs, addr;
+	struct sockaddr_in *sin;
+	int naddrs, i, j;
+	int needsort = 0;
+
+	if (!sentinel)
+		return -1;
+	naddrs = 0;
+	for (ai = sentinel->ai_next; ai; ai = ai->ai_next)
+		naddrs++;
+	if (naddrs < 2)
+		return 0;		/* We don't need sorting. */
+	if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL)
+		return -1;
+	i = 0;
+	for (ai = sentinel->ai_next; ai; ai = ai->ai_next) {
+		sin = (struct sockaddr_in *)ai->ai_addr;
+		for (j = 0; (unsigned)j < _res.nsort; j++) {
+			if (_res.sort_list[j].addr.s_addr == 
+			    (sin->sin_addr.s_addr & _res.sort_list[j].mask))
+				break;
+		}
+		addrs[i].ai = ai;
+		addrs[i].aval = j;
+		if (needsort == 0 && i > 0 && j < addrs[i - 1].aval)
+			needsort = i;
+		i++;
+	}
+	if (!needsort) {
+		free(addrs);
+		return 0;
+	}
+
+	while (needsort < naddrs) {
+	    for (j = needsort - 1; j >= 0; j--) {
+		if (addrs[j].aval > addrs[j+1].aval) {
+		    addr = addrs[j];
+		    addrs[j] = addrs[j + 1];
+		    addrs[j + 1] = addr;
+		} else
+		    break;
+	    }
+	    needsort++;
+	}
+
+	ai = sentinel;
+	for (i = 0; i < naddrs; ++i) {
+		ai->ai_next = addrs[i].ai;
+		ai = ai->ai_next;
+	}
+	ai->ai_next = NULL;
+	free(addrs);
+	return 0;
+}
+#endif /*RESOLVSORT*/
+
 #ifdef DEBUG
 static const char AskedForGot[] =
 	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
@@ -1387,6 +1456,19 @@
 			haveanswer++;
 	}
 	if (haveanswer) {
+#if defined(RESOLVSORT)
+		/*
+		 * We support only IPv4 address for backward
+		 * compatibility against gethostbyname(3).
+		 */
+		if (_res.nsort && qtype == T_A) {
+			if (addr4sort(&sentinel) < 0) {
+				freeaddrinfo(sentinel.ai_next);
+				h_errno = NO_RECOVERY;
+				return NULL;
+			}
+		}
+#endif /*RESOLVSORT*/
 		if (!canonname)
 			(void)get_canonname(pai, sentinel.ai_next, qname);
 		else

--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@bisd.hitachi.co.jp  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/

------- End of Forwarded Message
Comment 2 Jens Schweikhardt freebsd_committer freebsd_triage 2002-08-09 20:35:06 UTC
Responsible Changed
From-To: freebsd-bugs->pirzyk

Over to originator. Jim, have you ever tested the patch in the PR?
Comment 3 Jim Pirzyk freebsd_committer freebsd_triage 2002-10-14 20:59:12 UTC
State Changed
From-To: open->closed

commited the patch to RELENG_4 now (-CURRENT over a month ago)