1 #include <connection.h>
6 #include <sys/utsname.h>
15 extern std::vector<Module*> modules;
16 extern std::vector<ircd_module*> factory;
31 connection::connection()
38 bool connection::CreateListener(char* host, int p)
40 sockaddr_in host_address;
44 struct linger linger = { 0 };
46 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
52 memset((void*)&host_address, 0, sizeof(host_address));
54 host_address.sin_family = AF_INET;
58 host_address.sin_addr.s_addr = htonl(INADDR_ANY);
62 inet_aton(host,&addy);
63 host_address.sin_addr = addy;
66 host_address.sin_port = htons(p);
68 if (bind(fd,(sockaddr*)&host_address,sizeof(host_address))<0)
73 // make the socket non-blocking
74 flags = fcntl(fd, F_GETFL, 0);
75 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
79 setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on));
82 setsockopt(fd,SOL_SOCKET,SO_LINGER,(const char*)&linger,sizeof(linger));
84 // attempt to increase socket sendq and recvq as high as its possible
85 // to get them on linux.
88 setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
89 setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
96 char* ircd_connector::GetServerIP()
101 int ircd_connector::GetServerPort()
106 bool ircd_connector::SetHostAndPort(char* host, int port)
108 strncpy(this->host,host,160);
113 bool ircd_connector::SetHostAddress(char* host, int port)
115 strncpy(this->host,host,160);
117 memset((void*)&addr, 0, sizeof(addr));
118 addr.sin_family = AF_INET;
119 inet_aton(host,&addr.sin_addr);
120 addr.sin_port = htons(port);
124 bool ircd_connector::MakeOutboundConnection(char* host, int port)
126 hostent* hoste = gethostbyname(host);
129 WriteOpers("Failed to look up hostname for %s, using as an ip address",host);
130 this->SetHostAddress(host,port);
134 WriteOpers("Found hostname for %s",host);
135 this->SetHostAddress(hoste->h_addr,port);
138 this->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
141 if(connect(this->fd, (sockaddr*)&addr,sizeof(addr)))
143 WriteOpers("connect() failed for %s",host);
146 int flags = fcntl(this->fd, F_GETFL, 0);
147 fcntl(this->fd, F_SETFL, flags | O_NONBLOCK);
150 setsockopt(this->fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
151 setsockopt(this->fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
156 WriteOpers("socket() failed!");
163 bool connection::BeginLink(char* targethost, int port, char* password, char* servername)
165 char connect[MAXBUF];
167 ircd_connector connector;
171 if (connector.MakeOutboundConnection(targethost,port))
173 // targethost has been turned into an ip...
174 // we dont want this as the server name.
175 connector.SetServerName(servername);
176 sprintf(connect,"S %s %s :%s",getservername().c_str(),password,getserverdesc().c_str());
177 connector.SetState(STATE_NOAUTH_OUTBOUND);
178 this->connectors.push_back(connector);
179 return this->SendPacket(connect, servername);
183 WriteOpers("Could not create outbound connection to %s:%d",targethost,port);
189 bool connection::MeshCookie(char* targethost, int port, long cookie, char* servername)
191 char connect[MAXBUF];
193 ircd_connector connector;
195 WriteOpers("Establishing meshed link to %s:%d",targethost,port);
199 if (connector.MakeOutboundConnection(targethost,port))
201 // targethost has been turned into an ip...
202 // we dont want this as the server name.
203 connector.SetServerName(servername);
204 sprintf(connect,"- %d %s :%s",cookie,getservername().c_str(),getserverdesc().c_str());
205 connector.SetState(STATE_NOAUTH_OUTBOUND);
206 this->connectors.push_back(connector);
207 return this->SendPacket(connect, servername);
211 WriteOpers("Could not create outbound connection to %s:%d",targethost,port);
217 bool connection::AddIncoming(int fd,char* targethost, int sourceport)
219 char connect[MAXBUF];
221 ircd_connector connector;
223 // targethost has been turned into an ip...
224 // we dont want this as the server name.
225 connector.SetHostAndPort(targethost, sourceport);
226 connector.SetServerName(targethost);
227 connector.SetDescriptor(fd);
228 connector.SetState(STATE_NOAUTH_INBOUND);
229 int flags = fcntl(fd, F_GETFL, 0);
230 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
233 setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
234 setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
235 log(DEBUG,"connection::AddIncoming() Added connection: %s:%d",host,sourceport);
236 this->connectors.push_back(connector);
240 void connection::TerminateLink(char* targethost)
242 // this locates the targethost in the connection::connectors vector of the class,
243 // and terminates it by sending it an SQUIT token and closing its descriptor.
244 // TerminateLink with a null string causes a terminate of ALL links
248 // Returns a pointer to the connector for 'host'
249 ircd_connector* connection::FindHost(std::string host)
251 for (int i = 0; i < this->connectors.size(); i++)
253 if (this->connectors[i].GetServerName() == host)
255 return &this->connectors[i];
261 std::string ircd_connector::GetServerName()
263 return this->servername;
266 void ircd_connector::SetServerName(std::string serv)
268 this->servername = serv;
272 int ircd_connector::GetDescriptor()
277 int ircd_connector::GetState()
283 void ircd_connector::SetState(int state)
288 void ircd_connector::SetDescriptor(int fd)
293 bool connection::SendPacket(char *message, const char* host)
295 ircd_connector* cn = this->FindHost(host);
299 log(DEBUG,"main: Connection::SendPacket() sent '%s' to %s",message,cn->GetServerName().c_str());
301 strncat(message,"\n",MAXBUF);
302 // returns false if the packet could not be sent (e.g. target host down)
303 if (send(cn->GetDescriptor(),message,strlen(message),0)<0)
305 log(DEBUG,"send() failed for Connection::SendPacket(): %s",strerror(errno));
312 // receives a packet from any where there is data waiting, first come, first served
313 // fills the message and host values with the host where the data came from.
315 bool connection::RecvPacket(std::deque<std::string> &messages, char* host)
318 memset(data, 0, 32767);
319 for (int i = 0; i < this->connectors.size(); i++)
321 // returns false if the packet could not be sent (e.g. target host down)
323 if (rcvsize = recv(this->connectors[i].GetDescriptor(),data,32767,0))
327 char* l = strtok(data,"\n");
330 char sanitized[32767];
331 memset(sanitized, 0, 32767);
333 for (int pt = 0; pt < strlen(l); pt++)
337 sanitized[ptt++] = l[pt];
340 sanitized[ptt] = '\0';
341 if (strlen(sanitized))
343 messages.push_back(sanitized);
344 strncpy(host,this->connectors[i].GetServerName().c_str(),160);
345 log(DEBUG,"main: Connection::RecvPacket() got '%s' from %s",sanitized,host);
348 l = strtok(NULL,"\n");
354 // nothing new yet -- message and host will be undefined
358 long connection::GenKey()
361 return (random()*time(NULL));