s2s.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:5k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* Copyright (c) 1995,1996,1997 NEC Corporation.  All rights reserved.       */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6. /*
  7.  * $Id: s2s.c,v 1.24.4.2 1998/11/02 18:51:50 wlu Exp $
  8.  */
  9. #include "socks5p.h"
  10. #include "daemon.h"
  11. #include "protocol.h"
  12. #include "validate.h"
  13. #include "sident.h"
  14. #include "info.h"
  15. #include "log.h"
  16. /* Not sure when/if this is ever necessary during failed connects...         */
  17. static int Reset(S5IOInfo *info, int otype) {
  18.     S5IOHandle nfd;
  19.     if ((nfd = socket(AF_INET, otype, 0)) == S5InvalidIOHandle) return -1;
  20.     CLOSESOCKET(info->fd);
  21.     info->fd = nfd;
  22.     return 0;
  23. }
  24. int S5SExchangeProtocol(S5IOInfo *iiop, S5IOInfo *oiop, S5LinkInfo *pri, char *ibuf, S5NetAddr *dest, S5NetAddr *resp) {
  25.     int i, rval = -1, optval = 1, optlen = sizeof(int);
  26.     S5NetAddr route;
  27.     u_char errbyte = 0; 
  28.     char effuser[S5_USERNAME_SIZE];
  29.     
  30.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Using proxy (version %d) %s:%d", pri->nextVersion, ADDRANDPORT(&pri->sckAddr));
  31.     if (!pri->nextVersion || !pri->nAltSckAddrs) {
  32. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "S2S: No proxy to connect to.");
  33. return 0;
  34.     }
  35.     GetRoute(&pri->sckAddr, pri->sckName, "tcp", &route);
  36.     if (bind(oiop->fd, &route.sa, lsAddrSize(&route)) == 0) {
  37.         rval = connect(oiop->fd, &pri->sckAddr.sa, lsAddrSize(&pri->sckAddr));
  38.     }
  39.     if (rval < 0 && pri->peerCommand == SOCKS_UDP) { /* multiple server is not supported yet */
  40. S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S: Failed to connected to proxy at %s:%d", ADDRANDPORT(&pri->sckAddr));
  41. goto error;
  42.     } else if (rval < 0) {
  43. S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S: Failed to connected to proxy at %s:%d", ADDRANDPORT(&pri->sckAddr));
  44.         getsockopt(oiop->fd, SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen);
  45.         for (i = 1; i < pri->nAltSckAddrs; i++) {
  46.     if (Reset(oiop, optval) < 0) goto error;
  47.          lsAddrCopy(&pri->sckAddr, &pri->altSckAddrs[i], lsAddrSize(&pri->altSckAddrs[i]));
  48.          GetName(pri->sckName, &pri->sckAddr);
  49.     GetRoute(&pri->sckAddr, pri->sckName, "tcp", &route);
  50.     if (bind(oiop->fd, &route.sa, lsAddrSize(&route)) < 0) goto error;
  51.     if (connect(oiop->fd, &pri->altSckAddrs[i].sa, lsAddrSize(&pri->altSckAddrs[i])) == 0) break;
  52.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S: Failed to connected to proxy at %s:%d", ADDRANDPORT(&pri->altSckAddrs[i]));
  53.         }
  54.         if (i == pri->nAltSckAddrs) goto error;
  55.     }
  56.     if (ibuf) MakeIdentEntry(iiop->fd, oiop->fd, pri, ibuf);
  57.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Connected to proxy %s:%d", ADDRANDPORT(&pri->sckAddr));
  58.     MUTEX_LOCK(gpw_mutex);
  59.     strcpy(effuser, lsEffUser());
  60.     MUTEX_UNLOCK(gpw_mutex);
  61.     if (lsProtoExchg(oiop->fd, oiop, dest, effuser, pri->nextVersion, pri->peerCommand, pri->peerReserved) < 0) {
  62. S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S Protocol exchange with proxy (%s:%d) failed", ADDRANDPORT(&pri->sckAddr));
  63. goto error;
  64.     }
  65.     
  66.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Sent message to proxy (dest %s:%d)", ADDRANDPORT(dest));
  67.     if (lsReadResponse(oiop->fd, oiop, resp, pri->nextVersion, &errbyte, &pri->nextReserved) < 0) {
  68. S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S Recieved bad reply (%d) from proxy (%s:%d)", (int)errbyte, ADDRANDPORT(&pri->sckAddr));
  69. goto error;
  70.     }
  71.     
  72.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Received good reply from proxy");
  73.     /* socks4 often put 0's in the reply's address field so we have to replace them with our */
  74.     /* best guess...                                                                         */
  75.     if (resp->sin.sin_addr.s_addr == INADDR_ANY || resp->sin.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
  76.         resp->sin.sin_addr.s_addr = pri->sckAddr.sin.sin_addr.s_addr;
  77.     }
  78.     return 0;
  79. error:
  80.     SETSOCKETERROR(ECONNREFUSED);
  81.     return -1;
  82. }
  83. int S5SExchgUdpCmd(S5IOHandle io, S5IOInfo *info, S5LinkInfo *pri, u_char version, u_char cmd, u_char *err) {
  84.     u_char flags;
  85.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Exchange UDP command (%d) for address (%s:%d)", (int)cmd, ADDRANDPORT(&pri->dstAddr));
  86.     if (lsSendRequest(io, info, &pri->dstAddr, version, cmd, 0, NULL) < 0) {
  87. S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S Fail to send UDP command");
  88.   return -1;
  89.     }
  90.     return lsReadResponse(io, info, &pri->intAddr, version, err, &flags);
  91. }