8 #include <sys/socket.h>
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
14 #include <sys/param.h>
16 /* Generic Proxy 1.1 */
18 static void sig_usr(int);
24 int main(int argc
,char *argv
[])
28 struct hostent
*hostptr
;
29 struct hostent
*l_hostptr
;
31 char rhost
[100] = "127.0.0.1";
32 char lhost
[100] = "0.0.0.0";
39 char logfile
[MAXPATHLEN
] = "";
40 char filename
[MAXPATHLEN
];
48 int sockfd
, lnewsockfd
, clilen
;
49 struct sockaddr_in cli_addr
, serv_addr
;
53 while( (c
= getopt(argc
, argv
, "A:a:S:s:R:r:L:l:D:d:Ffh")) != EOF
) {
54 switch( toupper(c
) ) {
56 strcpy(rhost
, optarg
);
59 strcpy(lhost
, optarg
);
69 strcpy(logfile
, optarg
);
80 if( strcmp(rhost
, "") == 0 ) {
85 printf("Starting proxy from %s:%d to remote %s:%d\n", lhost
, lport
, rhost
,
88 hostptr
= gethostbyname(rhost
);
91 fprintf( stderr
, "failed to resolve remote ip address: %s (h_errno=%d)\n",
95 l_hostptr
= gethostbyname(lhost
);
96 if( l_hostptr
== NULL
)
98 fprintf( stderr
, "failed to resolve local ip address: %s (h_errno=%d)\n",
106 sockfd
= socket(AF_INET
, SOCK_STREAM
, 0);
107 serv_addr
.sin_family
= AF_INET
;
108 (void) memcpy(&serv_addr
.sin_addr
.s_addr
, *(l_hostptr
->h_addr_list
),
109 sizeof(serv_addr
.sin_addr
.s_addr
)) ;
110 serv_addr
.sin_port
= htons(lport
);
112 setsockopt(sockfd
, SOL_SOCKET
, SO_REUSEADDR
, (char *)&status
, sizeof(int));
113 if( bind(sockfd
, (struct sockaddr
*)&serv_addr
, sizeof(serv_addr
)) < 0) {
114 perror("failed binding server socket");
119 ** Start running in background by default
121 if( in_bgr
&& fork() ) {
126 ** Set queue length and signal interrupt
129 signal(SIGCHLD
,sig_usr
);
134 ** Wait for new clients
136 clilen
= sizeof(cli_addr
);
138 while( lnewsockfd
< 0 ) {
139 lnewsockfd
= accept(sockfd
, (struct sockaddr
*)&cli_addr
, &clilen
);
144 ** It might happen that we got a signal and exited accept
145 ** In this case restart accept and continue to wait
147 if( (lnewsockfd
== -1) && (errno
== EINTR
) )
151 ** Otherwise, we've just failed, exit
153 perror("failed in accept");
157 printf( "Connecting client from %s to %s:%d\n",
158 inet_ntoa(cli_addr
.sin_addr
), rhost
, rport
);
161 ** Pass the new connection throught to the server
163 rnewsockfd
= socket(AF_INET
, SOCK_STREAM
, 0);
164 serv_addr
.sin_family
= AF_INET
;
165 (void) memcpy(&serv_addr
.sin_addr
.s_addr
, *(hostptr
->h_addr_list
),
166 sizeof(serv_addr
.sin_addr
.s_addr
)) ;
167 serv_addr
.sin_port
= htons(rport
);
168 connect(rnewsockfd
, (struct sockaddr
*) &serv_addr
, sizeof(serv_addr
));
171 ** Forking the baby-sitter
175 ** Starting first child. It will read from client and sent to
178 if ((lpid
= fork()) == 0) {
179 if( strcmp(logfile
, "") != 0 ) {
180 sprintf(filename
, "%s.%d.out", logfile
, getpid());
181 outf
= open(filename
, O_RDWR
|O_TRUNC
|O_CREAT
, 0666);
183 while( (len
= read(lnewsockfd
, buffer
, BUFSIZE
)) > 0 ) {
186 write(outf
, buffer
, len
);
187 write(rnewsockfd
, buffer
, len
);
192 ** When finished reading, exit
198 } else if (lpid
< 0) {
202 perror("failed forking 1st child");
207 ** Start second child. It will read from the server and write
210 if ((rpid
= fork()) == 0 ) {
211 if( strcmp(logfile
, "") != 0 ) {
212 sprintf(filename
, "%s.%d.in", logfile
, getpid());
213 inf
= open(filename
, O_RDWR
|O_TRUNC
|O_CREAT
, 0666);
215 while( (len
= read(rnewsockfd
, buffer
, BUFSIZE
)) > 0) {
218 write(inf
, buffer
, len
);
219 write(lnewsockfd
, buffer
, len
);
224 ** When finished writing, exist
235 perror("failed forking 2nd child");
240 ** Now baby-sitter waits for any child to finish
247 ** If any of the children terminated, kill all of them
255 ** The main process closes files and goes on to wait for new clients
265 printf("Usage: vproxy [-a local_ip=0.0.0.0] [-l local_port=9081] [-s remote_ip=127.0.0.1] [-r remote_port=9080] [-d log_prefix]\n");
269 static void sig_usr(int signo
)
275 signal(SIGCHLD
,sig_usr
);