mirror of
https://git.FreeBSD.org/ports.git
synced 2024-11-01 22:05:08 +00:00
61ce7c4a22
will be used to support SOCKS operation in the soon-to-be-released next version of CVSup. A tip of the hat to: Darryl Okahata, who developed the patches necessary to make the SOCKS library work with Modula-3's multithreaded I/O system.
250 lines
6.0 KiB
Plaintext
250 lines
6.0 KiB
Plaintext
Index: SOCKS-SOURCE/client/Xconnect.c
|
|
diff -r -u SOCKS-SOURCE/client/Xconnect.c socks-jdp/client/Xconnect.c
|
|
--- SOCKS-SOURCE/client/Xconnect.c Wed Aug 7 19:25:51 1996
|
|
+++ socks-jdp/client/Xconnect.c Thu Oct 24 21:35:47 1996
|
|
@@ -24,7 +24,9 @@
|
|
#include <netdb.h>
|
|
#include <arpa/nameser.h>
|
|
int res_init PARAM((void));
|
|
+#ifndef __FreeBSD__
|
|
int res_search PARAM((char*,int,int,u_char*,int));
|
|
+#endif
|
|
int dn_skipname PARAM((u_char*,u_char*));
|
|
#include <arpa/inet.h>
|
|
#include <resolv.h>
|
|
@@ -39,6 +41,10 @@
|
|
#include "bytes.h"
|
|
#include "check_user.h"
|
|
|
|
+#ifndef FIOSNBIO
|
|
+# define FIOSNBIO FIONBIO
|
|
+#endif
|
|
+
|
|
unsigned char _SOCKS_version=SOCKS_VERSION;
|
|
|
|
char *socks_dst_serv=NULL, *socks_dst_name=NULL;
|
|
@@ -102,6 +108,8 @@
|
|
struct info *l; /* must be first field */
|
|
int snum;
|
|
unsigned short type;
|
|
+ int connect_done:8;
|
|
+ int bind_done:8;
|
|
int sin_valid:8;
|
|
int peer_valid:8;
|
|
struct sockaddr_in sin;
|
|
@@ -185,16 +193,34 @@
|
|
#ifndef INTERNAL_ONLY
|
|
if (_SOCKS_external) {
|
|
u_short port;
|
|
+ int status, oldf;
|
|
+
|
|
+ oldf = -1;
|
|
+ status = 0;
|
|
+ while (1)
|
|
+ {
|
|
+ if ((oldf = fcntl(s, F_GETFL, NULL)) == -1)
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+ (void)fcntl(s, F_SETFL, oldf&~(O_NDELAY|O_NONBLOCK));
|
|
if (_SOCKS_read(s,&net.version,sizeof(net.version)) < -1)
|
|
- return -1;
|
|
+ break;
|
|
if (_SOCKS_read(s,&net.cmd,sizeof(net.cmd)) < -1)
|
|
- return -1;
|
|
+ break;
|
|
if (_SOCKS_read(s,&port,sizeof(port)) < -1)
|
|
- return -1;
|
|
- net.port=port;
|
|
+ break;
|
|
+ net.port = port;
|
|
if (_SOCKS_read(s,&net.host,sizeof(net.host)) < -1)
|
|
- return -1;
|
|
- } else
|
|
+ break;
|
|
+ status = 1;
|
|
+ break;
|
|
+ }
|
|
+ if (oldf != -1)
|
|
+ (void)fcntl(s, F_SETFL, oldf);
|
|
+ if (!status)
|
|
+ return (-1);
|
|
+ } else
|
|
#endif /* INTERNAL_ONLY */
|
|
{
|
|
if (_SOCKS_read(s,&net,sizeof(net)) < -1)
|
|
@@ -297,6 +323,12 @@
|
|
|
|
if (s>=0 && af == AF_INET) {
|
|
(void)add_sock(s,NULL,type);
|
|
+#if 1
|
|
+ bval = size;
|
|
+ blen = sizeof(bval);
|
|
+ (void)setsockopt(s,SOL_SOCKET,SO_RCVBUF,&bval,blen);
|
|
+ (void)setsockopt(s,SOL_SOCKET,SO_SNDBUF,&bval,blen);
|
|
+#else
|
|
if (getsockopt(s,SOL_SOCKET,SO_RCVBUF,&bval,&blen)==0 && bval<size) {
|
|
bval=size;
|
|
(void)setsockopt(s,SOL_SOCKET,SO_RCVBUF,&bval,blen);
|
|
@@ -305,6 +337,7 @@
|
|
bval=size;
|
|
(void)setsockopt(s,SOL_SOCKET,SO_SNDBUF,&bval,blen);
|
|
}
|
|
+#endif
|
|
}
|
|
return s;
|
|
}
|
|
@@ -380,6 +413,7 @@
|
|
oldf=fcntl(sock,F_GETFL,NULL);
|
|
(void)fcntl(sock,F_SETFL,oldf&~(O_NDELAY|O_NONBLOCK));
|
|
(void)ioctl(sock,FIOSNBIO,0);
|
|
+ errno = 0;
|
|
if (Xconnect(sock, sin, sizeof(struct sockaddr_in)) == 0) {
|
|
if (SendDst(sock, dst) < 0) {
|
|
ret_val=-1;
|
|
@@ -389,6 +423,7 @@
|
|
lastSocksHost=sin->sin_addr.s_addr;
|
|
lastSocksPort=sin->sin_port;
|
|
*dst=mydst;
|
|
+ (void)fcntl(sock,F_SETFL,oldf);
|
|
return 0;
|
|
} else {
|
|
errno=ECONNREFUSED;
|
|
@@ -402,7 +437,7 @@
|
|
exit(1);
|
|
}
|
|
Xclose(new_sock);
|
|
-
|
|
+ (void)fcntl(sock,F_SETFL,oldf);
|
|
return ret_val;
|
|
}
|
|
#ifdef PROTOTYPES
|
|
@@ -605,6 +640,12 @@
|
|
l->sin.sin_family = AF_INET;
|
|
l->sin_valid = 1;
|
|
|
|
+ if (type == SOCKS_CONNECT) {
|
|
+ l->connect_done = 1;
|
|
+ } else if (type == SOCKS_BIND) {
|
|
+ l->bind_done = 1;
|
|
+ }
|
|
+
|
|
return 0;
|
|
break;
|
|
default:
|
|
@@ -627,9 +668,20 @@
|
|
struct sockaddr_in *sin=(struct sockaddr_in *)usin;
|
|
|
|
if (size == sizeof(struct sockaddr_in) && sin->sin_family == AF_INET) {
|
|
+ register infot *l=find_sock(sock);
|
|
_SOCKS_last_connect=*sin;
|
|
- return _SOCKS_cbind(sock,sin,size,
|
|
- sin->sin_addr.s_addr,SOCKS_CONNECT);
|
|
+ if (l == NULL || !l->connect_done) {
|
|
+ return _SOCKS_cbind(sock,sin,size,
|
|
+ sin->sin_addr.s_addr,
|
|
+ SOCKS_CONNECT);
|
|
+ l=find_sock(sock);
|
|
+ if (l) {
|
|
+ l->connect_done = 1;
|
|
+ }
|
|
+ } else {
|
|
+ errno = EISCONN;
|
|
+ return -1;
|
|
+ }
|
|
} else {
|
|
register infot *l=find_sock(sock);
|
|
if (l!=NULL)
|
|
@@ -713,10 +765,10 @@
|
|
}
|
|
|
|
#ifdef PROTOTYPES
|
|
-int Rrecvfrom(int s,char *m,int len,int f,struct sockaddr_in *from,int *size)
|
|
+int Rrecvfrom(int s,char *m,size_t len,int f,struct sockaddr_in *from,int *size)
|
|
#else
|
|
int Rrecvfrom(s,m,len,f,from,size)
|
|
-int s;char *m;int len;int f;struct sockaddr_in *from;int *size;
|
|
+int s;char *m;size_t len;int f;struct sockaddr_in *from;int *size;
|
|
#endif
|
|
{
|
|
infot *l=find_sock(s);
|
|
@@ -758,10 +810,10 @@
|
|
}
|
|
|
|
#ifdef PROTOTYPES
|
|
-int Rrecv(int s,char *m,int len,int f)
|
|
+int Rrecv(int s,char *m,size_t len,int f)
|
|
#else
|
|
int Rrecv(s,m,len,f)
|
|
-int s;char *m;int len;int f;
|
|
+int s;char *m;size_t len;int f;
|
|
#endif
|
|
{
|
|
struct sockaddr_in from;
|
|
@@ -771,10 +823,10 @@
|
|
}
|
|
|
|
#ifdef PROTOTYPES
|
|
-int Rsendto(int s,char *m,int len,int f,struct sockaddr_in *to,int size)
|
|
+int Rsendto(int s,char *m,size_t len,int f,struct sockaddr_in *to,int size)
|
|
#else
|
|
int Rsendto(s,m,len,f,to,size)
|
|
-int s;char *m;int len;int f;struct sockaddr_in *to;int size;
|
|
+int s;char *m;size_t len;int f;struct sockaddr_in *to;int size;
|
|
#endif
|
|
{
|
|
infot *l=find_sock(s);
|
|
@@ -805,10 +857,10 @@
|
|
return _SOCKS_write(s,m,len);
|
|
}
|
|
#ifdef PROTOTYPES
|
|
-int Rsend(int s,char *m,int len,int f)
|
|
+int Rsend(int s,char *m,size_t len,int f)
|
|
#else
|
|
int Rsend(s,m,len,f)
|
|
-int s;char *m;int len;int f;
|
|
+int s;char *m;size_t len;int f;
|
|
#endif
|
|
{
|
|
infot *l=find_sock(s);
|
|
@@ -877,17 +929,28 @@
|
|
fd_set fds;
|
|
Socks_t dst;
|
|
infot *l=find_sock(sock);
|
|
+ int nfds;
|
|
+ struct timeval timeout, *tptr=NULL;
|
|
+ int flags;
|
|
|
|
+ errno = 0;
|
|
if (l == NULL || !l->sin_valid)
|
|
return Xaccept(sock,sin,size);
|
|
|
|
/* if we found the entry, bind or connect was called, so no
|
|
SOCKSinit is needed. */
|
|
|
|
+ flags = fcntl(sock, F_GETFL, 0);
|
|
+ if (flags != -1 && (flags & O_NONBLOCK)) {
|
|
+ timeout.tv_sec = 0;
|
|
+ timeout.tv_usec = 0;
|
|
+ tptr = &timeout;
|
|
+ }
|
|
+
|
|
FD_ZERO(&fds);
|
|
FD_SET(sock, &fds);
|
|
|
|
- if (select(sock+1, (int*)&fds, NULL, NULL, NULL) > 0)
|
|
+ if ((nfds = select(sock+1, &fds, NULL, NULL, tptr)) > 0) {
|
|
if (FD_ISSET(sock, &fds)) {
|
|
if (GetDst(sock, &dst) < 0)
|
|
return -1;
|
|
@@ -901,6 +964,9 @@
|
|
|
|
return dup(sock);
|
|
}
|
|
+ }
|
|
+ if (nfds == 0)
|
|
+ errno = EWOULDBLOCK;
|
|
return -1;
|
|
}
|
|
#ifdef PROTOTYPES
|