返回信息流谢谢大家的和帮助,现在程序已经修改好了,代码仍然放在6楼
非常感谢大家,尤其是sunway同学发现了我的sizeof错误
我现在正在用自己的代理上论坛发贴阿,非常幸福,运行结果贴在后面了。
又解决了一个post的小bug,代码已更新。
这是一条镜像帖。来源:北邮人论坛 / soft-design / #31371同步于 2008/11/29
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖
proxy~已经解决~代码已更新
shot
2008/11/29镜像同步27 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
见签名档。
【 在 shot 的大作中提到: 】
: *** glibc detected *** ./HttpProxy: free(): invalid next size (fast): 0x08129068 ***
: ======= Backtrace: =========
: /lib/libc.so.6[0x99d394]
: ...................
//============================================================================
// Name : HttpProxy.c
// Author : wjc
// Version : 1.0
// Copyright : copyright wjc
// Description : proxy in C, Ansi-style
// Attention : this code runs on linux
//============================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <asm/ioctls.h>
#include <arpa/inet.h>
#include <netdb.h>
#define LENGTH_OF_LISTEN_QUEUE 10 //length of listen queue in server
#define BUFFER_SIZE 2550
#define WELCOME_MESSAGE "welcome to connect the server. "
#define ERROR_MESSAGE "we come across some problems!"
struct Session
{
int sock;
int remt;
int stat;
char *buffer;
int length;
int size;
unsigned long ip;
int port;
struct Session *next;
struct Session *last;
};
int GetMax(int sock,struct Session *s);
int Connect(unsigned long ip,int port);
int StartServ(unsigned long ip,int port);
unsigned long GetHostIp(char * chs);
struct Session * CreateSession(struct Session * s);
int ResizeBuffer(struct Session * s);
void DelSession(struct Session * s);
int AppendBuffer(struct Session * s,char * buffer,int buflen);
int TestEnd(struct Session * s);
int FirstIndex(char * source,int soulen,char *target, int tarlen,int from);
int LastIndex(char * source,int soulen,char *target, int tarlen,int to);
int CutoutStr(char * source,int soulen,int from,int to);
int StrCompare(char * source,int soulen,char * target,int tarlen);
int AnalyzeBuffer(struct Session * s,unsigned long * ip,int * port);
int CloseRemt(struct Session * s,fd_set * aset);
int CloseSock(struct Session * s,fd_set * aset);
int main(int argc, char **argv)
{
int servfd,rejfd,i;
int servport=20000,conport=21;
unsigned long conip=inet_addr("127.0.0.1");
unsigned long servip=inet_addr("0.0.0.0");
struct Session * socks;
struct Session * temp;
char buffer[BUFFER_SIZE];
int buflen=0;
if(argc>=5)
{
conip=GetHostIp(argv[3]);
conport=atoi(argv[4]);
servip=inet_addr(argv[1]);
servport=atoi(argv[2]);
}
servfd=StartServ(servip,servport);
if(servfd<0)
{
exit(1);
}
printf("server started on %d\n",servport);
/*struct timeval timeout;
timeout.tv_sec=60;
timeout.tv_usec=0;*/
fd_set rfd;
fd_set afd;
FD_ZERO(&afd);
FD_SET(servfd,&afd);
socks=CreateSession(NULL);
if(socks==NULL)
{
puts("malloc failed");
exit(1);
}
while (1)
{
rfd=afd;
if(select(GetMax(servfd,socks)+1,&rfd,NULL,NULL,NULL)<0)//socket error
{
exit(1);
}
else
{
if(FD_ISSET(servfd,&rfd))
{
puts("receive a request");
if((temp=CreateSession(socks))!=NULL)
{
puts("create session success");
temp->sock=accept(servfd,0,0);
if(temp->sock<0)
{
puts("connect remote failed");
close(temp->sock);
DelSession(temp);
}
else
{
puts("connect remote success");
puts("service started one side");
FD_SET(temp->sock,&afd);
temp->stat=1;
}
}
else
{
puts("create session failed");
puts("shutdown the session");
rejfd=accept(servfd,0,0);
close(rejfd);
}
}
temp=socks->next;
i=0;
while(temp!=NULL)
{
printf("line %d\n",++i);
if(temp->stat>=1&&FD_ISSET(temp->sock,&rfd))
{
puts("received local package");
if(temp->stat==2)
{
buflen=recv(temp->sock,buffer,BUFFER_SIZE,0);
if(buflen>0)
{
send(temp->remt,buffer,buflen,0);
}
else
{
CloseRemt(temp,&afd);
CloseSock(temp,&afd);
DelSession(temp);
}
}
else
{
buflen=recv(temp->sock,buffer,BUFFER_SIZE,0);
if(buflen>0)
{
puts("package length > 0");
if(AppendBuffer(temp,buffer,buflen)<0)
{
puts("buffer store failed");
puts("shutdown the session");
CloseRemt(temp,&afd);
CloseSock(temp,&afd);
DelSession(temp);
}
else
{
puts("buffer store success");
if(TestEnd(temp)>=0)
{
puts("all request buffered");
if(AnalyzeBuffer(temp,&conip,&conport)>=0)
{
puts("analyze buffer success");
if(conip!=temp->ip||conport!=temp->port||temp->stat==1)
{
puts("new target");
puts("close remote");
CloseRemt(temp,&afd);
printf("connecting %ld:%d",conip,conport);
temp->remt=Connect(conip,conport);
if(temp->remt<0)
{
puts("connect remote failed");
puts("shutdown the session");
CloseSock(temp,&afd);
DelSession(temp);
}
else
{
puts("connect remote success");
puts("send request");
temp->ip=conip;
temp->port=conport;
send(temp->remt,temp->buffer,temp->length,0);
FD_SET(temp->remt,&afd);
temp->stat=2;
}
}
else if(temp->stat>=2)
{
puts("old target");
puts("send request");
send(temp->remt,temp->buffer,temp->length,0);
}
}
else
{
puts("analyze buffer failed");
puts("close session");
CloseRemt(temp,&afd);
CloseSock(temp,&afd);
DelSession(temp);
}
temp->length=0;
}
}
}
else
{
puts("received shutdown signal");
puts("shutdown the session");
CloseRemt(temp,&afd);
CloseSock(temp,&afd);
DelSession(temp);
}
}
}
else if(temp->stat>=2&&FD_ISSET(temp->remt,&rfd))
{
puts("receive remote packet");
buflen=recv(temp->remt,buffer,BUFFER_SIZE,0);
if(buflen<=0)
{
puts("received shutdown signal");
puts("shutdown the session");
CloseRemt(temp,&afd);
CloseSock(temp,&afd);
DelSession(temp);
}
else
{
puts("package length > 0");
puts("send response");
temp->stat=3;
send(temp->sock,buffer,buflen,0);
}
}
temp=temp->next;
}
}
}
close(servfd);
return 0;
}
int GetMax(int sock,struct Session *s)
{
int max=sock;
s=s->next;
while(s!=NULL)
{
if(s->stat>=1&&s->sock>max)
max=s->sock;
if(s->stat>=2&&s->remt>max)
max=s->remt;
s=s->next;
}
printf("max = %d\n",max);
return max;
}
int Connect(unsigned long ip,int port)
{
int clifd;
struct sockaddr_in servaddr,cliaddr;
socklen_t socklen = sizeof(servaddr);
if ((clifd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
return -1;
}
bzero(&cliaddr,sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = htons(INADDR_ANY);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=ip;
servaddr.sin_port = htons(port);
if (bind(clifd,(struct sockaddr*)&cliaddr,sizeof(cliaddr))<0)
{
close(clifd);
return -2;
}
if (connect(clifd,(struct sockaddr*)&servaddr, socklen) < 0)
{
close(clifd);
return -3;
}
return clifd;
}
int StartServ(unsigned long ip,int port)
{
int servfd;
struct sockaddr_in servaddr;
if ((servfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("create socket error!\n");
return -1;
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr=ip;
//servaddr.sin_addr.s_addr = htons(INADDR_ANY);
if (bind(servfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
{
printf("bind to port %d failure!\n",port);
close(servfd);
return -2;
}
if (listen(servfd,LENGTH_OF_LISTEN_QUEUE) < 0)
{
printf("call listen failure!\n");
close(servfd);
return -3;
}
return servfd;
}
unsigned long GetHostIp(char * chs)
{
struct hostent *hostp;
hostp=gethostbyname(chs);
if(hostp==NULL)return 0;
return *(unsigned long *)(*hostp->h_addr_list);
}
struct Session * CreateSession(struct Session * s)
{
struct Session * temp;
temp=(struct Session *)malloc(sizeof(struct Session));
if(temp==NULL)return NULL;
temp->buffer=(char *)malloc(sizeof(char)*BUFFER_SIZE);
if(temp->buffer==NULL)
{
free(temp);
return NULL;
}
temp->sock=0;
temp->remt=0;
temp->stat=0;
temp->length=0;
temp->size=BUFFER_SIZE;
temp->ip=0;
temp->port=0;
temp->next=NULL;
temp->last=NULL;
if(s)
{
temp->next=s->next;
temp->last=s;
if(temp->next)temp->next->last=temp;
if(temp->last)temp->last->next=temp;
}
return temp;
}
int ResizeBuffer(struct Session * s)
{
char * temp=s->buffer;
s->buffer=(char *)realloc(s->buffer,sizeof(char)*(BUFFER_SIZE+s->size));
if(s->buffer==NULL)
{
s->buffer=temp;
return -1;
}
s->size+=BUFFER_SIZE;
return 0;
}
void DelSession(struct Session * s)
{
if(s->last)s->last->next=s->next;
if(s->next)s->next->last=s->last;
free(s->buffer);
free(s);
}
int AppendBuffer(struct Session * s,char * buffer,int buflen)
{
int pos=0;
while(s->length+buflen>s->size)
{
if(ResizeBuffer(s)<0)return -1;
}
for(pos=s->length;pos<s->length+buflen;pos++)
{
s->buffer[pos]=buffer[pos-(s->length)];
}
s->length+=buflen;
return 0;
}
int TestEnd(struct Session * s)
{
if(FirstIndex(s->buffer,s->length,"\r\n\r\n",4,0)>=0)
return 0;
else
return -1;
}
int FirstIndex(char * source,int soulen,char *target, int tarlen,int from)
{
int i;
for(;from+tarlen<=soulen;from++)
{
for(i=0;i<tarlen;i++)
{
if(source[i+from]!=target[i])
break;
}
if(i>=tarlen)return from;
}
return -1;
}
int LastIndex(char * source,int soulen,char *target, int tarlen,int to)
{
int i;
for(;to-tarlen>=0;to--)
{
for(i=0;i<tarlen;i++)
{
if(source[to-i-1]!=target[tarlen-i-1])
break;
}
if(i>=tarlen)return to-tarlen;
}
return -1;
}
int CutoutStr(char * source,int soulen,int from,int to)
{
int i;
for(i=from;i>=0&&i<soulen&&i+to-from>=0&&i+to-from<soulen;i++)
{
source[i]=source[i+to-from];
}
return to-from;
}
int StrCompare(char * source,int soulen,char * target,int tarlen)
{
int i;
if(soulen!=tarlen)return -1;
for (i=0;i<soulen;i++)
{
if(source[i]!=target[i])
return -2;
}
return 0;
}
int AnalyzeBuffer(struct Session * s,unsigned long * ip,int * port)
{
int start=0,end,mid;
char * buffer=s->buffer;
int buflen=s->length;
//get/post
end=FirstIndex(buffer,buflen," ",1,start);
if(end<0)return -1;
if(StrCompare(buffer+start,end-start,"POST",4)<0&&StrCompare(buffer+start,end-start,"GET",3)<0)return -1;
//remove host name
start=end+1;
end=FirstIndex(buffer,buflen," ",1,start);
if(end<0)return -1;
start=FirstIndex(buffer,end,"http://",7,start);
if(start>=0)
{
mid=FirstIndex(buffer,end,"/",1,start+7);
if(mid<0)
{
buffer[--end]='/';
buflen-=CutoutStr(buffer,buflen,start,end);
}
else
{
buflen-=CutoutStr(buffer,buflen,start,mid);
}
}
//get host name
start=FirstIndex(buffer,buflen,"\r\nHost",6,start);
if(start<0)return -1;
start+=6;
end=FirstIndex(buffer,buflen,"\r\n",2,start);
if(end<0)return -1;
start=FirstIndex(buffer,end,":",1,start);
start+=2;
if(start>=end)return -1;
mid=FirstIndex(buffer,end,":",1,start);
if(mid==-1)
{
buffer[end]='\0';
*ip=GetHostIp(buffer+start);
buffer[end]='\r';
*port=80;
}
else
{
buffer[mid]='\0';
*ip=GetHostIp(buffer+start);
buffer[mid]=':';
buffer[end]='\0';
*port=atoi(buffer+mid+1);
buffer[end]='\r';
}
//remove proxy
while((start=FirstIndex(buffer,buflen,"\r\nProxy",7,start))>=0)
{
end=FirstIndex(buffer,buflen,"\r\n",2,start+2);
buflen-=CutoutStr(buffer,buflen,start,end);
}
s->length=buflen;
return 0;
}
int CloseRemt(struct Session * s,fd_set * aset)
{
if(s->stat>=2)
{
close(s->remt);
FD_CLR(s->remt,aset);
s->stat=1;
return 0;
}
return -1;
}
int CloseSock(struct Session * s,fd_set * aset)
{
if(s->stat>=1)
{
close(s->sock);
FD_CLR(s->sock,aset);
s->stat=0;
return 0;
}
return -1;
}
这个代码确实和Tcp校验和那个有些关系,我把之前的代码改进了一下,支持无限连接数并且尝试实现HTTP代理
但是之前的代码只是校验和错误,程序还是可以正常使用的,到了这个代码就会在ResizeBuffer()和GetHostIp()
这两个函数中出现顶层所示的错误,忘大牛指教,代码在linux下编译。
unsigned long GetHostIp(char * chs)
{
struct hostent *hostp;
hostp=gethostbyname(chs);
return *(unsigned long *)(*hostp->h_addr_list);
}
没有仔细看你代码,但是
你这个hostp指针有实际指向的内存空间么?
还有男人了一下gethostbyname,描述如下:
These functions are obsolete. Applications should use getaddrinfo(3)
and getnameinfo(3) instead。
gethostbyname返回的是指针,执行之前空着很正常阿,因为即便之前真的指上了一个一个是一个实际的内存空间,
hostp=gethostbyname(chs); 执行完了之后仍然会被新的地址覆盖,另外gethostbyname虽然过时,但是宝刀未老,
就跟在vc上提示strcpy不安全推荐使用XXX一样