+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
+ * E-mail:
+ * <brain@chatspike.net>
+ * <Craig@chatspike.net>
+ *
+ * Written by Craig Edwards, Craig McLure, and others.
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
#include <connection.h>
#include <unistd.h>
#include <fcntl.h>
#include <deque>
#include "inspircd.h"
#include "modules.h"
+#include "inspstring.h"
using namespace std;
+
extern std::vector<Module*> modules;
extern std::vector<ircd_module*> factory;
extern int MODCOUNT;
+extern time_t TIME;
+
connection::connection()
{
fd = 0;
return false;
}
+ setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on));
+ linger.l_onoff = 1;
+ linger.l_linger = 1;
+ setsockopt(fd,SOL_SOCKET,SO_LINGER,(const char*)&linger,sizeof(linger));
+
+ // attempt to increase socket sendq and recvq as high as its possible
+ // to get them on linux.
+ int sendbuf = 32768;
+ int recvbuf = 32768;
+ setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
+ setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
+
memset((void*)&host_address, 0, sizeof(host_address));
host_address.sin_family = AF_INET;
this->port = p;
- setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on));
- linger.l_onoff = 1;
- linger.l_linger = 0;
- setsockopt(fd,SOL_SOCKET,SO_LINGER,(const char*)&linger,sizeof(linger));
-
- // attempt to increase socket sendq and recvq as high as its possible
- // to get them on linux.
- int sendbuf = 32768;
- int recvbuf = 32768;
- setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
- setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
-
listen(this->fd,5);
return true;
if(connect(this->fd, (sockaddr*)&this->addr,sizeof(this->addr)))
{
WriteOpers("connect() failed for %s",host);
+ RemoveServer(this->servername.c_str());
return false;
}
int flags = fcntl(this->fd, F_GETFL, 0);
else
{
WriteOpers("socket() failed!");
+ RemoveServer(this->servername.c_str());
}
return false;
char connect[MAXBUF];
ircd_connector connector;
+ ircd_connector *cn = this->FindHost(servername);
+
+
+ if (cn)
+ {
+ WriteOpers("CONNECT aborted: Server %s already exists",servername);
+ return false;
+ }
+
if (this->fd)
{
// targethost has been turned into an ip...
// we dont want this as the server name.
connector.SetServerName(servername);
- sprintf(connect,"S %s %s %d %d :%s",getservername().c_str(),password,myport,GetRevision(),getserverdesc().c_str());
+ snprintf(connect,MAXBUF,"S %s %s %d %d :%s",getservername().c_str(),password,myport,GetRevision(),getserverdesc().c_str());
connector.SetState(STATE_NOAUTH_OUTBOUND);
connector.SetHostAndPort(targethost, port);
this->connectors.push_back(connector);
// targethost has been turned into an ip...
// we dont want this as the server name.
connector.SetServerName(servername);
- sprintf(connect,"- %d %s :%s",cookie,getservername().c_str(),getserverdesc().c_str());
+ snprintf(connect,MAXBUF,"- %d %s :%s",cookie,getservername().c_str(),getserverdesc().c_str());
connector.SetState(STATE_NOAUTH_OUTBOUND);
connector.SetHostAndPort(targethost, port);
connector.SetState(STATE_CONNECTED);
bool connection::SendPacket(char *message, const char* host)
{
+ if ((!message) || (!host))
+ return true;
+
ircd_connector* cn = this->FindHost(host);
if (!strchr(message,'\n'))
{
- strncat(message,"\n",MAXBUF);
+ strlcat(message,"\n",MAXBUF);
}
if (cn)
if (cn->GetState() == STATE_DISCONNECTED)
{
log(DEBUG,"Main route to %s is down, seeking alternative",host);
- // this route is down, we must re-route the packet through an available point in the mesh.
- for (int k = 0; k < this->connectors.size(); k++)
+ // fix: can only route one hop to avoid a loop
+ if (strlcat(message,"R ",2))
{
- // search for another point in the mesh which can 'reach' where we want to go
- for (int m = 0; m < this->connectors[k].routes.size(); m++)
+ // this route is down, we must re-route the packet through an available point in the mesh.
+ for (int k = 0; k < this->connectors.size(); k++)
{
- if (!strcasecmp(this->connectors[k].routes[m].c_str(),host))
+ // search for another point in the mesh which can 'reach' where we want to go
+ for (int m = 0; m < this->connectors[k].routes.size(); m++)
{
- log(DEBUG,"Found alternative route for packet: %s",this->connectors[k].GetServerName().c_str());
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"R %s %s",host,message);
- this->SendPacket(buffer,this->connectors[k].GetServerName().c_str());
- return true;
+ if (!strcasecmp(this->connectors[k].routes[m].c_str(),host))
+ {
+ log(DEBUG,"Found alternative route for packet: %s",this->connectors[k].GetServerName().c_str());
+ char buffer[MAXBUF];
+ snprintf(buffer,MAXBUF,"R %s %s",host,message);
+ this->SendPacket(buffer,this->connectors[k].GetServerName().c_str());
+ return true;
+ }
}
}
}
cn->CloseConnection();
cn->SetState(STATE_DISCONNECTED);
// retry the packet along a new route so either arrival OR failure are gauranteed (bugfix)
- this->SendPacket(message,host);
- return false;
+ return this->SendPacket(message,host);
}
return true;
}
if (strlen(sanitized))
{
messages.push_back(sanitized);
- strncpy(host,this->connectors[i].GetServerName().c_str(),160);
+ strlcpy(host,this->connectors[i].GetServerName().c_str(),160);
log(DEBUG,"main: Connection::RecvPacket() got '%s' from %s",sanitized,host);
}
long connection::GenKey()
{
- srand(time(NULL));
return (random()*time(NULL));
}