}
else
{
- log(DEBUG,"*** BUG *** Non-module umode passed to process_module_umode!");
if (faked)
{
delete s2;
// send out an squit across the mesh and then clear the server list (for local squit)
}
-char islast(serverrec* s)
+char islast(const char* s)
{
char c = '`';
- /*for (int j = 0; j < 255; j++)
+ for (int j = 0; j < 32; j++)
{
- if (servers[j] != NULL)
- {
- c = '|';
- }
- if (servers[j] == s)
- {
- c = '`';
+ if (me[j] != NULL)
+ {
+ for (int k = 0; k < me[j]->connectors.size(); k++)
+ {
+ if (strcasecmp(me[j]->connectors[k].GetServerName().c_str(),s))
+ {
+ c = '|';
+ }
+ if (!strcasecmp(me[j]->connectors[k].GetServerName().c_str(),s))
+ {
+ c = '`';
+ }
+ }
}
- }*/
+ }
return c;
}
-long map_count(serverrec* s)
+long map_count(const char* s)
{
int c = 0;
for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
{
- if ((i->second->fd) && (isnick(i->second->nick)) && (!strcasecmp(i->second->server,s->name))) c++;
+ if ((i->second->fd) && (isnick(i->second->nick)) && (!strcasecmp(i->second->server,s))) c++;
}
return c;
}
void handle_links(char **parameters, int pcnt, userrec *user)
{
WriteServ(user->fd,"364 %s %s %s :0 %s",user->nick,ServerName,ServerName,ServerDesc);
- for (int j = 0; j < 255; j++)
+ for (int j = 0; j < 32; j++)
{
- // if (servers[j] != NULL)
- // {
- // WriteServ(user->fd,"364 %s %s %s :1 %s",user->nick,servers[j]->name,ServerName,servers[j]->description);
- // }
+ if (me[j] != NULL)
+ {
+ for (int k = 0; k < me[j]->connectors.size(); k++)
+ {
+ WriteServ(user->fd,"364 %s %s %s :1 %s",user->nick,me[j]->connectors[k].GetServerName().c_str(),ServerName,me[j]->connectors[k].GetDescription().c_str());
+ }
+ }
}
WriteServ(user->fd,"365 %s * :End of /LINKS list.",user->nick);
}
while (strlen(line) < 50)
strcat(line," ");
WriteServ(user->fd,"%s%d (%.2f%%)",line,local_count(),(float)(((float)local_count()/(float)usercnt())*100));
- for (int j = 0; j < 255; j++)
+ for (int j = 0; j < 32; j++)
{
- // if (servers[j] != NULL)
- // {
- // snprintf(line,MAXBUF,"006 %s :%c-%s",user->nick,islast(servers[j]),servers[j]->name);
- // while (strlen(line) < 50)
- // strcat(line," ");
- // WriteServ(user->fd,"%s%d (%.2f%%)",line,map_count(servers[j]),(float)(((float)map_count(servers[j])/(float)usercnt())*100));
- // }
+ if (me[j] != NULL)
+ {
+ for (int k = 0; k < me[j]->connectors.size(); k++)
+ {
+ snprintf(line,MAXBUF,"006 %s :%c-%s",user->nick,islast(me[j]->connectors[k].GetServerName().c_str()),me[j]->connectors[k].GetServerName().c_str());
+ while (strlen(line) < 50)
+ strcat(line," ");
+ WriteServ(user->fd,"%s%d (%.2f%%)",line,map_count(me[j]->connectors[k].GetServerName().c_str()),(float)(((float)map_count(me[j]->connectors[k].GetServerName().c_str())/(float)usercnt())*100));
+ }
+ }
}
WriteServ(user->fd,"007 %s :End of /MAP",user->nick);
}
{
/* found this oper's opertype */
ConfValue("type","host",j,Hostname,&config_f);
- strncpy(user->dhost,Hostname,256);
+ ChangeDisplayedHost(user,Hostname);
}
}
if (!strchr(user->modes,'o'))
strncpy(clientlist[nick]->host, host,160);
strncpy(clientlist[nick]->dhost, dhost,160);
strncpy(clientlist[nick]->server, server,256);
- strncpy(clientlist[nick]->ident, ident,10); // +1 char to compensate for '~'
+ strncpy(clientlist[nick]->ident, ident,10); // +1 char to compensate for tilde
strncpy(clientlist[nick]->fullname, gecos,128);
clientlist[nick]->signon = TS;
clientlist[nick]->nping = 0; // this is ignored for a remote user anyway.
void handle_plus(char token,char* params,serverrec* source,serverrec* reply, char* udp_host)
{
// %s %s %d %d
+ // + test3.chatspike.net 7010 -2016508415
char* servername = strtok(params," ");
char* ipaddr = strtok(NULL," ");
char* ipport = strtok(NULL," ");
char* cookie = strtok(NULL," ");
+ log(DEBUG," ");
+ log(DEBUG," ");
+ log(DEBUG,"*** Connecting back to %s:%d",ipaddr,atoi(ipport));
me[defaultRoute]->MeshCookie(ipaddr,atoi(ipport),atoi(cookie),servername);
+ log(DEBUG," ");
}
+void handle_R(char token,char* params,serverrec* source,serverrec* reply, char* udp_host)
+{
+ char* server = strtok(params," ");
+ char* data = strtok(NULL,"\r\n");
+ log(DEBUG,"Forwarded packet '%s' to '%s'",data,server);
+ NetSendToOne(server,data);
+}
void handle_J(char token,char* params,serverrec* source,serverrec* reply, char* udp_host)
{
}
}
+void NetSendMyRoutingTable()
+{
+ // send out a line saying what is reachable to us.
+ // E.g. if A is linked to B C and D, send out:
+ // $ A B C D
+ // if its only linked to B and D send out:
+ // $ A B D
+ // if it has no links, dont even send out the line at all.
+ char buffer[MAXBUF];
+ sprintf(buffer,"$ %s",ServerName);
+ bool sendit = false;
+ for (int i = 0; i < 32; i++)
+ {
+ if (me[i] != NULL)
+ {
+ for (int j = 0; j < me[i]->connectors.size(); j++)
+ {
+ if (me[i]->connectors[j].GetState() != STATE_DISCONNECTED)
+ {
+ strncat(buffer," ",MAXBUF);
+ strncat(buffer,me[i]->connectors[j].GetServerName().c_str(),MAXBUF);
+ sendit = true;
+ }
+ }
+ }
+ }
+ if (sendit)
+ NetSendToAll(buffer);
+}
+
+void handle_dollar(char token,char* params,serverrec* source,serverrec* reply, char* udp_host)
+{
+ log(DEBUG,"Storing routing table...");
+ char* sourceserver = strtok(params," ");
+ char* server = strtok(NULL," ");
+ for (int i = 0; i < 32; i++)
+ {
+ if (me[i] != NULL)
+ {
+ for (int j = 0; j < me[i]->connectors.size(); j++)
+ {
+ if (!strcasecmp(me[i]->connectors[j].GetServerName().c_str(),sourceserver))
+ {
+ me[i]->connectors[j].routes.clear();
+ log(DEBUG,"Found entry for source server.");
+ while (server)
+ {
+ // store each route
+ me[i]->connectors[j].routes.push_back(server);
+ log(DEBUG,"*** Stored route: %s -> %s -> %s",ServerName,sourceserver,server);
+ server = strtok(NULL," ");
+ }
+ return;
+ }
+ }
+ }
+ }
+ log(DEBUG,"Warning! routing table received from nonexistent server!");
+}
+
+
void process_restricted_commands(char token,char* params,serverrec* source,serverrec* reply, char* udp_host,char* ipaddr,int port)
{
long authcookie = rand()*rand();
+ char buffer[MAXBUF];
switch(token)
{
WriteOpers("Server %s is starting netburst.",udp_host);
// now broadcast this new servers address out to all servers that are linked to us,
// except the newcomer. They'll all attempt to connect back to it.
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"+ %s %s %d %d",udp_host,ipaddr,port,authcookie);
- NetSendToAllExcept(buffer,udp_host);
+
+ // give the server its authcookie.
snprintf(buffer,MAXBUF,"~ %d",authcookie);
- NetSendToAllExcept(buffer,udp_host);
+ source->SendPacket(buffer,udp_host);
+ // tell all the other servers to use this authcookie to connect back again
+ // got '+ test3.chatspike.net 7010 -2016508415' from test.chatspike.net
+ snprintf(buffer,MAXBUF,"+ %s %s %d %d",udp_host,ipaddr,port,authcookie);
+ NetSendToAllExcept(udp_host,buffer);
break;
// ~
// Store authcookie
// without user or password, using it.
case '~':
auth_cookies.push_back(atoi(params));
- log(DEBUG,"Stored auth cookie, will permit servers with auth-cookie %d",atoi(params));
+ log(DEBUG,"*** Stored auth cookie, will permit servers with auth-cookie %d",atoi(params));
break;
// connect back to a server using an authcookie
case '+':
handle_plus(token,params,source,reply,udp_host);
break;
+ // routing table
+ case '$':
+ handle_dollar(token,params,source,reply,udp_host);
+ break;
+ // R <server> <data>
+ // redirect token, send all of <data> along to the given
+ // server as this server has been found to still have a route to it
+ case 'R':
+ handle_R(token,params,source,reply,udp_host);
+ break;
// ?
// ping
case '?':
WriteOpers("Sending my netburst to %s",udp_host);
DoSync(source,udp_host);
WriteOpers("Send of netburst to %s completed",udp_host);
-
+ NetSendMyRoutingTable();
break;
// anything else
default:
if (auth_cookies[u] == atoi(cookie))
{
WriteOpers("Allowed cookie from %s, is now part of the mesh",servername);
+
+
+ for (int j = 0; j < 32; j++)
+ {
+ if (me[j] != NULL)
+ {
+ for (int k = 0; k < me[j]->connectors.size(); k++)
+ {
+ if (!strcasecmp(me[j]->connectors[k].GetServerName().c_str(),udp_host))
+ {
+ me[j]->connectors[k].SetServerName(servername);
+ NetSendMyRoutingTable();
+ return;
+ }
+ }
+ }
+ WriteOpers("\2WARNING!\2 %s sent us an authentication packet but we are not authenticating with this server right now! Possible intrusion attempt!",udp_host);
+ return;
+ }
+
+
return;
}
}
+ // bad cookie, bad bad! go sit in the corner!
WriteOpers("Bad cookie from %s!",servername);
return;
}
sprintf(buffer,"X 0");
serv->SendPacket(buffer,udp_host);
DoSync(me[j],udp_host);
+ NetSendMyRoutingTable();
return;
}
}
// *FIX* Instead of closing sockets in kill_link when they receive the ERROR :blah line, we should queue
// them in a list, then reap the list every second or so.
- if (reap_counter>5000)
+ if (reap_counter>2500)
{
if (fd_reap.size() > 0)
{
fd_reap.clear();
reap_counter=0;
}
+ reap_counter++;
fd_set serverfds;
FD_ZERO(&serverfds);
{
if (FD_ISSET (me[x]->fd, &serverfds))
{
- char remotehost[MAXBUF];
+ char remotehost[MAXBUF],resolved[MAXBUF];
+ length = sizeof (client);
incomingSockfd = accept (me[x]->fd, (sockaddr *) &client, &length);
- strncpy (remotehost,(char *) inet_ntoa (client.sin_addr),MAXBUF);
+ strncpy(remotehost,(char *)inet_ntoa(client.sin_addr),MAXBUF);
+ if(CleanAndResolve(resolved, remotehost) != TRUE)
+ {
+ strncpy(resolved,remotehost,MAXBUF);
+ }
// add to this connections ircd_connector vector
- me[x]->AddIncoming(incomingSockfd,remotehost,ntohs(client.sin_port));
+ me[x]->AddIncoming(incomingSockfd,resolved,ntohs(client.sin_port));
}
}
}
char udp_msg[MAXBUF];
strncpy(udp_msg,msgs[ctr].c_str(),MAXBUF);
if (strlen(udp_msg)<1)
- {
+ {
log(DEBUG,"Invalid string from %s [route%d]",udp_host,x);
break;
}
// during a netburst, send all data to all other linked servers
if ((nb_start>0) && (udp_msg[0] != 'Y') && (udp_msg[0] != 'X') && (udp_msg[0] != 'F'))
{
- NetSendToAllExcept(udp_msg,udp_host);
+ NetSendToAllExcept(udp_host,udp_msg);
}
FOREACH_MOD OnPacketReceive(udp_msg);
handle_link_packet(udp_msg, udp_host, me[x]);
FD_SET (openSockfd[count], &selectFds);
}
- reap_counter++;
tv.tv_usec = 1;
selectResult = select(MAXSOCKS, &selectFds, NULL, NULL, &tv);
{
if (FD_ISSET (openSockfd[count], &selectFds))
{
+ length = sizeof (client);
incomingSockfd = accept (openSockfd[count], (struct sockaddr *) &client, &length);
address_cache::iterator iter = IP.find(client.sin_addr);