chiark / gitweb /
debianutils: Update from 4.8.3 to 4.8.4
[termux-packages] / packages / tsocks / 04_getpeername.patch
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));