Add getaddrinfo() wrapper function support.

Tested and confirmed by: Robert Muir <rmuir@looksharp.net>,
	Toshihiko Kodama <kodama@ayame.mfd.cs.fujitsu.co.jp>,
	Masahide -mac- NODA <mac@clave.gr.jp>

Approved by: jkh

Reviewed by: imp
This commit is contained in:
Yoshinobu Inoue 2000-02-24 06:37:27 +00:00
parent a35e470938
commit e53d640ca4
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=26240
8 changed files with 330 additions and 57 deletions

View file

@ -1,6 +1,6 @@
--- lib/rld.c.org Wed Jun 24 22:32:37 1998
+++ lib/rld.c Wed Jun 24 22:33:11 1998
@@ -140,7 +140,7 @@
--- lib/rld.c.orig Wed Aug 4 04:59:28 1999
+++ lib/rld.c Mon Feb 21 03:55:45 2000
@@ -143,7 +143,7 @@
static void DGetOriginalFunc(void **fptr, char *name, int libmask) {
/* Synchronize access to func and lib opening functions if we can... */
@ -9,3 +9,30 @@
name++;
#endif
@@ -197,6 +197,26 @@
lsInRLDFunctions = 0;
S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: gethostbyname2 results: %s %s", name, hp?hp->h_name:"???");
return hp;
+}
+#endif
+
+#ifdef HAVE_GETADDRINFO
+int REAL(getaddrinfo)(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **aip) {
+ int error;
+ static void *func = NULL;
+
+ S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: getaddrinfo: %s", hostname);
+ GetOriginalFunc(&func, "_getaddrinfo", TRY_LIBC | TRY_LIBNSL | TRY_LIBRESOLV);
+ if (!func || func == (void *)-1) return NULL;
+
+ lsInRLDFunctions = 1;
+ error = ((int (*)P((const char *, const char *, const struct addrinfo *,
+ struct addrinfo **)))func)(hostname, servname,
+ hints, aip);
+ lsInRLDFunctions = 0;
+ S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: getaddrinfo results: %s %s", hostname, (*aip&&(*aip)->ai_canonname)?(*aip)->ai_canonname:"???");
+ return error;
}
#endif

View file

@ -1,55 +1,162 @@
The patch is for clients that do not have DNS resolution. Sites that do not
use the remote name resolution do not have to apply this patch.
The fakehost files (/tmp/.s5fakehost-<uid>) created with releases prior to
release 10 are not compatible.
If the fakehost file has size 65284 bytes, it is the old version. Delete the
file, apply the following patch, and rebuild the clients. The new fakehost
file has size 32644 bytes.
steve@syl.dl.nec.com
Index: lib/hostname.c
===================================================================
RCS file: lib/hostname.c,v
retrieving revision 1.31.4.12
retrieving revision 1.31.4.17
diff -c -r1.31.4.12 -r1.31.4.17
*** hostname.c 1999/08/02 14:52:23 1.31.4.12
--- hostname.c 1999/08/11 18:53:42 1.31.4.17
***************
*** 171,177 ****
strncpy(hostname, name, MIN(strlen(name), S5_HOSTNAME_SIZE-1));
hostname[MIN(strlen(name), S5_HOSTNAME_SIZE-1)] = '\0';
--- lib/hostname.c.orig Wed Aug 4 04:59:29 1999
+++ lib/hostname.c Tue Feb 22 09:51:48 2000
@@ -17,6 +17,11 @@
#define S5_HOSTLIST_SIZE 256
#define S5_HOSTALIASES_SIZE 16
#define S5_FAKEHOSTFILE ".s5fakehost"
+
+/* wrapper for KAME-special getnameinfo() */
+#ifndef NI_WITHSCOPEID
+#define NI_WITHSCOPEID 0
+#endif
! lseek(fd, (j-1)*256+sizeof(int), SEEK_SET);
if (REAL(write)(fd, hostname, sizeof(hostname)) != sizeof(hostname)) {
S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "GetHostFromFile: write table failed %m");
SetWriteLock(0);
--- 170,176 ----
strncpy(hostname, name, MIN(strlen(name), S5_HOSTNAME_SIZE-1));
hostname[MIN(strlen(name), S5_HOSTNAME_SIZE-1)] = '\0';
! lseek(fd, (j-1)*S5_HOSTNAME_SIZE+sizeof(int), SEEK_SET);
if (REAL(write)(fd, hostname, sizeof(hostname)) != sizeof(hostname)) {
S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "GetHostFromFile: write table failed %m");
SetWriteLock(0);
***************
*** 472,478 ****
if (fd > 0) {
SetReadLock(1);
! lseek(fd, (i-1)*256+sizeof(int), SEEK_SET);
if (REAL(read)(fd, hostname, len) != len) {
S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "lsGetCachedHostname: read fake table failed %m");
--- 471,477 ----
if (fd > 0) {
SetReadLock(1);
! lseek(fd, (i-1)*S5_HOSTNAME_SIZE+sizeof(int), SEEK_SET);
if (REAL(read)(fd, hostname, len) != len) {
S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "lsGetCachedHostname: read fake table failed %m");
struct hostEntry {
char name[S5_HOSTNAME_SIZE];
@@ -171,7 +176,7 @@
strncpy(hostname, name, MIN(strlen(name), S5_HOSTNAME_SIZE-1));
hostname[MIN(strlen(name), S5_HOSTNAME_SIZE-1)] = '\0';
- lseek(fd, (j-1)*256+sizeof(int), SEEK_SET);
+ lseek(fd, (j-1)*S5_HOSTNAME_SIZE+sizeof(int), SEEK_SET);
if (REAL(write)(fd, hostname, sizeof(hostname)) != sizeof(hostname)) {
S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "GetHostFromFile: write table failed %m");
SetWriteLock(0);
@@ -402,6 +407,129 @@
}
#endif
+#if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO)
+/* wrapper around the getaddrinfo call. */
+/* similar to getaddrinfo() except for: */
+/* *** if getaddrinfo() fails, then it returns a pointer to a addrinfo */
+/* structure filled with a special value, so that SOCKSxxxxxx() will */
+/* realize that this host was unresolved and fill in the protocol */
+/* accordingly... */
+/* */
+/* returns an error number on failure; 0 on success */
+int LIBPREFIX(getaddrinfo)(const char *hostname, const char *servname,
+ const struct addrinfo *hints,
+ struct addrinfo **aip) {
+ static char numaddrbuf[MAXHOSTNAMELEN];
+ static struct addrinfo *ai;
+ char *local, *fake;
+ int error = 0, i;
+ int addrlen, namelen, family;
+
+#ifdef FOR_SHARED_LIBRARY
+ if (lsInRLDFunctions || lsInWrapFunction || lsInWrapHostname) return REAL(getaddrinfo)(hostname, servname, hints, aip);
+#endif
+
+ lsInWrapFunction = 1;
+ lsInWrapHostname = 1;
+ LIBPREFIX2(init)("libsocks5");
+ S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS getaddrinfo: looking up %s", hostname);
+
+ fake = getenv("SOCKS5_FAKEALLHOSTS");
+ local = getenv("SOCKS5_LOCALDNSONLY");
+
+ if (!fake &&
+ (error = REAL(getaddrinfo)(hostname, servname, hints, aip)) == NULL) {
+ getnameinfo((*aip)->ai_addr, (*aip)->ai_addrlen, numaddrbuf,
+ sizeof(numaddrbuf) - 1, NULL, 0,
+ NI_NUMERICHOST|NI_WITHSCOPEID);
+ S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS getaddrinfo: REAL: %s", numaddrbuf);
+
+ lsInWrapFunction = 0;
+ lsInWrapHostname = 0;
+ return error;
+ }
+
+ /* If your DNS is the same as the socks server, don't fake a correct */
+ /* lookup when you know it won't work... */
+ if (local) {
+ S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS getaddrinfo: REAL: Fake not configured");
+ lsInWrapFunction = 0;
+ lsInWrapHostname = 0;
+ return (error != 0) ? error : EAI_FAIL;
+ }
+
+ /* Fill in some UNRESOLVED values and let the daemon resolve it */
+ if ((i = GetFakeHost(hostname)) <= 0) {
+ S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "SOCKS getaddrinfo: Get fake host failed");
+ lsInWrapFunction = 0;
+ lsInWrapHostname = 0;
+ return (error != 0) ? error : EAI_FAIL;
+ }
+
+ /* create fake for AF_INET. AF_INET6 support is not yet */
+ if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET) {
+ addrlen = sizeof(struct sockaddr_in);
+ family = AF_INET;
+ ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + addrlen);
+ if (ai == NULL)
+ return EAI_MEMORY;
+ memcpy(ai, hints, sizeof(struct addrinfo));
+ ai->ai_family = family;
+ ai->ai_addr = (struct sockaddr *)(ai + 1);
+ memset(ai->ai_addr, 0, addrlen);
+ ai->ai_addr->sa_len = addrlen;
+ ai->ai_addrlen = addrlen;
+ ai->ai_addr->sa_family = family;
+ if (servname != NULL) {
+ struct servent *sp;
+ const char *p;
+ int is_number, port;
+
+ p = servname;
+ is_number = 1;
+ while (*p) {
+ if (!isdigit(*p))
+ is_number = 0;
+ p++;
+ }
+ if (is_number) {
+ port = htons(atoi(servname));
+ if (port < 0 || port > 65535) {
+ free(ai);
+ return EAI_SERVICE;
+ }
+ } else {
+ sp = getservbyname(servname, NULL);
+ if (sp == NULL) {
+ free(ai);
+ return EAI_SERVICE;
+ }
+ port = sp->s_port;
+ }
+ ((struct sockaddr_in *)ai->ai_addr)->sin_port = port;
+ }
+ ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr = htonl(i);
+ if ((hints->ai_flags & AI_CANONNAME) != 0) {
+ ai->ai_canonname = (char *)malloc(strlen(hostname) + 1);
+ if (ai->ai_canonname == NULL) {
+ free(ai);
+ return EAI_MEMORY;
+ }
+ strncpy(ai->ai_canonname, hostname, strlen(hostname) + 1);
+ }
+ } else
+ return EAI_FAMILY;
+ *aip = ai;
+
+ getnameinfo((*aip)->ai_addr, (*aip)->ai_addrlen, numaddrbuf,
+ sizeof(numaddrbuf) - 1, NULL, 0, NI_NUMERICHOST);
+ S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS getaddrinfo: FAKE: %s", numaddrbuf);
+ lsInWrapFunction = 0;
+ lsInWrapHostname = 0;
+ return 0;
+}
+#endif
+
int lsGetCachedAddress(const char *name, S5NetAddr *na) {
int i;
char hostname[S5_HOSTNAME_SIZE];
@@ -472,7 +600,7 @@
if (fd > 0) {
SetReadLock(1);
- lseek(fd, (i-1)*256+sizeof(int), SEEK_SET);
+ lseek(fd, (i-1)*S5_HOSTNAME_SIZE+sizeof(int), SEEK_SET);
if (REAL(read)(fd, hostname, len) != len) {
S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "lsGetCachedHostname: read fake table failed %m");

10
net/socks5/files/patch-am Normal file
View file

@ -0,0 +1,10 @@
--- configure.in.orig Tue Aug 3 00:00:50 1999
+++ configure.in Sun Feb 20 21:24:32 2000
@@ -120,6 +120,7 @@
AC_CHECK_FUNCS(gethostbyname2)
AC_CHECK_FUNCS(gethostbyname_r gethostbyaddr_r getpwuid_r getservbyname_r)
+AC_CHECK_FUNCS(getaddrinfo getnameinfo)
AC_CHECK_FUNCS(memset memcmp memmove strchr strrchr strdup strerror)
AC_CHECK_FUNCS(bcopy bcmp bzero index rindex)
AC_CHECK_FUNCS(setenv putenv unsetenv getenv)

64
net/socks5/files/patch-an Normal file
View file

@ -0,0 +1,64 @@
--- configure Tue Aug 3 00:01:03 1999
+++ configure.orig Sun Feb 20 21:28:20 2000
@@ -3090,6 +3090,61 @@
fi
done
+for ac_func in getaddrinfo getnameinfo
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3182: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3187 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3210: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
for ac_func in memset memcmp memmove strchr strrchr strdup strerror
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6

15
net/socks5/files/patch-ao Normal file
View file

@ -0,0 +1,15 @@
--- include/config.h.in.orig Mon Aug 2 23:57:28 1999
+++ include/config.h.in Sun Feb 20 21:20:53 2000
@@ -133,6 +133,12 @@
/* Define if you have the gethostbyname_r function. */
#undef HAVE_GETHOSTBYNAME_R
+/* Define if you have the getaddrinfo function. */
+#undef HAVE_GETADDRINFO
+
+/* Define if you have the getnameinfo function. */
+#undef HAVE_GETNAMEINFO
+
/* Define if you have the getifaddrs function. */
#undef HAVE_GETIFADDRS

18
net/socks5/files/patch-ap Normal file
View file

@ -0,0 +1,18 @@
--- include/hide.h.orig Wed Aug 4 04:59:30 1999
+++ include/hide.h Mon Feb 21 14:41:49 2000
@@ -19,6 +19,7 @@
#ifdef HAVE_GETHOSTBYNAME2
#define gethostbyname2 HIDE(gethostbyname2)
#endif
+#define getaddrinfo HIDE(getaddrinfo)
#define gethostbyname HIDE(gethostbyname)
#define getpeername HIDE(getpeername)
#define getsockname HIDE(getsockname)
@@ -53,6 +54,7 @@
#ifdef HAVE_GETHOSTBYNAME2
#undef gethostbyname2
#endif
+#undef getaddrinfo
#undef gethostbyname
#undef getpeername
#undef getsockname

20
net/socks5/files/patch-aq Normal file
View file

@ -0,0 +1,20 @@
--- include/socks.h.orig Wed Aug 4 04:59:30 1999
+++ include/socks.h Mon Feb 21 14:44:03 2000
@@ -52,6 +52,9 @@
#ifdef HAVE_GETHOSTBYNAME2
extern struct hostent *LIBPREFIX(gethostbyname2) P((char *, int));
#endif
+extern int LIBPREFIX(getaddrinfo) P((const char *, const char *,
+ const struct addrinfo *,
+ struct addrinfo **));
#endif /* include prototypes */
#ifndef LIBPREFIX
@@ -93,6 +96,7 @@
#ifdef HAVE_GETHOSTBYNAME2
#define gethostbyname2 LIBPREFIX(gethostbyname2)
#endif
+#define getaddrinfo LIBPREFIX(getaddrinfo)
#define gethostbyname LIBPREFIX(gethostbyname)
#define rresvport LIBPREFIX(rresvport)
#define connect LIBPREFIX(connect)

12
net/socks5/files/patch-ar Normal file
View file

@ -0,0 +1,12 @@
--- include/system.h.orig Wed Aug 4 04:59:30 1999
+++ include/system.h Mon Feb 21 14:43:42 2000
@@ -24,6 +24,9 @@
#ifdef HAVE_GETHOSTBYNAME2
struct hostent * REAL(gethostbyname2) P((const char *, int));
#endif
+int REAL(getaddrinfo) P((const char *, const char *,
+ const struct addrinfo *,
+ struct addrinfo **));
struct hostent * REAL(gethostbyname) P((const char *));
struct hostent * REAL(gethostbyaddr) P((const void *, int, int));
struct servent * REAL(getservbyname) P((const char *, const char *));