📄 mrelayd.c
字号:
width=3; if (acfd>=width) width=acfd+1;restart_select: FD_ZERO(&readfds);FD_ZERO(&writefds); FD_SET(acfd,&readfds); for (i=nrofrelays;i--;) { struct relay *relay = relays+i; /* both sides closed? -> clean */ if ((relay->flags & (FLAG_CLOSED_TARGET|FLAG_CLOSED_USER)) == (FLAG_CLOSED_TARGET|FLAG_CLOSED_USER) ) { clean_connection(relay); continue; } /* transmitted all stuff left to user? -> close */ if ((relay->flags&(FLAG_CLOSED_TARGET|FLAG_EOF_TARGET))&&(!relay->outcur)) { clean_connection(relay); continue; } /* transmitted all stuff left to target? -> close */ if ((relay->flags&(FLAG_CLOSED_USER|FLAG_EOF_USER))&&(!relay->incur)) { clean_connection(relay); continue; } if (relay->outfd>=0) { /*need to do that... else it will cause load 1*/ if (relay->incur) FD_SET(relay->outfd,&writefds); if (!(relay->flags & FLAG_EOF_TARGET)) FD_SET(relay->outfd,&readfds); if (relay->outfd>=width) width=relay->outfd+1; } if (relay->infd>=0) { /*need to do that... else it will cause load 1*/ if (relay->outcur) FD_SET(relay->infd,&writefds); if (!(relay->flags & FLAG_EOF_USER)) FD_SET(relay->infd,&readfds); if (relay->infd>=width) width=relay->infd+1; } } if (-1==select( width, (FD_CAST*)&readfds, (FD_CAST*)&writefds, NULL,/*no exceptfds.*/ 0) ) { if (errno!=EINTR) perror("select"); else goto restart_select; } if (FD_ISSET(acfd,&readfds)) { int afd; int aclen; struct sockaddr_in conaddr; struct relay *relay = NULL; aclen=sizeof(struct sockaddr_in); if (-1==(afd=accept(acfd,(struct sockaddr*)&conaddr,&aclen))) perror("accept"); if (relays) relays=(struct relay*)xrealloc(relays,sizeof(struct relay)*(nrofrelays+1)); else relays=(struct relay*)xmalloc(sizeof(struct relay)); nrofrelays++; relay = relays+(nrofrelays-1); relay->inbuf = xmalloc(DEFAULTSIZE); relay->outbuf = xmalloc(DEFAULTSIZE); relay->insize = DEFAULTSIZE; relay->outsize = DEFAULTSIZE; relay->flags = 0; relay->incur = 0; relay->outcur = 0; relay->infd = afd; relay->outfd = -1; relay->state = STATE_ACCEPTED; memcpy(&relay->inaddr,&conaddr,sizeof(struct sockaddr_in)); if (nrofrelays>=MAXUSERS) { strcpy(relay->outbuf,relaystring); relay->outcur = strlen(relaystring)+1; relay->state = STATE_OK; relay->flags = FLAG_CLOSED_TARGET; }#ifdef SO_LINGER { struct linger sol; sol.l_linger = 5; sol.l_onoff = 1; if (-1==setsockopt(acfd,SOL_SOCKET,SO_LINGER,(char*)&sol,sizeof(sol))) perror("setsockopt SOL_SOCKET SO_LINGER"); }#endif } for (i=nrofrelays;i--;) { struct relay *relay = relays+i; if ((relay->infd>=0) && FD_ISSET(relay->infd,&readfds)) { do { if (-1==(res=read(relay->infd,readbuf,1000))) { if (errno==EINTR) break; /* user side has broken the connection */ close(relay->infd);relay->infd=-1; relay->flags |= FLAG_CLOSED_USER; break; } break; } while (1); if (res==0) { /* we read the End Of File marker. but we still have to write * the rest of the text */ relay->flags |= FLAG_EOF_USER; } if (res>0) { readbuf[res]='\0'; while (relay->incur+res>=relay->insize) { relay->inbuf=xrealloc(relay->inbuf,relay->insize*2); relay->insize*=2; } memcpy(relay->inbuf+relay->incur,readbuf,res+1); relay->incur+=res; } if ( (relay->outfd==-1) && (relay->state==STATE_ACCEPTED) && memchr(relay->inbuf,'\n',relay->incur) ) { char sendbuf[200]; struct hostent *hp; char *s,*nextchar,*tmp; int port; s = memchr(relay->inbuf,'\n',relay->incur); if (!s) continue; *s='\0'; nextchar=s+1; if ((s=memchr(relay->inbuf,'\r',(s-relay->inbuf)))) *s='\0'; relay->state = STATE_OK; tmp = (char*)xmalloc(strlen(relay->inbuf)); if (2!=sscanf(relay->inbuf,"relay %s %d", tmp,&port )) { if (!sscanf(relay->inbuf,"relay %s",tmp)) { free(tmp); /* we avoid telling potential hackers how to use this relay */ sprintf(relay->outbuf,"550 Bad syntax. Go away.\n",tmp); relay->outcur = strlen(relay->outbuf); relay->flags = FLAG_CLOSED_TARGET; continue; } else port = DEFAULTPORT; } hp=gethostbyname(tmp); if (!hp) {/* not found */ sprintf(relay->outbuf,"No hostentry for '%s'!\n",tmp); free(tmp); relay->outcur = strlen(relay->outbuf); relay->flags = FLAG_CLOSED_TARGET; continue; } memcpy(&targetaddr,hp->h_addr_list[0],sizeof(struct in_addr)); relay->outaddr.sin_family=AF_INET; relay->outaddr.sin_port=htons(port); memcpy(&(relay->outaddr.sin_addr),&targetaddr,4); strcpy(sendbuf,RELAYHEADER); relay->outcur=strlen(sendbuf); memcpy(relay->outbuf,sendbuf,strlen(sendbuf)+1); if (-1==(relay->outfd=socket(PF_INET,SOCK_STREAM,0))) perror("socket(connect_socket)");#ifndef _WIN32 (void)fd_make_nonblocking(relay->outfd);#endif if ( (-1==connect( relay->outfd, (struct sockaddr*)&(relay->outaddr), sizeof(struct sockaddr_in))#ifdef _WIN32 ) && (WSAGetLastError()!=WSAEINPROGRESS)#else ) && (errno!=EINPROGRESS)#endif ) { sprintf(readbuf,"Connect to %s failed: %s\n",tmp,strerror(errno)); perror("connect"); close(relay->outfd);relay->outfd=-1; relay->state = STATE_OK; relay->flags |= FLAG_CLOSED_TARGET; strcpy(relay->outbuf,readbuf); relay->outsize = strlen(readbuf)+1; free(tmp); continue; } free(tmp);#ifdef SEND_REMOTEIP /* only useful if you want to tell the * remotemud the _real_ host the caller * is calling from */ tmphp=gethostbyaddr( (char*)(&(conaddr.sin_addr)), sizeof(struct in_addr), AF_INET ); if (!tmphp) { sprintf(sendbuf,"remoteip %s %s\n", inet_ntoa(conaddr.sin_addr), inet_ntoa(conaddr.sin_addr) ); } else { sprintf(sendbuf,"remoteip %s %s\n", inet_ntoa(conaddr.sin_addr), tmphp->h_name ); } memcpy(relay->inbuf,sendbuf,strlen(sendbuf)+1); relay->incur=strlen(sendbuf);#else relay->inbuf[0]='\0'; relay->incur=0;#endif } } if ((relay->outfd>=0) && FD_ISSET(relay->outfd,&readfds)) { do { if (-1==(res=read(relay->outfd,readbuf,1000))) { if (errno==EINTR) continue; /* the mudside has broken the * connection. we still have * to transmit the rest of * the text */ close(relay->outfd);relay->outfd=-1; relay->flags |= FLAG_CLOSED_TARGET; break; } break; } while (1); if (res==0) { /* we read the End Of File marker. but we still have to write * the rest of the text */ relay->flags |= FLAG_EOF_TARGET; } if (res>0) { /* 0 is not automagically appended. */ readbuf[res]='\0'; while (relay->outcur+res>=relay->outsize) { relay->outbuf=xrealloc(relay->outbuf,relay->outsize*2); relay->outsize*=2; } memcpy(relay->outbuf+relay->outcur,readbuf,res+1); relay->outcur+=res; } } if ((relay->infd>=0) && FD_ISSET(relay->infd,&writefds)) { j=relay->outcur; if (-1==(res=write(relay->infd,relay->outbuf,j))) { if (errno!=EINTR) { close(relay->infd);relay->infd=-1; relay->flags |= FLAG_CLOSED_USER; } } if (res>0) { memcpy(relay->outbuf,relay->outbuf+res,relay->outcur-res); relay->outcur-=res; } } if ((relay->outfd>=0) && FD_ISSET(relay->outfd,&writefds)) { j=relay->incur; if (-1==(res=write(relay->outfd,relay->inbuf,j))) { if (errno!=EINTR) { close(relay->outfd);relay->outfd=-1; relay->flags |= FLAG_CLOSED_TARGET; } } if (res>0) { memcpy(relay->inbuf,relay->inbuf+res,relay->incur-res); relay->incur-=res; } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -