aboutsummaryrefslogtreecommitdiffstats
path: root/net/socks5/files/patch-ak
blob: e94333601db12f151d03e681c539dd3db2b9ea5c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
--- 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
  
 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");