preload-hacks: Some patches to make it work.
[termux-packages] / packages / tsocks / 04_getpeername.patch
CommitLineData
0301524b
OS
1#! /bin/sh /usr/share/dpatch/dpatch-run
2## 04_getpeername.dpatch by Nico Golde <nion@debian.org>
3##
4## All lines beginning with `## DP:' are a description of the patch.
5## DP: No description.
6
7--- a/acconfig.h
8+++ b/acconfig.h
9@@ -43,6 +43,9 @@ allows socksified DNS */
10 /* Prototype and function header for close function */
11 #undef CLOSE_SIGNATURE
12
13+/* Prototype and function header for getpeername function */
14+#undef GETPEERNAME_SIGNATURE
15+
16 /* Work out which function we have for conversion from string IPs to
17 numerical ones */
18 #undef HAVE_INET_ADDR
19--- a/config.h.in
20+++ b/config.h.in
21@@ -46,6 +46,9 @@ allows socksified DNS */
22 /* Prototype and function header for close function */
23 #undef CLOSE_SIGNATURE
24
25+/* Prototype and function header for close function */
26+#undef GETPEERNAME_SIGNATURE
27+
28 /* Work out which function we have for conversion from string IPs to
29 numerical ones */
30 #undef HAVE_INET_ADDR
31--- a/configure
32+++ b/configure
33@@ -2225,14 +2225,60 @@ cat >> confdefs.h <<EOF
34 EOF
35
36
37+
38+echo $ac_n "checking for correct getpeername prototype""... $ac_c" 1>&6
39+echo "configure:2231: checking for correct getpeername prototype" >&5
40+PROTO=
41+PROTO1='int __fd, const struct sockaddr * __name, int *__namelen'
42+PROTO2='int __fd, const struct sockaddr_in * __name, socklen_t *__namelen'
43+PROTO3='int __fd, struct sockaddr * __name, socklen_t *__namelen'
44+PROTO4='int __fd, const struct sockaddr * __name, socklen_t *__namelen'
45+for testproto in "${PROTO1}" \
46+ "${PROTO2}" \
47+ "${PROTO3}" \
48+ "${PROTO4}"
49+do
50+ if test "${PROTO}" = ""; then
51+ cat > conftest.$ac_ext <<EOF
52+#line 2244 "configure"
53+#include "confdefs.h"
54+
55+ #include <sys/socket.h>
56+ int getpeername($testproto);
57+
58+int main() {
59+
60+; return 0; }
61+EOF
62+if { (eval echo configure:2254: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
63+ rm -rf conftest*
64+ PROTO="$testproto";
65+else
66+ echo "configure: failed program was:" >&5
67+ cat conftest.$ac_ext >&5
68+fi
69+rm -f conftest*
70+ fi
71+done
72+if test "${PROTO}" = ""; then
73+ { echo "configure: error: "no match found!"" 1>&2; exit 1; }
74+fi
75+echo "$ac_t""getpeername(${PROTO})" 1>&6
76+cat >> confdefs.h <<EOF
77+#define GETPEERNAME_SIGNATURE ${PROTO}
78+EOF
79+
80+
81+
82+
83 echo $ac_n "checking for correct poll prototype""... $ac_c" 1>&6
84-echo "configure:2230: checking for correct poll prototype" >&5
85+echo "configure:2276: checking for correct poll prototype" >&5
86 PROTO=
87 for testproto in 'struct pollfd *ufds, unsigned long nfds, int timeout'
88 do
89 if test "${PROTO}" = ""; then
90 cat > conftest.$ac_ext <<EOF
91-#line 2236 "configure"
92+#line 2282 "configure"
93 #include "confdefs.h"
94
95 #include <sys/poll.h>
96@@ -2242,7 +2288,7 @@ int main() {
97
98 ; return 0; }
99 EOF
100-if { (eval echo configure:2246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
101+if { (eval echo configure:2292: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
102 rm -rf conftest*
103 PROTO="$testproto";
104 else
105--- a/configure.in
106+++ b/configure.in
107@@ -309,6 +309,34 @@ fi
108 AC_MSG_RESULT([close(${PROTO})])
109 AC_DEFINE_UNQUOTED(CLOSE_SIGNATURE, [${PROTO}])
110
111+
112+dnl Find the correct getpeername prototype on this machine
113+AC_MSG_CHECKING(for correct getpeername prototype)
114+PROTO=
115+PROTO1='int __fd, const struct sockaddr * __name, int *__namelen'
116+PROTO2='int __fd, const struct sockaddr_in * __name, socklen_t *__namelen'
117+PROTO3='int __fd, struct sockaddr * __name, socklen_t *__namelen'
118+PROTO4='int __fd, const struct sockaddr * __name, socklen_t *__namelen'
119+for testproto in "${PROTO1}" \
120+ "${PROTO2}" \
121+ "${PROTO3}" \
122+ "${PROTO4}"
123+do
124+ if test "${PROTO}" = ""; then
125+ AC_TRY_COMPILE([
126+ #include <sys/socket.h>
127+ int getpeername($testproto);
128+ ],,[PROTO="$testproto";],)
129+ fi
130+done
131+if test "${PROTO}" = ""; then
132+ AC_MSG_ERROR("no match found!")
133+fi
134+AC_MSG_RESULT([getpeername(${PROTO})])
135+AC_DEFINE_UNQUOTED(GETPEERNAME_SIGNATURE, [${PROTO}])
136+
137+
138+
139 dnl Find the correct poll prototype on this machine
140 AC_MSG_CHECKING(for correct poll prototype)
141 PROTO=
142--- a/tsocks.c
143+++ b/tsocks.c
144@@ -62,6 +62,7 @@ static int (*realconnect)(CONNECT_SIGNAT
145 static int (*realselect)(SELECT_SIGNATURE);
146 static int (*realpoll)(POLL_SIGNATURE);
147 static int (*realclose)(CLOSE_SIGNATURE);
148+static int (*realgetpeername)(GETPEERNAME_SIGNATURE);
149 static struct parsedfile *config;
150 static struct connreq *requests = NULL;
151 static int suid = 0;
152@@ -73,6 +74,7 @@ int connect(CONNECT_SIGNATURE);
153 int select(SELECT_SIGNATURE);
154 int poll(POLL_SIGNATURE);
155 int close(CLOSE_SIGNATURE);
156+int getpeername(GETPEERNAME_SIGNATURE);
157 #ifdef USE_SOCKS_DNS
158 int res_init(void);
159 #endif
160@@ -109,14 +111,15 @@ void _init(void) {
161 /* most programs that are run won't use our services, so */
162 /* we do our general initialization on first call */
163
164- /* Determine the logging level */
165- suid = (getuid() != geteuid());
166+ /* Determine the logging level */
167+ suid = (getuid() != geteuid());
168
169 #ifndef USE_OLD_DLSYM
170 realconnect = dlsym(RTLD_NEXT, "connect");
171 realselect = dlsym(RTLD_NEXT, "select");
172 realpoll = dlsym(RTLD_NEXT, "poll");
173 realclose = dlsym(RTLD_NEXT, "close");
174+ realgetpeername = dlsym(RTLD_NEXT, "getpeername");
175 #ifdef USE_SOCKS_DNS
176 realresinit = dlsym(RTLD_NEXT, "res_init");
177 #endif
178@@ -125,14 +128,15 @@ void _init(void) {
179 realconnect = dlsym(lib, "connect");
180 realselect = dlsym(lib, "select");
181 realpoll = dlsym(lib, "poll");
182+ realgetpeername = dlsym(lib, "getpeername");
183 #ifdef USE_SOCKS_DNS
184 realresinit = dlsym(lib, "res_init");
185 #endif
186- dlclose(lib);
187+ dlclose(lib);
188
189 lib = dlopen(LIBC, RTLD_LAZY);
190- realclose = dlsym(lib, "close");
191- dlclose(lib);
192+ realclose = dlsym(lib, "close");
193+ dlclose(lib);
194 #endif
195 }
196
197@@ -350,8 +354,10 @@ int select(SELECT_SIGNATURE) {
198
199 /* If we're not currently managing any requests we can just
200 * leave here */
201- if (!requests)
202+ if (!requests) {
203+ show_msg(MSGDEBUG, "No requests waiting, calling real select\n");
204 return(realselect(n, readfds, writefds, exceptfds, timeout));
205+ }
206
207 get_environment();
208
209@@ -705,6 +711,50 @@ int close(CLOSE_SIGNATURE) {
210 return(rc);
211 }
212
213+/* If we are not done setting up the connection yet, return
214+ * -1 and ENOTCONN, otherwise call getpeername
215+ *
216+ * This is necessary since some applications, when using non-blocking connect,
217+ * (like ircII) use getpeername() to find out if they are connected already.
218+ *
219+ * This results in races sometimes, where the client sends data to the socket
220+ * before we are done with the socks connection setup. Another solution would
221+ * be to intercept send().
222+ *
223+ * This could be extended to actually set the peername to the peer the
224+ * client application has requested, but not for now.
225+ *
226+ * PP, Sat, 27 Mar 2004 11:30:23 +0100
227+ */
228+int getpeername(GETPEERNAME_SIGNATURE) {
229+ struct connreq *conn;
230+ int rc;
231+
232+ if (realgetpeername == NULL) {
233+ show_msg(MSGERR, "Unresolved symbol: getpeername\n");
234+ return(-1);
235+ }
236+
237+ show_msg(MSGDEBUG, "Call to getpeername for fd %d\n", __fd);
238+
239+
240+ rc = realgetpeername(__fd, __name, __namelen);
241+ if (rc == -1)
242+ return rc;
243+
244+ /* Are we handling this connect? */
245+ if ((conn = find_socks_request(__fd, 1))) {
246+ /* While we are at it, we might was well try to do something useful */
247+ handle_request(conn);
248+
249+ if (conn->state != DONE) {
250+ errno = ENOTCONN;
251+ return(-1);
252+ }
253+ }
254+ return rc;
255+}
256+
257 static struct connreq *new_socks_request(int sockid, struct sockaddr_in *connaddr,
258 struct sockaddr_in *serveraddr,
259 struct serverent *path) {
260@@ -854,7 +904,7 @@ static int connect_server(struct connreq
261 sizeof(conn->serveraddr));
262
263 show_msg(MSGDEBUG, "Connect returned %d, errno is %d\n", rc, errno);
264- if (rc) {
265+ if (rc) {
266 if (errno != EINPROGRESS) {
267 show_msg(MSGERR, "Error %d attempting to connect to SOCKS "
268 "server (%s)\n", errno, strerror(errno));