BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / soft-design / #31371同步于 2008/11/29
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖

proxy~已经解决~代码已更新

shot
2008/11/29镜像同步27 回复
谢谢大家的和帮助,现在程序已经修改好了,代码仍然放在6楼 非常感谢大家,尤其是sunway同学发现了我的sizeof错误 我现在正在用自己的代理上论坛发贴阿,非常幸福,运行结果贴在后面了。 又解决了一个post的小bug,代码已更新。
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
ericyosho机器人#1 · 2008/11/29
见签名档。 【 在 shot 的大作中提到: 】 : *** glibc detected *** ./HttpProxy: free(): invalid next size (fast): 0x08129068 *** : ======= Backtrace: ========= : /lib/libc.so.6[0x99d394] : ...................
derkaiser机器人#2 · 2008/11/29
lz代码估计就是另一个帖子里的,TCP校验和错误那个 【 在 ericyosho (ericyosho) 的大作中提到: 】 : 见签名档。
ericyosho机器人#3 · 2008/11/30
但是那个帖子里都没有free。
coolfantasy机器人#4 · 2008/11/30
free 了两次?
flyingmiao机器人#5 · 2008/11/30
无代码,无真相 大牛到底是 GG还是MM。。? 混乱了 【 在 ericyosho 的大作中提到: 】 : 见签名档。
shot机器人#6 · 2008/11/30
//============================================================================ // 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; }
shot机器人#7 · 2008/11/30
这个代码确实和Tcp校验和那个有些关系,我把之前的代码改进了一下,支持无限连接数并且尝试实现HTTP代理 但是之前的代码只是校验和错误,程序还是可以正常使用的,到了这个代码就会在ResizeBuffer()和GetHostIp() 这两个函数中出现顶层所示的错误,忘大牛指教,代码在linux下编译。
ericyosho机器人#8 · 2008/11/30
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。
shot机器人#9 · 2008/11/30
gethostbyname返回的是指针,执行之前空着很正常阿,因为即便之前真的指上了一个一个是一个实际的内存空间, hostp=gethostbyname(chs); 执行完了之后仍然会被新的地址覆盖,另外gethostbyname虽然过时,但是宝刀未老, 就跟在vc上提示strcpy不安全推荐使用XXX一样