proxy_src.txt
上传用户:pumpzc021
上传日期:2007-01-07
资源大小:5k
文件大小:14k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. [本讨论区] [返回首页] [分类讨论区] [全部讨论区]   讨论区
  2. [上一篇] [下一篇]
  3. 发信人: stwzyang (hook), 信区: Winsock 
  4. 标  题: Proxy source code 
  5. 发信站: BBS 水木清华站 (Sat Jan  3 04:14:04 1998) 
  6.  
  7.  
  8. /**************************************************************************** 
  9.   program:      proxyd 
  10.   module:       proxyd.c 
  11.   summary:      provides proxy tcp service for a host on an isolated network. 
  12.  
  13.   programmer:   Carl Harris (ceharris@vt.edu) 
  14.   date:         22 Feb 94 
  15.    
  16.   description:   
  17.         This code implements a daemon process which listens for tcp connec- 
  18.         tions on a specified port number.  When a connection is established,  
  19.         a child is forked to handle the new client.  The child then estab- 
  20.         lishes a tcp connection to a port on the isolated host.  The child 
  21.         then falls into a loop in which it writes data to the isolated host 
  22.         for the client and vice-versa.  Once a child has been forked, the  
  23.         parent resumes listening for additional connections. 
  24.  
  25.         The name of the isolated host and the port to serve as proxy for,  
  26.         as well as the port number the server listen on are specified as 
  27.         command line arguments. 
  28.  ****************************************************************************/ 
  29.  
  30.  
  31. #include <stdio.h> 
  32. #include <ctype.h> 
  33. #include <errno.h> 
  34. #include <signal.h> 
  35. #include <sys/types.h> 
  36. #include <sys/socket.h> 
  37. #include <sys/file.h> 
  38. #include <sys/ioctl.h>  
  39. #include <sys/wait.h> 
  40. #include <netinet/in.h> 
  41. #include <netdb.h> 
  42.  
  43.  
  44. #define  TCP_PROTO      "tcp" 
  45.  
  46. int proxy_port;                 /* port to listen for proxy connections on */ 
  47. struct sockaddr_in hostaddr;    /* host addr assembled from gethostbyname() */ 
  48.  
  49. extern int errno;               /* defined by libc.a */ 
  50. extern char *sys_errlist[];     /* defined by libc.a */ 
  51.  
  52.  
  53. void parse_args (int argc, char **argv); 
  54. void daemonize (int servfd); 
  55. void do_proxy (int usersockfd); 
  56. void reap_status (void); 
  57. void errorout (char *msg);  
  58.  
  59.  
  60.  
  61. /**************************************************************************** 
  62.   function:      main 
  63.   description:   Main level driver.  After daemonizing the process, a socket 
  64.                  is opened to listen for connections on the proxy port,  
  65.                  connections are accepted and children are spawned to handle  
  66.                  each new connection. 
  67.   arguments:      
  68.     argc,argv    you know what those are. 
  69.  
  70.   return value:  none. 
  71.   calls:         parse_args, do_proxy. 
  72.   globals:       reads proxy_port. 
  73.  ****************************************************************************/ 
  74.  
  75. main (argc,argv)  
  76. int argc; 
  77. char **argv; 
  78.   int clilen; 
  79.   int childpid; 
  80.   int sockfd, newsockfd; 
  81.   struct sockaddr_in servaddr, cliaddr; 
  82.  
  83.   parse_args(argc,argv); 
  84.  
  85.   /* prepare an address struct to listen for connections */ 
  86.   bzero((char *) &servaddr, sizeof(servaddr)); 
  87.   servaddr.sin_family = AF_INET; 
  88.   servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
  89.   servaddr.sin_port = proxy_port; 
  90.  
  91.   /* get a socket... */ 
  92.   if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { 
  93.     fputs("failed to create server socketrn",stderr); 
  94.     exit(1); 
  95.   } 
  96.  
  97.   /* ...and bind our address and port to it */ 
  98.   if (bind(sockfd,(struct sockaddr_in *) &servaddr,sizeof(servaddr)) < 0) { 
  99.     fputs("faild to bind server socket to specified portrn",stderr); 
  100.     exit(1); 
  101.   } 
  102.  
  103.   /* get ready to accept with at most 5 clients waiting to connect */ 
  104.   listen(sockfd,5); 
  105.    
  106.   /* turn ourselves into a daemon */ 
  107.   daemonize(sockfd); 
  108.  
  109.   /* fall into a loop to accept new connections and spawn children */ 
  110.   while (1) { 
  111.  
  112.     /* accept the next connection */ 
  113.     clilen = sizeof(cliaddr); 
  114.     newsockfd = accept(sockfd, (struct sockaddr_in *) &cliaddr, &clilen); 
  115.     if (newsockfd < 0 && errno == EINTR) 
  116.       continue;    /* a signal might interrupt our accept() call */ 
  117.     else if (newsockfd < 0) 
  118.       /* something quite amiss -- kill the server */ 
  119.       errorout("failed to accept connection"); 
  120.      
  121.     /* fork a child to handle this connection */ 
  122.     if ((childpid = fork()) == 0) { 
  123.       close(sockfd); 
  124.       do_proxy(newsockfd); 
  125.       exit(0); 
  126.     } 
  127.  
  128.     /* if fork() failed, the connection is silently dropped -- oops! */ 
  129.  
  130.     close(newsockfd); 
  131.   } 
  132.  
  133.  
  134.  
  135. /**************************************************************************** 
  136.   function:      parse_args 
  137.   description:   parse the command line args. 
  138.   arguments: 
  139.     argc,argv    you know what these are. 
  140.  
  141.   return value:  none. 
  142.   calls:         none. 
  143.   globals:       writes proxy_port, writes hostaddr. 
  144.  ****************************************************************************/ 
  145.  
  146. void parse_args (argc,argv) 
  147. int argc; 
  148. char **argv; 
  149.   int i; 
  150.   struct hostent *hostp; 
  151.   struct servent *servp; 
  152.   unsigned long inaddr; 
  153.   struct { 
  154.     char proxy_port [16]; 
  155.     char isolated_host [64]; 
  156.     char service_name [32]; 
  157.   } pargs; 
  158.     
  159.  
  160.   if (argc < 4) { 
  161.     printf("usage:  %s <proxy-port> <host> <service-name|port-number>rn", 
  162.            argv[0]); 
  163.     exit(1); 
  164.   } 
  165.  
  166.   strcpy(pargs.proxy_port,argv[1]); 
  167.   strcpy(pargs.isolated_host,argv[2]); 
  168.   strcpy(pargs.service_name,argv[3]); 
  169.  
  170.   for (i = 0;  i < strlen(pargs.proxy_port);  i++)  
  171.     if (!isdigit(*(pargs.proxy_port + i)))  
  172.       break; 
  173.   
  174.   if (i == strlen(pargs.proxy_port)) 
  175.     proxy_port = htons(atoi(pargs.proxy_port)); 
  176.   else { 
  177.     printf("%s: invalid proxy portrn",pargs.proxy_port); 
  178.     exit(0); 
  179.   } 
  180.      
  181.   bzero(&hostaddr,sizeof(hostaddr)); 
  182.   hostaddr.sin_family = AF_INET; 
  183.   if ((inaddr = inet_addr(pargs.isolated_host)) != INADDR_NONE) 
  184.     bcopy(&inaddr,&hostaddr.sin_addr,sizeof(inaddr)); 
  185.   else if ((hostp = gethostbyname(pargs.isolated_host)) != NULL) 
  186.     bcopy(hostp->h_addr,&hostaddr.sin_addr,hostp->h_length); 
  187.   else { 
  188.     printf("%s: unknown hostrn",pargs.isolated_host); 
  189.     exit(1); 
  190.   } 
  191.      
  192.   if ((servp = getservbyname(pargs.service_name,TCP_PROTO)) != NULL) 
  193.     hostaddr.sin_port = servp->s_port; 
  194.   else if (atoi(pargs.service_name) > 0)  
  195.     hostaddr.sin_port = htons(atoi(pargs.service_name)); 
  196.   else { 
  197.     printf("%s: invalid/unknown service name or port numberrn", 
  198.            pargs.service_name); 
  199.     exit(1); 
  200.   } 
  201.  
  202.  
  203.  
  204. /**************************************************************************** 
  205.   function:      daemonize 
  206.   description:   detach the server process from the current context,  
  207.                  creating a pristine, predictable environment in which it 
  208.                  will execute. 
  209.   arguments: 
  210.     servfd       file descriptor in use by server. 
  211.  
  212.   return value:  none. 
  213.   calls:         none. 
  214.   globals:       none. 
  215.  ****************************************************************************/ 
  216.  
  217. void daemonize (servfd) 
  218. int servfd; 
  219.   int childpid, fd, fdtablesize; 
  220.  
  221.   /* ignore terminal I/O, stop signals */ 
  222.   signal(SIGTTOU,SIG_IGN); 
  223.   signal(SIGTTIN,SIG_IGN); 
  224.   signal(SIGTSTP,SIG_IGN); 
  225.  
  226.   /* fork to put us in the background (whether or not the user  
  227.      specified '&' on the command line */ 
  228.  
  229.   if ((childpid = fork()) < 0) { 
  230.     fputs("failed to fork first childrn",stderr); 
  231.     exit(1); 
  232.   } 
  233.   else if (childpid > 0) 
  234.     exit(0);    /* terminate parent, continue in child */ 
  235.  
  236.   /* dissociate from process group */ 
  237.   if (setpgrp(0,getpid()) < 0) { 
  238.     fputs("failed to become process group leaderrn",stderr); 
  239.     exit(1); 
  240.   } 
  241.  
  242.   /* lose controlling terminal */ 
  243.   if ((fd = open("/dev/tty",O_RDWR)) >= 0) { 
  244.     ioctl(fd,TIOCNOTTY,NULL);    
  245.     close(fd); 
  246.   } 
  247.  
  248.   /* close any open file descriptors */ 
  249.   for (fd = 0, fdtablesize = getdtablesize();  fd < fdtablesize;  fd++)  
  250.     if (fd != servfd)  
  251.       close(fd); 
  252.  
  253.   /* set working directory to / to allow filesystems to be unmounted */ 
  254.   chdir("/"); 
  255.  
  256.   /* clear the inherited umask */ 
  257.   umask(0); 
  258.  
  259.   /* setup zombie prevention */ 
  260.   signal(SIGCLD,reap_status); 
  261.  
  262.  
  263.  
  264.  
  265. /**************************************************************************** 
  266.   function:      do_proxy 
  267.   description:   does the actual work of virtually connecting a client to 
  268.                  the telnet service on the isolated host. 
  269.   arguments:      
  270.     usersockfd   socket to which the client is connected. 
  271.  
  272.   return value:  none. 
  273.   calls:         none. 
  274.   globals:       reads hostaddr. 
  275.  ****************************************************************************/ 
  276.  
  277. void do_proxy (usersockfd)   
  278. int usersockfd; 
  279.   int isosockfd; 
  280.   fd_set rdfdset; 
  281.   int connstat; 
  282.   int iolen; 
  283.   char buf [2048]; 
  284.    
  285.   /* open a socket to connect to the isolated host */ 
  286.   if ((isosockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) 
  287.     errorout("failed to create socket to host"); 
  288.   
  289.   /* attempt a connection */ 
  290.   connstat = connect(isosockfd,  
  291.                      (struct sockaddr *) &hostaddr,  
  292.                      sizeof(hostaddr)); 
  293.   switch (connstat) { 
  294.     case 0: 
  295.       break; 
  296.     case ETIMEDOUT: 
  297.     case ECONNREFUSED: 
  298.     case ENETUNREACH: 
  299.       strcpy(buf,sys_errlist[errno]); 
  300.       strcat(buf,"rn"); 
  301.       write(usersockfd,buf,strlen(buf)); 
  302.       close(usersockfd); 
  303.       exit(1);  /* die peacefully if we can't establish a connection */ 
  304.       break; 
  305.     default: 
  306.       errorout("failed to connect to host"); 
  307.   } 
  308.  
  309.  
  310.   /* now we're connected, serve fall into the data echo loop */ 
  311.   while (1) { 
  312.     /* Select for readability on either of our two sockets */ 
  313.     FD_ZERO(&rdfdset); 
  314.     FD_SET(usersockfd,&rdfdset); 
  315.     FD_SET(isosockfd,&rdfdset); 
  316.     if (select(FD_SETSIZE,&rdfdset,NULL,NULL,NULL) < 0) 
  317.       errorout("select failed"); 
  318.        
  319.     /* is the client sending data? */ 
  320.     if (FD_ISSET(usersockfd,&rdfdset)) { 
  321.       if ((iolen = read(usersockfd,buf,sizeof(buf))) <= 0) 
  322.         break;   /* zero length means the client disconnected */ 
  323.        
  324.       write(isosockfd,buf,iolen);   /* copy to host -- blocking semantics */ 
  325.     } 
  326.  
  327.     /* is the host sending data? */ 
  328.     if (FD_ISSET(isosockfd,&rdfdset)) { 
  329.       if ((iolen = read(isosockfd,buf,sizeof(buf))) <= 0) 
  330.         break;   /* zero length means the host disconnected */ 
  331.   
  332.       write(usersockfd,buf,iolen);  /* copy to client -- blocking semantics */ 
  333.     } 
  334.   } 
  335.  
  336.   /* we're done with the sockets */ 
  337.   close(isosockfd); 
  338.   close(usersockfd); 
  339.  
  340.        
  341.  
  342. /**************************************************************************** 
  343.   function:      errorout 
  344.   description:   displays an error message on the console and kills the 
  345.                  current process. 
  346.   arguments:      
  347.     msg          message to be displayed. 
  348.  
  349.   return value:  none -- does not return. 
  350.   calls:         none. 
  351.   globals:       none. 
  352.  ****************************************************************************/ 
  353.  
  354. void errorout (msg) 
  355. char *msg; 
  356.   FILE *console; 
  357.  
  358.   console = fopen("/dev/console","a"); 
  359.   fprintf(console,"proxyd: %srn",msg); 
  360.   fclose(console); 
  361.   exit(1); 
  362.    
  363.  
  364.        
  365. /**************************************************************************** 
  366.   function:      reap_status 
  367.   description:   handle a SIGCLD signal by reaping the exit status of the 
  368.                  perished child, and discarding it. 
  369.   arguments:     none. 
  370.   return value:  none. 
  371.   calls:         none. 
  372.   globals:       none. 
  373.  ****************************************************************************/ 
  374.  
  375. void reap_status () 
  376.   int pid; 
  377.   union wait status; 
  378.  
  379.   while ((pid = wait3(&status,WNOHANG,NULL)) > 0) 
  380.     ;  /* loop while there are more dead children */ 
  381.  
  382.  
  383. -- 
  384. ※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.193.65.100] 
  385. 发信人: stwzyang (hook), 信区: Winsock 
  386. 标  题: About Proxy source code (转帖) 
  387. 发信站: BBS 水木清华站 (Sat Jan  3 04:19:25 1998) 
  388.  
  389. 偶在网上得此proxyd,先post出来,再慢慢研究。。。 
  390.  
  391. 17 Dev 1997 
  392.  
  393. Author:         Carl Harris (ceharris@vt.edu) 
  394. Compiler:       TjL <luomat@peak.org> 
  395.  
  396. Compiled by: 
  397. cc -O2  -object -s  
  398.         -arch m68k -arch i386 -arch hppa -arch sparc  
  399.         proxyd.c -o proxyd 
  400.  
  401.  
  402. This is a little daemon I felt was useful and was able to compile, so I thought 
  403. I would make it available. 
  404.  
  405. I did not write this!  I am just compiling and distributing. The source code had 
  406. no restrictions on doing so. 
  407.  
  408. All I know as far as how to use it is what it says: 
  409.  
  410. usage: proxyd <proxy-port> <host> <service-name|port-number> 
  411.  
  412. Which means: 
  413.  
  414. proxyd localport-on-this-machine the-host-this-is-to  port-or-name 
  415.  
  416. EXAMPLE: 
  417.  
  418. Say you have a machine named MYHOST want to bind your port #777 to the TELNET 
  419. port of the host REMOTEHOST. 
  420.  
  421. Use: proxyd 777 REMOTEHOST telnet 
  422.  
  423. Then if you did 'telnet MYHOST 777' you would actually connect to the TELNET 
  424. port of the host REMOTEHOST. 
  425.  
  426. As far as the 'service-name/port-number' goes: services can be referred to 
  427. either by a number or a name.  For example, NNTP requests are usually on port 
  428. 119, so if you wanted to connect directly to a machine to do NNTP you could do 
  429. either: 
  430.  
  431. telnet REMOTEHOST nntp 
  432.         or 
  433. telnet REMOTEHOST 119    
  434.  
  435.  
  436. NOTE/WARNING: Make sure to use an unused port on your machine!  If you are not 
  437. sure, do this: 
  438.  
  439.  nidump services . 
  440.  
  441. to see a listing of all the services known on your machine. 
  442.  
  443. This program does NOT always have to be run as root... Some ports are available 
  444. even to regular users, it appears. 
  445.   
  446.   
  447.  
  448. -- 
  449. ※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.193.65.100] 
  450. [上一篇] [下一篇]
  451. [本讨论区] [返回首页] [分类讨论区] [全部讨论区]   讨论区