/* Handle a PONG packet */ void servuser::execpong(char **array, int count) { int fd; if (count<5) return; sscanf(array[4],"%d",&fd); server *source=getserver(array[1]); if (!source) return; source->receivepong(array[4]); if (fd!=-1) systeminterface->receivepong(array[1], array[4], array[2], array[3]); }
int getnextserver(int nuser) { int first; first = user(nuser)->currentserver; while(1) { user(nuser)->currentserver++; if (getserver(user(nuser)->currentserver,nuser) ==0) { return 0; /* found it, bye */ } if (user(nuser)->currentserver>20) user(nuser)->currentserver = 0; if (user(nuser)->currentserver == first) return -1; } return 1; }
/* Handle an ADD CLIENT packet */ int servuser::execaddclient(char **array, int count) { int type; client *c; if (count<12) return 1; server *location=getserver(array[5]); /* If we can't find the server, or the indicated server is our server, we don't need the new client. */ if (!location||location==myserver) return 1; type=atoi(array[7]); c=getclient(array[6]); if (c) return 0; c=new client(array[4],location,array[6],type,atoi(array[8]), array[9], array[10], atoi(array[11])); if (type==CLIENT_ATC) clientinterface->sendaa(c, NULL); else if (type==CLIENT_PILOT) clientinterface->sendap(c, NULL); return 1; }
/* Handle a LINKDOWN packet */ void servuser::execlinkdown(char **array, int count) { int x; for (x=4;x<count;x++) { /* Get the next server ident from the packet and look it up */ server *temp=getserver(array[x]); if (!temp) continue; /* If the shortest path to the server is pointing at the direction which the packet came from, we can no longer route packets to the server in that direction: reset the path to NULL; packets for the server will then be broadcast, until a new shortest path is found */ if (temp->path==this) temp->setpath(NULL, -1); } serverinterface->sendsync(); }
/* Handle a NOTIFY packet */ void servuser::execnotify(char **array, int count) { server *s; int packetcount, hops, feedflag; if (count<11) return; packetcount=atoi(array[2]), hops=atoi(array[3]), feedflag=atoi(array[4]); s=getserver(array[5]); if (s==myserver) return; if (!s) { s=new server(array[5],array[6],array[7],array[8],array[9], atoi(array[10]), (char *)(count==12?array[11]:"")); } else s->configure(array[6],array[7],array[8],array[9], (char *)(count==12?array[11]:"")); /* If this is a notify from our peer, set 'thisserver' */ if (!feedflag&&hops==1) thisserver=s; /* If this is a server feed, or we already have routing info, we don't need to set the routing info */ if (feedflag||(s->hops>-1&&hops>=s->hops)) return; s->setpath(this, hops); }
PROTO int group(const char *group, char nogroupecho) { char b[MAX_SERVERRSP]; ACTIVE *newgroup; SERVER *svr; CLEARBUF if ( nullstr(group) ) { swriteclient(client,"500 You must select a group\r\n"); return 1; } /* only change group if it has changed */ if ( client->group == NULL || strcmp(client->group->newsgroup, group) != 0 ) { /* check for read permission */ if ( ! match_expression((unsigned char *)group , (unsigned char *)getwildmat(client->user->readpat) , 0) ) { if ( ! nogroupecho ) swriteclient(client, MSG_NOSUCHGROUP); return 1; } /* find and load our new group */ if ( (newgroup = getgroup(group)) == NULL ) { if ( ! nogroupecho ) swriteclient(client, MSG_NOSUCHGROUP); return 1; } if ( (svr=getserver(newgroup->server)) == NULL ) return swriteclient(client, "500 Cant find server for group\r\n"); /* disconnect first if we have to change server */ if ( client->groupserver != NULL && client->connected == 1 && strcmp(svr->Groups, client->groupserver->Groups) != 0 ) { disconnect_server(client); } /* close group and reconnect */ closegroup(); client->group = newgroup; switch ( connect_groupserver(client, svr->Name) ) { case CONNECT_ERR: return swriteclient(client, "500 Error selecting server\r\n"); case CONNECT_DOWN: sleep(cfg.DownDelay); return writeclient(client, MSG_SERVER_DOWN); default: break; } /* reset by connect_groupserver (via disconnect_server FIXME) */ client->group = newgroup; client->groups++; } if ( ! writeserver(client, "GROUP %s\r\n", group) ) return -1; if ( ! readserver(client, b, MAX_SERVERRSP-1) ) return -1; syslog(LOG_NOTICE, "%s: group %s", client->hostname, group); if ( ! nogroupecho ) return swriteclient(client,b); return 0; }
void servuser::execreset(char **array, int count) { server *s=getserver(array[1]); if (!s) return; s->pcount=0; }
void servuser::doparse(char *s) { int index=0, count, packetcount, hops, bi; char *array[100], *from, *to; server *origin; if (s[0]=='#') return; /*if (strlen(s)>80) dolog(L_ERR,"POSERR2:%s", s);*/ /* Take all the fields from the packet */ count=breakpacket(s,array,100); if (count<6) { /* This packet doesn't have the basic fields, show an error and drop it */ manager->incvar(parent->varshape); uprintf("# Missing basic packet fields, syntax error\r\n"); return; } /* Some statistics */ int packeterr=0; if (sscanf(array[3]+1, "%d", &packetcount)==0) packeterr=1; if (sscanf(array[4], "%d", &hops)==0) packeterr=1; from=array[2], to=array[1], bi=(*(array[3])=='B'); if (packeterr) { manager->incvar(parent->varinterr); return; } if (hops > MAXHOPS) { /* This packet seems to bounce, drop it */ manager->incvar(parent->varbounce); return; } /* Find the origin of the packet */ origin=getserver(from); if (origin) { /* This server seems to be alive */ origin->setalive(); /* Discard if it originated from our server */ if (origin==myserver) return; /* Check if this packet travelled a shorter route */ if (hops<origin->hops||origin->hops==-1) origin->setpath(this,hops); /* Discard if the packet was broadcast and the packetcount doesn't match the packetcount (we already handled this packet earlier) The broadcast check (bi) is nessecary to prevent newer broadcast packets from passing stalled unicast packets with a quicker route. */ #define MAXSPACE 1000000 if (packetcount<=origin->pcount||packetcount>(origin->pcount+MAXSPACE)) { if ((packetcount==origin->pcount)||(bi&&origin->packetdrops<100)|| (bi&&packetcount>(origin->pcount+MAXSPACE))) { manager->incvar(parent->varmcdrops); origin->packetdrops++; return; } manager->incvar(parent->varucoverrun); } if (origin->packetdrops>=100) origin->pcount=packetcount; if (packetcount>origin->pcount) { /* Update the packetcount for this server */ origin->pcount=packetcount; } if (bi) { /* Set the path to the server */ origin->setpath(this,hops); origin->packetdrops=0; } } /* Now find the command number for this packet */ while (cmdnames[index]) { if (!STRCASECMP(cmdnames[index],array[0])) { char buf[1000]; /* This user is correct */ clientok=1; /* If we don't know the server, we only allow the NOTIFY packet from it */ if (!origin&&index!=CMD_NOTIFY) return; /* If the packet doesn't need local delivery, forward and return */ if (!needlocaldelivery(to)) { /* call sendpacket() to relay the packet to the other servers */ if (STRCASECMP(to,myserver->ident)) parent->sendpacket(this,NULL,index,to,from,packetcount, hops, bi, catcommand(array+5,count-5,buf)); return; } /* Execute the command */ int needforward=runcmd(index,array+1,count-1); /* if the packet needs forwarding, call sendpacket() to relay the packet to the other servers */ if (STRCASECMP(to,myserver->ident)&&needforward) parent->sendpacket(this,NULL,index,to,from,packetcount, hops, bi, catcommand(array+5,count-5,buf)); manager->incvar(bi?parent->varmchandled:parent->varuchandled); return; } else index++; } uprintf("# Unknown command, Syntax error\r\n"); manager->incvar(parent->varfailed); }
extern int telnet_main(int argc, char** argv) { struct in_addr host; int port; int len; #ifdef USE_POLL struct pollfd ufds[2]; #else fd_set readfds; int maxfd; #endif #ifdef BB_FEATURE_AUTOWIDTH struct winsize winp; if( ioctl(0, TIOCGWINSZ, &winp) == 0 ) { win_width = winp.ws_col; win_height = winp.ws_row; } #endif #ifdef BB_FEATURE_TELNET_TTYPE ttype = getenv("TERM"); #endif memset(&G, 0, sizeof G); if (tcgetattr(0, &G.termios_def) < 0) exit(1); G.termios_raw = G.termios_def; cfmakeraw(&G.termios_raw); if (argc < 2) show_usage(); port = (argc > 2)? getport(argv[2]): 23; host = getserver(argv[1]); G.netfd = remote_connect(host, port); signal(SIGINT, fgotsig); #ifdef USE_POLL ufds[0].fd = 0; ufds[1].fd = G.netfd; ufds[0].events = ufds[1].events = POLLIN; #else FD_ZERO(&readfds); FD_SET(0, &readfds); FD_SET(G.netfd, &readfds); maxfd = G.netfd + 1; #endif while (1) { #ifndef USE_POLL fd_set rfds = readfds; switch (select(maxfd, &rfds, NULL, NULL, NULL)) #else switch (poll(ufds, 2, -1)) #endif { case 0: /* timeout */ case -1: /* error, ignore and/or log something, bay go to loop */ if (G.gotsig) conescape(); else sleep(1); break; default: #ifdef USE_POLL if (ufds[0].revents) /* well, should check POLLIN, but ... */ #else if (FD_ISSET(0, &rfds)) #endif { len = read(0, G.buf, DATABUFSIZE); if (len <= 0) doexit(0); TRACE(0, ("Read con: %d\n", len)); handlenetoutput(len); } #ifdef USE_POLL if (ufds[1].revents) /* well, should check POLLIN, but ... */ #else if (FD_ISSET(G.netfd, &rfds)) #endif { len = read(G.netfd, G.buf, DATABUFSIZE); if (len <= 0) { WriteCS(1, "Connection closed by foreign host.\r\n"); doexit(1); } TRACE(0, ("Read netfd (%d): %d\n", G.netfd, len)); handlenetinput(len); } } } }