#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; }