home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / junkbust / conn.c < prev    next >
C/C++ Source or Header  |  1998-10-30  |  3KB  |  175 lines

  1. char *conn_rcs = "$Id: conn.c,v 2.16 1998/10/27 02:14:07 ACJC Exp $";
  2. /* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
  3.  * Distributed under the GNU General Public License; see the README file.
  4.  * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
  5.  */
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <errno.h>
  11. #include <fcntl.h>
  12. #include <sys/types.h>
  13.  
  14. #ifdef _WIN32
  15.  
  16. #include <windows.h>
  17. #include <sys/timeb.h>
  18. #include <io.h>
  19.  
  20. #else
  21.  
  22. #include <unistd.h>
  23. #include <sys/time.h>
  24. #include <netinet/in.h>
  25. #include <sys/ioctl.h>
  26. #include <netdb.h> 
  27. #include <sys/socket.h>
  28.  
  29. #ifndef __BEOS__
  30. #include <netinet/tcp.h>
  31. #include <arpa/inet.h>
  32. #endif
  33.  
  34. #endif
  35.  
  36. #ifdef REGEX
  37. #include "gnu_regex.h"
  38. #endif
  39.  
  40. #include "jcc.h"
  41.  
  42. int
  43. direct_connect(struct gateway *gw, struct http_request *http, struct client_state *csp)
  44. {
  45.     if(gw->forward_host) {
  46.         return(connect_to(gw->forward_host, gw->forward_port, csp));
  47.     } else {
  48.         return(connect_to(http->host, http->port, csp));
  49.     }
  50. }
  51.  
  52. int
  53. atoip(char *host)
  54. {
  55.     struct sockaddr_in inaddr;
  56.     struct hostent *hostp;
  57.  
  58.     if ((host == NULL) || (*host == '\0')) 
  59.         return(INADDR_ANY);
  60.  
  61.     memset ((char * ) &inaddr, 0, sizeof inaddr);
  62.     if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1) {
  63.         if ((hostp = gethostbyname(host)) == NULL) {
  64.             errno = EINVAL;
  65.             return(-1);
  66.         }
  67.         if (hostp->h_addrtype != AF_INET) {
  68. #ifdef _WIN32
  69.             errno = WSAEPROTOTYPE;
  70. #else
  71.             errno = EPROTOTYPE;
  72. #endif
  73.             return(-1);
  74.         }
  75.         memcpy((char * ) &inaddr.sin_addr, (char * ) hostp->h_addr,
  76.             sizeof(inaddr.sin_addr));
  77.     }
  78.     return(inaddr.sin_addr.s_addr);
  79. }
  80.  
  81.  
  82. int
  83. connect_to(char *host, int portnum, struct client_state *csp)
  84. {
  85.     struct sockaddr_in inaddr;
  86.     int    fd, addr;
  87.     fd_set wfds;
  88.     struct timeval tv[1];
  89.     int    flags;
  90.     struct access_control_addr src[1], dst[1];
  91.  
  92.     memset ((char * ) &inaddr, 0, sizeof inaddr);
  93.  
  94.     if((addr = atoip(host)) == -1) return(-1);
  95.  
  96.     src->addr = csp->ip_addr_long;
  97.     src->port = 0;
  98.  
  99.     dst->addr = ntohl(addr);
  100.     dst->port = portnum;
  101.  
  102.     if(block_acl(src, dst, csp)) {
  103.         errno = EPERM;
  104.         return(-1);
  105.     }
  106.  
  107.     inaddr.sin_addr.s_addr = addr;
  108.     inaddr.sin_family      = AF_INET;
  109.  
  110.     if (sizeof(inaddr.sin_port) == sizeof(short)) {
  111.         inaddr.sin_port = htons(portnum);
  112.     } else {
  113.         inaddr.sin_port = htonl(portnum);
  114.     }
  115.  
  116.     if((fd = socket(inaddr.sin_family, SOCK_STREAM, 0)) < 0) {
  117.         return(-1);
  118.     }
  119.  
  120. #ifdef TCP_NODELAY
  121. {    /* turn off TCP coalescence */
  122.     int    mi = 1;
  123.     setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char * ) &mi, sizeof (int));
  124. }
  125. #endif
  126.  
  127. #ifndef _WIN32
  128. #ifndef __BEOS__
  129.     if ((flags = fcntl(fd, F_GETFL, 0)) != -1) {
  130.         flags |= O_NDELAY;
  131.         fcntl(fd, F_SETFL, flags);
  132.     }
  133. #endif
  134. #endif
  135.  
  136.     while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == -1) {
  137.  
  138. #ifdef _WIN32
  139.         if (errno == WSAEINPROGRESS)
  140. #else
  141.         if (errno == EINPROGRESS)
  142. #endif
  143.         {
  144.             break;
  145.         }
  146.  
  147.         if (errno != EINTR) {
  148.             (void) close (fd);
  149.             return(-1);
  150.         }
  151.     }
  152.  
  153. #ifndef _WIN32
  154. #ifndef __BEOS__
  155.     if (flags != -1) {
  156.         flags &= ~O_NDELAY;
  157.         fcntl(fd, F_SETFL, flags);
  158.     }
  159. #endif
  160. #endif
  161.  
  162.     /* wait for connection to complete */
  163.     FD_ZERO(&wfds);
  164.     FD_SET(fd, &wfds);
  165.  
  166.     tv->tv_sec  = 30;
  167.     tv->tv_usec = 0;
  168.  
  169.     if (select(fd + 1, NULL, &wfds, NULL, tv) <= 0) {
  170.         (void) close(fd);
  171.         return(-1);
  172.     }
  173.     return(fd);
  174. }
  175.