socket轉發程序

#include <pthread.h> 
 #include <openssl/x509v3.h> 
 #include <fcntl.h> 
 #include <stdio.h> 
 #include <stdlib.h> 
 #include <errno.h> 
 #include <sys/types.h> 
 #include <netinet/in.h> 
 #include <sys/socket.h> 
 #include <sys/wait.h> 
 #include <string.h> 
 #include <semaphore.h> 
 #include <netdb.h> 
 #include <unistd.h> 
 #include <arpa/inet.h> 
   #define MAXSIZE     65535    //最大接收和發送字節 
   #define uint16      unsigned short 
 #define uint8       unsigned char 
 #define uint32      unsigned int 
   #define PERROR { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); } 
 #define EXIT_PERROR { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); exit(errno); } 
 #define CONTINUE_PERROR { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); continue; } 
 #define BREAK_PERROR { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); break; } 
 #define RETURN_PERROR(X) { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); return (X); } 
   #define max(x,y)            ((x>y) ? x:y) 
   static unsigned int packet_count = 0; 
   void init_signal() 
 { 
     int i=0; 
     for(i; i<=64; i++){ 
         signal( i, SIG_IGN ); 
     } 
 } 
   void init_daemon(){ 
     if( fork() != 0 ){ 
         exit(0); 
     } 
     setsid(); 
     if( fork() != 0 ){ 
         exit(0); 
     } 
 } 
   void set_keepalive(int fd) 
 { 
         int val = 1; 
         int nRet = setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,&val,sizeof(val)); 
         if(nRet < 0) { 
                 perror( strerror(errno) ); 
                 return; 
         } 
           return; 
 } 
   int writing(int fd, const void *vptr, int n ) 
 { 
     int nwritten; 
     int nleft = n; 
     const char *ptr=(char*)vptr; 
     while(nleft > 0){ 
         if( (nwritten = write(fd,ptr,nleft)) <= 0){ 
             if( errno == EINTR ){ 
                 nwritten =0; 
             }else{ 
                 return -1; 
             } 
         } 
         nleft -= nwritten; 
         ptr += nwritten; 
     } 
     return n; 
 } 
 /* read file */ 
 static int read_file(char *filename, unsigned char *buffer, int maxlen) { 
     int fd,len; 
       if ( (fd = open(filename, O_RDONLY)) == -1) { 
         perror( filename ); 
         return -1; 
     } 
     len = read (fd, buffer, maxlen); 
     close(fd); 
     return len; 
 } 
   /* 
  * 
  */ 
 void * forwarding(void *argv){ 
     int conn_clientfd = ((int*)argv)[0]; 
     int conn_serverfd = ((int*)argv)[1]; 
     int maxfd = max( conn_clientfd, conn_serverfd ); 
     int i = 0; 
     fd_set fdread; 
     FD_ZERO(&fdread); 
     unsigned char buffer[MAXSIZE]={0}; 
     int nreceived = 0; 
     int nwritten = 0; 
       while(1) { 
         FD_SET(conn_clientfd, &fdread); 
         FD_SET(conn_serverfd, &fdread); //鏈接到rdp服務器端的socket 
         int ret=select( maxfd+1 ,&fdread,NULL,NULL,NULL); 
         if( ret < 0 ) BREAK_PERROR; 
          
         ret = FD_ISSET(conn_serverfd,&fdread); 
         if( ret < 0 ) BREAK_PERROR \ 
         else if( ret > 0 ){ //traffic from RDP client 
             nreceived = read(conn_serverfd,buffer,MAXSIZE); 
             if(nreceived < 0){ 
                 if(errno == EINTR) CONTINUE_PERROR; 
                 BREAK_PERROR; 
             } 
             if(nreceived == 0) break; 
              
             printf("#seq %d from client to server\n",packet_count++); 
             nwritten = writing( conn_clientfd, buffer, nreceived ); 
             if( nwritten < 0 || nwritten != nreceived ) BREAK_PERROR; 
         } 
          
         ret = FD_ISSET(conn_clientfd,&fdread); 
         if( ret < 0 ) BREAK_PERROR \ 
         else if( ret > 0 ){ 
             nreceived = read(conn_clientfd, buffer, MAXSIZE ); 
             if( nreceived < 0 ){ 
                 if( errno == EINTR ) CONTINUE_PERROR; 
                 BREAK_PERROR; 
             } else if( nreceived == 0 ){ 
                 break; 
             } 
             printf("#seq %d from server to client\n",packet_count++); 
             int nwritten = writing( conn_serverfd, buffer, nreceived ); 
             if( nwritten < 0 || nwritten!=nreceived ) BREAK_PERROR; 
         } 
     } 
     close(conn_clientfd); 
     close(conn_serverfd); 
     exit(0); 
 } 
   int Listen(const char *ip,const char *port){ 
     int listenfd = socket(AF_INET,SOCK_STREAM,0); 
     if( listenfd < 0 ){ 
         perror("Listen() Failed to create socket\n" ); 
         exit(errno); 
     } 
     struct sockaddr_in listenaddr; 
     bzero( &listenaddr, sizeof(listenaddr) ); 
     listenaddr.sin_family = AF_INET; 
     listenaddr.sin_port = htons( atoi( port ) ); 
     int ret = inet_pton( AF_INET, ip, &listenaddr.sin_addr ); 
     if( ret < 0 ) EXIT_PERROR; 
     int optval = 1; 
     ret = setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval) ); 
     if( ret < 0 ) EXIT_PERROR; 
     ret = bind( listenfd, (struct sockaddr*)&listenaddr, sizeof( listenaddr ) ); 
     if( ret < 0 ) EXIT_PERROR; 
     ret = listen( listenfd, 16 ); 
     if( ret < 0 ) EXIT_PERROR; 
       return listenfd; 
 } 
   int Connect(const char *ip, const char *port) 
 { 
     int clientfd = socket(AF_INET,SOCK_STREAM,0); 
     if( clientfd < 0 ) RETURN_PERROR(-1); 
     struct sockaddr_in addr; 
     bzero(&addr, sizeof(addr) ); 
     addr.sin_family = AF_INET; 
     addr.sin_port = htons( atoi( port ) ); 
     int ret = inet_pton( AF_INET, ip, &addr.sin_addr ); 
     if( ret <= 0 ) RETURN_PERROR(-1); 
     ret = connect( clientfd, (struct sockaddr*)&addr, sizeof(addr) ); 
     if( ret < 0 ) RETURN_PERROR(-1); 
     return clientfd; 
 } 
   int main(int argc,char* argv[]){ 
     int listenerfd,conn_serverfd,conn_clientfd; 
     struct sockaddr_in     localaddr; 
     struct sockaddr_in     clientaddr; 
       
     char localport[8]={0};//本地監聽端口 
     char remoteip[20]={0};//遠程ip 
     char remoteport[8]={0};//遠程端口 
       int i=0; 
       /* config */ 
     FILE *fd; 
     if((fd = fopen("./conf","r"))== NULL) EXIT_PERROR; 
     fscanf(fd,"localport:%s\nremoteip:%s\nremoteport:%s\n", localport,remoteip,remoteport); 
      
     /* initialize */ 
     init_daemon(); 
     init_signal(); 
      
     /* listening */ 
     listenerfd = Listen( "localhost" , localport ); 
     while(1){ 
         conn_serverfd = accept(listenerfd,NULL,NULL); 
         if( conn_serverfd < 0 ) CONTINUE_PERROR; 
         conn_clientfd = Connect( remoteip, remoteport ); 
         if( conn_clientfd < 0 ){ 
             close( conn_serverfd ); 
             CONTINUE_PERROR; 
         } 
         printf( "serverfd:%d,clientfd:%d\n", conn_serverfd, conn_clientfd ); 
         set_keepalive( conn_clientfd ); 
         set_keepalive( conn_serverfd ); 
         if( fork() == 0 ){ 
             pthread_t tid1,tid2; 
             int conn_socks[2]; 
             conn_socks[0] = conn_clientfd; 
             conn_socks[1] = conn_serverfd; 
             pthread_create( &tid1, NULL, forwarding , conn_socks ); 
             pthread_join( tid1, NULL ); 
             exit(0); 
         } 
         close( conn_serverfd ); 
         close( conn_clientfd ); 
     } 
     close( listenerfd ); 
     return 0; 
 }
相關文章
相關標籤/搜索