摘要
这是我写的http代理程序,可以做透明代理或传统代理,使用了3128作为代理端口,并将/proc/sys/net/ipv4/ip_forward 置为1(我也不知道为什么),透明代理还要将iptable的端口转发规则加上,现在我也在调试,欢迎大家给提提意见。(2003-12-11 16:39:16)
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <unistd.h>
#include <netdb.h>
#include <pthread.h>
#include <sys/select.h>
void *thread_proc(void *arg)
{
char *p_begin, *p_end;
struct hostent hs1, *hs=&hs1;
struct sockaddr_in soaddrtmp;
char buftmp[50];
int fromfd, tofd;
unsigned char buf[1000];
fd_set rfd;
int number, max=0;
fromfd = *((int *)(arg));
if((number = recv(fromfd, buf, 1000, 0)) == -1) {
close(fromfd);
printf("fromfd=%d is closed now! ", fromfd);
return;
}
bzero(&soaddrtmp, sizeof(struct sockaddr_in));
buf[number]=0;
p_begin = strstr(buf, "Host: ") + 6;
p_end = strchr(p_begin, ' ') - 1;
bzero(buftmp, 50);
strncpy(buftmp, p_begin, p_end - p_begin);
printf("URL========%s", buftmp);
hs = gethostbyname(buftmp);
memcpy(&(soaddrtmp.sin_addr), hs->h_addr, hs->h_length);
printf("ip address=%s ", inet_ntoa(soaddrtmp.sin_addr));
soaddrtmp.sin_port = htons(80);
soaddrtmp.sin_family = AF_INET;
if((tofd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "socket(): sock_to: is error! ");
close(fromfd);
return;
}
if(connect(tofd, (struct sockaddr *)(&soaddrtmp),
sizeof(struct sockaddr)) == -1) {
fprintf(stderr, "connect(): sock_to: %s! ",
strerror(errno));
close(fromfd);
return;
}
send(tofd, buf, number, 0);
if(fromfd < tofd)
max = tofd;
else
max = fromfd;
while(1) {
bzero(buf, 1000);
FD_ZERO(&rfd);
FD_SET(fromfd, &rfd);
FD_SET(tofd, &rfd);
select(max + 1, &rfd, NULL, NULL, NULL);
if(FD_ISSET(fromfd, &rfd)) {
number = recv(fromfd, buf, 1000, 0);
if((number == -1)' '(number == 0)) {
close(fromfd);
printf("fromfd=%d is closed now! ", fromfd);
close(tofd);
return;
}
send(tofd, buf, number, 0);
}
if(FD_ISSET(tofd, &rfd)) {
number = recv(tofd, buf, 1000, 0);
if((number == 0)' '(number == -1)) {
close(tofd);
printf("tofd=%d is closed now! ", tofd);
close(fromfd);
return;
}
send(fromfd, buf, number, 0);
}
}
return;
}
int main()
{
int sock_id;
int id_s;
int length=1;
struct sockaddr_in s_addr;
pthread_t th_id;
if((sock_id = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "socket(): is error! ");
return 1;
}
bzero(&s_addr, sizeof(struct sockaddr_in));
s_addr.sin_port = htons(3128);
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
if(bind(sock_id, (struct sockaddr *)(&s_addr),
sizeof(struct sockaddr)) == -1) {
fprintf(stderr, "bind(): %s! ", strerror(errno));
close(sock_id);
return 1;
}
if(listen(sock_id, 200) == -1) { //NOTE: attack of syn
fprintf(stderr, "listen(): %s! ", strerror(errno));
close(sock_id);
return 1;
}
while(1) {
bzero(&s_addr, sizeof(struct sockaddr_in));
if((id_s = accept(sock_id, (struct sockaddr *)(&s_addr),
&length)) == -1) {
fprintf(stderr, "accept(): is error! ");
continue;
}
pthread_create(&th_id, NULL, &thread_proc, &id_s);
//thread_proc((void *)(&id_s));
//doproxy();
//printf("ip=%s port=%d ", inet_ntoa(s_addr.sin_addr), ntohs(s_addr.sin_port));
}
close(sock_id);
return 0;
}