1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
7 * <brain@chatspike.net>
8 * <Craig@chatspike.net>
10 * Written by Craig Edwards, Craig McLure, and others.
11 * This program is free but copyrighted software; see
12 * the file COPYING for details.
14 * ---------------------------------------------------
19 #include <connection.h>
23 #include <sys/errno.h>
24 #include <sys/ioctl.h>
25 #include <sys/utsname.h>
32 #include "inspstring.h"
33 #include "helperfuncs.h"
36 extern std::vector<Module*> modules;
37 extern std::vector<ircd_module*> factory;
45 * The InspIRCd mesh network is maintained by a tree of objects which reference *themselves*.
46 * Every local server has an array of 32 *serverrecs, known as me[]. Each of these represents
47 * a local listening port, and is not null if the user has opened a listening port on the server.
48 * It is assumed nobody will ever want to open more than 32 listening server ports at any one
49 * time (i mean come on, why would you want more, the ircd works fine with ONE).
50 * Each me[] entry has multiple classes within it of type ircd_connector. These are stored in a vector
51 * and each represents a server linked via this socket. If the connection was created outbound,
52 * the connection is bound to the default ip address by using me[defaultRoute] (defaultRoute being
53 * a global variable which indicates the default server to make connections on). If the connection
54 * was created inbound, it is attached to the port the connection came in on. There may be as many
55 * ircd_connector objects as needed in each me[] entry. Each ircd_connector implements the specifics
56 * of an ircd connection in the mesh, however each ircd may have multiple ircd_connector connections
57 * to it, to maintain the mesh link.
60 char* xsumtable = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
62 // creates a random id for a line for detection of duplicate messages
63 std::string CreateSum()
68 for(int q = 1; q < 8; q++)
69 sum[q] = xsumtable[rand()%52];
73 connection::connection()
79 char* ircd_connector::GetServerIP()
84 int ircd_connector::GetServerPort()
89 bool ircd_connector::SetHostAndPort(char* newhost, int newport)
91 strncpy(this->host,newhost,160);
96 bool ircd_connector::SetHostAddress(char* newhost, int newport)
98 strncpy(this->host,newhost,160);
100 memset((void*)&addr, 0, sizeof(addr));
101 addr.sin_family = AF_INET;
102 inet_aton(host,&addr.sin_addr);
103 addr.sin_port = htons(port);
107 void ircd_connector::SetServerPort(int p)
112 void ircd_connector::AddBuffer(std::string a)
115 for (int i = 0; i < a.length(); i++)
119 std::stringstream stream(ircdbuffer);
121 log(DEBUG,"AddBuffer: %s",b.c_str());
122 ircdbuffer = stream.str();
125 bool ircd_connector::BufferIsComplete()
127 for (int i = 0; i < ircdbuffer.length(); i++)
128 if (ircdbuffer[i] == '\n')
133 void ircd_connector::ClearBuffer()
138 std::string ircd_connector::GetBuffer()
140 // Fix by Brain 28th Apr 2005
141 // seems my stringstream code isnt liked by linux
142 // EVEN THOUGH IT IS CORRECT! Fixed by using a different
143 // (SLOWER) algorithm...
144 char* line = (char*)ircdbuffer.c_str();
145 std::string ret = "";
146 while ((*line != '\n') && (strlen(line)))
151 if ((*line == '\n') || (*line == '\r'))
157 bool ircd_connector::MakeOutboundConnection(char* newhost, int newport)
159 log(DEBUG,"MakeOutboundConnection: Original param: %s",newhost);
161 hostent* hoste = gethostbyname(newhost);
164 log(DEBUG,"MakeOutboundConnection: gethostbyname was NULL, setting %s",newhost);
165 this->SetHostAddress(newhost,newport);
166 SetHostAndPort(newhost,newport);
170 struct in_addr* ia = (in_addr*)hoste->h_addr;
171 log(DEBUG,"MakeOutboundConnection: gethostbyname was valid, setting %s",inet_ntoa(*ia));
172 this->SetHostAddress(inet_ntoa(*ia),newport);
173 SetHostAndPort(inet_ntoa(*ia),newport);
176 this->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
179 if(connect(this->fd, (sockaddr*)&this->addr,sizeof(this->addr)))
181 WriteOpers("connect() failed for %s",host);
182 RemoveServer(this->servername.c_str());
185 int flags = fcntl(this->fd, F_GETFL, 0);
186 fcntl(this->fd, F_SETFL, flags | O_NONBLOCK);
189 setsockopt(this->fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
190 setsockopt(this->fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
195 WriteOpers("socket() failed!");
196 RemoveServer(this->servername.c_str());
203 void ircd_connector::SetVersionString(std::string newversion)
205 log(DEBUG,"Set version of %s to %s",this->servername.c_str(),newversion.c_str());
206 this->version = newversion;
209 std::string ircd_connector::GetVersionString()
211 return this->version;
215 std::string ircd_connector::GetServerName()
217 return this->servername;
220 std::string ircd_connector::GetDescription()
222 return this->description;
225 void ircd_connector::SetServerName(std::string serv)
227 this->servername = serv;
230 void ircd_connector::SetDescription(std::string desc)
232 this->description = desc;
236 int ircd_connector::GetDescriptor()
241 int ircd_connector::GetState()
247 void ircd_connector::SetState(int newstate)
249 this->state = newstate;
250 if (state == STATE_DISCONNECTED)
252 NetSendMyRoutingTable();
256 void ircd_connector::CloseConnection()
258 int flags = fcntl(this->fd, F_GETFL, 0);
259 fcntl(this->fd, F_SETFL, flags ^ O_NONBLOCK);
261 flags = fcntl(this->fd, F_GETFL, 0);
262 fcntl(this->fd, F_SETFL, flags | O_NONBLOCK);
265 void ircd_connector::SetDescriptor(int newfd)