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 #include 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 #include @@ -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 && bvalsin_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