conn.c
上传用户:qunlip
上传日期:2007-01-04
资源大小:203k
文件大小:3k
源码类别:

代理服务器

开发平台:

Visual C++

  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. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <errno.h>
  10. #include <fcntl.h>
  11. #include <sys/types.h>
  12. #ifdef _WIN32
  13. #include <windows.h>
  14. #include <sys/timeb.h>
  15. #include <io.h>
  16. #else
  17. #include <unistd.h>
  18. #include <sys/time.h>
  19. #include <netinet/in.h>
  20. #include <sys/ioctl.h>
  21. #include <netdb.h> 
  22. #include <sys/socket.h>
  23. #ifndef __BEOS__
  24. #include <netinet/tcp.h>
  25. #include <arpa/inet.h>
  26. #endif
  27. #endif
  28. #ifdef REGEX
  29. #include "gnu_regex.h"
  30. #endif
  31. #include "jcc.h"
  32. int
  33. direct_connect(struct gateway *gw, struct http_request *http, struct client_state *csp)
  34. {
  35. if(gw->forward_host) {
  36. return(connect_to(gw->forward_host, gw->forward_port, csp));
  37. } else {
  38. return(connect_to(http->host, http->port, csp));
  39. }
  40. }
  41. int
  42. atoip(char *host)
  43. {
  44. struct sockaddr_in inaddr;
  45. struct hostent *hostp;
  46. if ((host == NULL) || (*host == '')) 
  47. return(INADDR_ANY);
  48. memset ((char * ) &inaddr, 0, sizeof inaddr);
  49. if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1) {
  50. if ((hostp = gethostbyname(host)) == NULL) {
  51. errno = EINVAL;
  52. return(-1);
  53. }
  54. if (hostp->h_addrtype != AF_INET) {
  55. #ifdef _WIN32
  56. errno = WSAEPROTOTYPE;
  57. #else
  58. errno = EPROTOTYPE;
  59. #endif
  60. return(-1);
  61. }
  62. memcpy((char * ) &inaddr.sin_addr, (char * ) hostp->h_addr,
  63.     sizeof(inaddr.sin_addr));
  64. }
  65. return(inaddr.sin_addr.s_addr);
  66. }
  67. int
  68. connect_to(char *host, int portnum, struct client_state *csp)
  69. {
  70. struct sockaddr_in inaddr;
  71. int fd, addr;
  72. fd_set wfds;
  73. struct timeval tv[1];
  74. int flags;
  75. struct access_control_addr src[1], dst[1];
  76. memset ((char * ) &inaddr, 0, sizeof inaddr);
  77. if((addr = atoip(host)) == -1) return(-1);
  78. src->addr = csp->ip_addr_long;
  79. src->port = 0;
  80. dst->addr = ntohl(addr);
  81. dst->port = portnum;
  82. if(block_acl(src, dst, csp)) {
  83. errno = EPERM;
  84. return(-1);
  85. }
  86. inaddr.sin_addr.s_addr = addr;
  87. inaddr.sin_family      = AF_INET;
  88. if (sizeof(inaddr.sin_port) == sizeof(short)) {
  89. inaddr.sin_port = htons(portnum);
  90. } else {
  91. inaddr.sin_port = htonl(portnum);
  92. }
  93. if((fd = socket(inaddr.sin_family, SOCK_STREAM, 0)) < 0) {
  94. return(-1);
  95. }
  96. #ifdef TCP_NODELAY
  97. { /* turn off TCP coalescence */
  98. int mi = 1;
  99. setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char * ) &mi, sizeof (int));
  100. }
  101. #endif
  102. #ifndef _WIN32
  103. #ifndef __BEOS__
  104. if ((flags = fcntl(fd, F_GETFL, 0)) != -1) {
  105. flags |= O_NDELAY;
  106. fcntl(fd, F_SETFL, flags);
  107. }
  108. #endif
  109. #endif
  110. while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == -1) {
  111. #ifdef _WIN32
  112. if (errno == WSAEINPROGRESS)
  113. #else
  114. if (errno == EINPROGRESS)
  115. #endif
  116. {
  117. break;
  118. }
  119. if (errno != EINTR) {
  120. (void) close (fd);
  121. return(-1);
  122. }
  123. }
  124. #ifndef _WIN32
  125. #ifndef __BEOS__
  126. if (flags != -1) {
  127. flags &= ~O_NDELAY;
  128. fcntl(fd, F_SETFL, flags);
  129. }
  130. #endif
  131. #endif
  132. /* wait for connection to complete */
  133. FD_ZERO(&wfds);
  134. FD_SET(fd, &wfds);
  135. tv->tv_sec  = 30;
  136. tv->tv_usec = 0;
  137. if (select(fd + 1, NULL, &wfds, NULL, tv) <= 0) {
  138. (void) close(fd);
  139. return(-1);
  140. }
  141. return(fd);
  142. }