socket.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:4k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1997, 1998, 1999
  3.  *      Inferno Nettverk A/S, Norway.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. The above copyright notice, this list of conditions and the following
  9.  *    disclaimer must appear in all copies of the software, derivative works
  10.  *    or modified versions, and any portions thereof, aswell as in all
  11.  *    supporting documentation.
  12.  * 2. All advertising materials mentioning features or use of this software
  13.  *    must display the following acknowledgement:
  14.  *      This product includes software developed by
  15.  *      Inferno Nettverk A/S, Norway.
  16.  * 3. The name of the author may not be used to endorse or promote products
  17.  *    derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * Inferno Nettverk A/S requests users of this software to return to
  31.  *
  32.  *  Software Distribution Coordinator  or  sdc@inet.no
  33.  *  Inferno Nettverk A/S
  34.  *  Oslo Research Park
  35.  *  Gaustadal閑n 21
  36.  *  N-0349 Oslo
  37.  *  Norway
  38.  *
  39.  * any improvements or extensions that they make and grant Inferno Nettverk A/S
  40.  * the rights to redistribute these changes.
  41.  *
  42.  */
  43. #include "common.h"
  44. static const char rcsid[] =
  45. "$Id: socket.c,v 1.25 1999/12/20 13:07:41 karls Exp $";
  46. int
  47. socks_connect(s, host)
  48. int s;
  49. const struct sockshost_t *host;
  50. {
  51. const char *function = "socks_connect()";
  52. int new_s;
  53. struct hostent *hostent;
  54. struct sockaddr_in address;
  55. char **ip;
  56. bzero(&address, sizeof(address));
  57. address.sin_family = AF_INET;
  58. address.sin_port = host->port;
  59. switch (host->atype) {
  60. case SOCKS_ADDR_IPV4:
  61. address.sin_addr = host->addr.ipv4;
  62. /* LINTED pointer casts may be troublesome */
  63. return connect(s, (struct sockaddr *)&address, sizeof(address));
  64. case SOCKS_ADDR_DOMAIN:
  65. if ((hostent = gethostbyname(host->addr.domain)) == NULL)
  66. slog(LOG_DEBUG, "%s: gethostbyname(%s): %s",
  67. function, host->addr.domain, hstrerror(h_errno));
  68. break;
  69. default:
  70. SERRX(host->atype);
  71. }
  72. if (hostent == NULL)
  73. return -1;
  74. new_s = -1;
  75. ip = hostent->h_addr_list;
  76. do {
  77. if (new_s == -1)
  78. new_s = s; /* try to use given descriptor before creating our own. */
  79. else
  80. if ((new_s = socketoptdup(s)) == -1)
  81. return -1;
  82. /* LINTED pointer casts may be troublesome */
  83. address.sin_addr = *((struct in_addr *)*ip);
  84. /* LINTED pointer casts may be troublesome */
  85. if (connect(new_s, (struct sockaddr *)&address, sizeof(address)) == 0)
  86. break;
  87. if (new_s != s)
  88. close(new_s);
  89. /*
  90.  * Only try next address if errno indicates server/network error.
  91.  */
  92. switch (errno) {
  93. case ETIMEDOUT:
  94. case EINVAL:
  95. case ECONNREFUSED:
  96. case ENETUNREACH:
  97. break;
  98. default:
  99. return -1;
  100. }
  101. } while (ip != NULL && *++ip != NULL);
  102. if (ip == NULL || *ip == NULL)
  103. return -1; /* list exhausted, no successful connect. */
  104. if (new_s != s) { /* had to create a new socket of our own. */
  105. if (dup2(new_s, s) == -1) {
  106. close(new_s);
  107. return -1;
  108. }
  109. close(new_s);
  110. #if SOCKS_SERVER && HAVE_LIBWRAP
  111. if ((new_s = fcntl(s, F_GETFD, 0)) == -1
  112. || fcntl(s, F_SETFD, new_s | FD_CLOEXEC) == -1)
  113. swarn("%s: fcntl(F_GETFD/F_SETFD)", function);
  114. #endif
  115. }
  116. return 0;
  117. }
  118. int
  119. acceptn(s, addr, addrlen)
  120. int s;
  121. struct sockaddr *addr;
  122. socklen_t *addrlen;
  123. {
  124. int rc;
  125. while ((rc = accept(s, addr, addrlen)) == -1 && errno == EINTR)
  126. ;
  127. return rc;
  128. }