⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy.c

📁 代理服务器程序 将代理器的proxy_port端口绑定到remote_host的service_port端口.
💻 C
字号:
#include<stdio.h>#include<ctype.h>#include<errno.h>#include<signal.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/file.h>#include<sys/ioctl.h>#include<sys/wait.h>#include<netinet/in.h>#include<netdb.h>#define TCP_PROTO "TCP"/*extern variable*/int proxy_port ;      /*port to listen for proxy connections on */struct sockaddr_in hostaddr ;  /*host address from gethostbyname */extern int errno ;     /*defined by libc.a*/extern_const char*_const sys_errlist[] ; /*defined by libc.a*//*Thoese function define in back of main()  */void parse_args(int argc, char**argv) ;   /*Analysis command line parameter*/void daemonize(int servfd) ;    /*become into protect process*/void do_proxy(int usersockfd) ;   /* Realize function of proxy  */void reap_status() ;     /*capture signal of SIGCHLD,process dead proecss*/void errorout(char *msg) ;   /*output error *//*function main()*/main(int argc, char **argv){	int opt, len ;	int clilen ;	int childpid ;	int sockfd, newsockfd ;	struct sockaddr_in servaddr, cliaddr ;   /*information structure*/		parse_args(argc, argv) ;/*analysis command parameter ,to get port of protect and information of the remote host */			bzero((char*)&servaddr, sizeof(servaddr)) ;  /*initate server address*/		servaddr.sin_family = AF_INET ;	servaddr.sin_addr.s_addr=htonl(INADDR_ANY) ;     /*system will automatic fill ip informtion of this computer*/	servaddr.sin_port = proxy_port ;			if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0){		fputs("failed to create server socket\r\n",stderr) ;     /* stderr where are from*/	exit(1) ;	}		/*below will bind port*/	opt = 1; 	len = sizeof(opt) ;    /*this two variable will be,used in setsockopt*/	setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,&len) ; /*ensure when proxyd restart ,port of beginning will avilable */		if(bind(sockfd, (struct sockaddr_in)&servaddr, sizeof(servaddr)) < 0){		fputs("faild to bind server socket to specified port\r\n",stderr) ;		exit(1) ;			}		/*get ready to accept with at most 10 clients waiting to connect */	listen(sockfd,10) ;	daemonize(sockfd) ;  /*become into protect process*/		signal(SIGCHLD,reap_status) ;     /*capture terminal signal of child process */			/*below is circle of accept ,using a child process to deal with to per-child process*/	for(;;){		/*accept the next connection*/	clilen = sizeof(cliaddr) ;	newsockfd = accept(sockfd,(struct sockaddr_in)&cliaddr, &clilen) ;    /*waiting for client to connecting*/			if(newsockfd < 0 && errno == EINTR)		continue ;               /*a signal might interrpt out accept() call*/	else if(newsockfd < 0)		errorout("failed to accept connection") ;    /*something quite amiss --kill the server,accept executive failed*/					/*fork a child to handle this connection*/	if((childpid=fork())==0){          /*if childpid=0 ,is a child process*/		close(sockfd) ;         /*close listen socket of parent process */		do_proxy(newsockfd) ;   /*newsockfd is a waiting accept socket*/		exit(0) ;	}		close(newsockfd) ;   /*newsockfd is no use for parent,so close it*/	}/*for*/}void parse_args(int argc, char **argv){	int i ;	struct hostent *hostp ;    /*use for client*/	struct servent *servp ;    /*use for server*/	unsigned long inaddr ;		struct{		char proxy_port[16] ;   /*save port of proxy*/		char isolated_host[64] ;  		char service_name[32] ;	}pargs ;	if(argc<4){		printf("usage:%s<proxy-port><host><service-name|port-number>\r\n",argv[0]) ;			}	strcpy(pargs.proxy_port, argv[1]) ;	strcpy(pargs.isolated_host,argv[2]) ;	strcpy(pargs.service_name, argv[3]) ;	for(i = 0 ; i < strlen(pargs.proxy_port) ; i++)		if(!isdigit(*(pargs.proxy_port+i)))			break ;                 /*if not a number */		if(i == strlen(pargs.proxy_port))		proxy_port = htons(atoi(pargs.proxy_port)) ;    /*atoi :string to int*/	else{		printf("%s:invalid proxy port",pargs.proxy_port) ;		exit(0) ;                                    /*if invalid */	}		bzero(&hostaddr, sizeof(hostaddr)) ;		hostaddr.sin_family = AF_INET ;	if((inaddr = inet_addr(pargs.isolated_host))!=INADDR_NONE)    /*if pargs.isoslated_host is a ip*/		bcopy(&inaddr, &hostaddr.sin_addr, sizeof(inaddr)) ;      /*inaddr is a unsigned long*/								/*extern-struct sockaddr_in hostaddr*/	else if((hostp = gethostbyname(pargs.isolated_host))!=NULL)     /*struct hostent *hostp*/		bcopy(hostp->h_addr,&hostddr.sin_addr,hostp->h_length) ;	else{		printf("%s:invalid/unknown service name or port number\r\n",pargs.service_name) ;		exit(1) ;	}	/*have fill with hostaddr structure,this structure will be used in do_proxy*/		}	/*funtion: daemonize*//*this funtion let listen process become daemonize*/void daemonize(int servfd){	int childpid, fd, fdtablesize ;  		/*ignore terminal I/O ,stop signals*/	signal(SIGTTOU,SIG_IGN) ;	signal(SIGTTIN,SIG_IGN) ;	signal(SIGTSTP,SIG_IGN) ;		/*fork to put us in the background()*/	if((childpid = fork()) < 0){		fputs("failed to fork first child\r\n",stderr) ;		exit(1) ;	}	else if(childpid > 0)		exit(0) ;		/*terminate parent, continue in child*/	setsid() ;  /*set child process to group process*/		/*child process escape from terminate*/	signal(SIGHUP,SIG_IGN) ;		if(pid = fork())		exit(0) ;    /*kill first child process, create second child process ,to get child process cann't open controling terminate*/		for(fd = 0, fdtablesize = getdtablesize() ; fd < fdtablesize ; fd++)		if(fd != servfd)			close(fd) ;		chdir("/") ;   /*set working directory to / to allow file systems to be unmounted*/		umask(0) ;     /*clear the inherited umask*/}void do_proxy(int usersockfd){    /*usersockfd is a accept sockfd that have set in client of sides*/int isosockfd ;fd_set rdfdset ;   /*declare a new file description */int connstat ;int iolen ;char buf[2048] ;   /*get error information*//*open a socket to connect ot the isolated host*//*this is to connect to server*/if((isosockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)	errorout("failed to create socket host") ;connstat = connect(isosockfd, (struct sockaddr*)&hostaddr, sizeof(hostaddr)) ;    /*hostaddr is a struct sockaddr_in*/	switch(connstat){	case 0:               /*it will return 0,if sucessfull*/		break ;	case ETIMEDOUT:	case ECONNREFUSED:	case ENETUNREACH:		strcpy(buf, sys_errlist[errno]) ;   /*errno is extern int*/		strcat(buf,"\r\n") ;		write(usersockfd,buf, strlen(buf)) ;  /*this is doing*/		close(usersockfd) ;		exit(1) ;   /*die peacefully if we can't establish a connection*/		break ;	default:		errorout("failed to connect to host") ;	}	for(;;){		FD_ZERO(&rdfdset) ;   /*clear set of file description */		FD_SET(usersockfd,&rdfdset) ;  /*add new file description into set */		FD_SET(ioosockfd, &rdfdset) ; 				if(select(FD_SETSIZE, &rdfdset, NULL, NULL, NULL) < 0)			errorout("select failed") ;     				/*when client sending data*/		if(FD_ISSET(usersockfd, &rdfset)){			if((iolen = read(usersockfd, buf, sizeof(buf))) <= 0)				break ;			write(isosockfd, buf, iolen) ; /*copy to host*/		}		if(FD_ISSET(isosockfd, &rdfset)){			if( (iolen = read(ioosockfd, buf, sizeof(buf))) <= 0)				break ;			write(usersockfd, buf, iolen) ;		}			}/*for*/			close(isosockfd) ;	close(usersockfd) ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -