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

代理服务器

开发平台:

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: daemon.c,v 1.62.2.1.2.11 1998/11/13 16:17:47 steve Exp $
  8.  */
  9. /* This file has the main function in it for socks5, as well as variables    */
  10. /* which most or several modules will use...                                 */
  11. #include "socks5p.h"
  12. #include "threads.h"
  13. #include "daemon.h"
  14. #include "socket.h"
  15. #include "protocol.h"
  16. #include "msgids.h"
  17. #include "log.h"
  18. #ifndef _DECTHREADS_
  19. #define MAXTHREADS 64
  20. #else
  21. #define MAXTHREADS 16
  22. #endif
  23. #ifndef NUMCLIENTS
  24. #define NUMCLIENTS 64
  25. #endif
  26. #ifndef HAVE_SETSID
  27. #ifdef  HAVE_SETPGID
  28. #define setsid() setpgid(0, getpid())
  29. #elif defined(SETPGRP_VOID)
  30. #define setsid() setpgrp()
  31. #else
  32. #define setsid() setpgrp(0, getpid())
  33. #endif
  34. #endif
  35. MUTEX_T lt_mutex  = MUTEX_INITIALIZER; /* localtime mutex    */
  36. MUTEX_T accept_mutex  = MUTEX_INITIALIZER; /* localtime mutex    */
  37. MUTEX_T env_mutex = MUTEX_INITIALIZER; /* *env mutex         */
  38. MUTEX_T gpw_mutex = MUTEX_INITIALIZER; /* getpwd* mutex      */
  39. MUTEX_T gh_mutex  = MUTEX_INITIALIZER; /* gethost* mutex     */
  40. MUTEX_T gs_mutex  = MUTEX_INITIALIZER; /* getserv* mutex     */
  41. int nthreads   = 0;
  42. int nservers   = 0;
  43. int isthreaded = 0;
  44. int servermode = 0;
  45. int idletimeout = 15;
  46. char *bindif   = NULL;
  47. u_short ludpport = 0;
  48. u_short hudpport = 0xffff;
  49. static void version(void) {
  50.     fprintf(stdout, "Socks5 version: %s", SOCKS5_VERSION_NAME);
  51.     exit(0);
  52. }
  53. static void usage(void) {
  54.     fprintf(stderr, "Usage incorrect...n");
  55.     fprintf(stderr, "usage: socks5 ");
  56.     fprintf(stderr, "[-d [X]|--debug [X]] ");
  57.     fprintf(stderr, "[-s|--stderr] ");
  58.     fprintf(stderr, "[-v|--version] ");
  59.     fprintf(stderr, "n");
  60.     fprintf(stderr, "[-b X|--bindintfc X] ");
  61.     fprintf(stderr, "[-f|--foreground] ");
  62.     fprintf(stderr, "[-i|--inetd] ");
  63.     fprintf(stderr, "[-p|--prefork] ");
  64.     fprintf(stderr, "[-o|--oneshot] ");
  65.     fprintf(stderr, "[-t|--threaded] ");
  66.     fprintf(stderr, "[-n X|--nchildren X]");
  67.     fprintf(stderr, "n");
  68.     exit(-1);
  69. }
  70. int main(int argc, char **argv, char **envp) {
  71.     char tbuf[1024];
  72.     int how = S5_LOG_SYSTEM, level = S5_LOG_INFO;
  73.     time_t now = time(NULL);
  74.     int separate = 1;
  75.     IFTHREADED(MUTEX_SETUP(accept_mutex);)
  76.     IFTHREADED(MUTEX_SETUP(env_mutex);)
  77.     IFTHREADED(MUTEX_SETUP(gpw_mutex);)
  78.     IFTHREADED(MUTEX_SETUP(gh_mutex);)
  79.     IFTHREADED(MUTEX_SETUP(gs_mutex);)
  80.     IFTHREADED(MUTEX_SETUP(lt_mutex);)
  81.     for (argc--, argv++; argc > 0; argc--, argv++) {
  82. if (!strncmp(*argv, "-d", strlen("-d")) || !strncmp(*argv, "--debug", strlen("--debug")))  {
  83.             if (*(argv+1) && isdigit((int)**(argv+1))) {
  84.                 level = S5_LOG_DEBUG(atoi(*++argv)); argc--;
  85.             } else level = S5_LOG_DEBUG(25);
  86. } else if (!strcmp(*argv, "-s") || !strcmp(*argv, "--stderr"))   {
  87.     how = S5_LOG_LOCAL;
  88. } else if (!strcmp(*argv, "-i") || !strcmp(*argv, "--inetd"))  {
  89.     servermode = INETD;
  90. } else if (!strcmp(*argv, "-f") || !strcmp(*argv, "--foreground")) {
  91.     separate = 0;
  92. } else if (!strcmp(*argv, "-p") || !strcmp(*argv, "--prefork")) {
  93.     servermode = PREFORKING;
  94. } else if (!strcmp(*argv, "-n") || !strcmp(*argv, "--nchildren")) {
  95.             if (!(*++argv) || !isdigit(**argv)) usage();
  96.             else {
  97.                 nservers = atoi(*argv); argc--;
  98.             }
  99. } else if (!strcmp(*argv, "-b") || !strcmp(*argv, "--bindintfc")) {
  100.             if (!(*++argv)) usage();
  101.             else {
  102.                 bindif = strdup(*argv); argc--;
  103.             }
  104. } else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--version"))   {
  105.     version();
  106. } else if (!strcmp(*argv, "-t") || !strcmp(*argv, "--threaded"))  {
  107.     S5LogShowThreadIDS = 1;
  108.     servermode = THREADED;
  109. } else if (!strcmp(*argv, "-o") || !strcmp(*argv, "--oneshot"))   {
  110.     servermode = SINGLESHOT;
  111.     level      = S5_LOG_DEBUG_MAX;
  112.     how        = S5_LOG_LOCAL;
  113.     separate   = 0;
  114. } else {
  115.     usage();
  116. }
  117.     }
  118.     if (separate && fork() > 0) exit(0);
  119.     chdir("/");
  120.     umask(0);
  121.     setsid();
  122.     nthreads = MIN(MAXOPENS/4 - 1, MAXTHREADS);
  123.     if (nservers == 0) {
  124. if (servermode == THREADED) nservers = NUMCLIENTS/4;
  125. else nservers = MIN(MAXCLIENTS, NUMCLIENTS);
  126.     }
  127. #ifdef RLIMIT_NOFILE
  128.     if (servermode == THREADED) {
  129. struct rlimit rl;
  130.         /* try allow for maxc open file descriptors                          */
  131. if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
  132.     if (rl.rlim_cur < rl.rlim_max) {
  133.      rl.rlim_cur = rl.rlim_max;
  134. #ifndef bsdi
  135.      setrlimit(RLIMIT_NOFILE, &rl);
  136. #endif
  137.     }
  138.     nthreads = MIN(rl.rlim_cur/4 - 1, MAXTHREADS);
  139. }
  140.     }
  141. #endif
  142. #ifdef RLIMIT_NPROC
  143.     if (servermode != INETD) {
  144. struct rlimit rl;
  145. /* try allow for maxc children (or MAXCLIENTS)                       */
  146. if (getrlimit(RLIMIT_NPROC, &rl) == 0 && nservers > rl.rlim_cur && nservers <= rl.rlim_max) {
  147.     rl.rlim_cur = nservers;
  148.     setrlimit(RLIMIT_NPROC, &rl);
  149. }
  150.     }
  151. #endif
  152.     S5LogStart(&S5LogDefaultHandle, how, level, "Socks5");
  153.     /* make sure that number of child processes will not exceed the system    */
  154.     /* limit...                                                               */
  155.     if (nservers > MAXCLIENTS) {
  156.      S5LogUpdate(S5LogDefaultHandle, S5_LOG_INFO, MSGID_SERVER_START, "Requested child process number (%d). Socks5 will use the system limit (%d)", nservers, MAXCLIENTS);
  157. nservers = MAXCLIENTS;
  158.     }
  159.     LIBPREFIX2(init)("Socks5");
  160.     MUTEX_LOCK(lt_mutex);
  161.     strftime(tbuf, sizeof(tbuf), "%c", localtime(&now));
  162.     MUTEX_UNLOCK(lt_mutex);
  163.     switch (servermode) {
  164. case NORMAL:
  165.     strcat(tbuf, " in normal mode");      break;
  166. case INETD:
  167.     strcat(tbuf, " from inetd");          break;
  168. case PREFORKING:
  169.     strcat(tbuf, " in preforking mode");  break;
  170. case SINGLESHOT:
  171.     strcat(tbuf, " in single shot mode"); break;
  172. case THREADED:
  173.     strcat(tbuf, " in threading mode");   break;
  174. default:
  175.     strcat(tbuf, " in unknown mode");     break;
  176.     }
  177.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_INFO, MSGID_SERVER_START, "Socks5 starting at %s", tbuf);
  178.     GetConnection();
  179.     return(-1);
  180. }