1 #include <connection.h>
6 #include <sys/utsname.h>
14 extern std::vector<Module*> modules;
15 extern std::vector<ircd_module*> factory;
30 connection::connection()
37 bool connection::CreateListener(char* host, int p)
39 sockaddr_in host_address;
43 struct linger linger = { 0 };
45 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
51 memset((void*)&host_address, 0, sizeof(host_address));
53 host_address.sin_family = AF_INET;
57 host_address.sin_addr.s_addr = htonl(INADDR_ANY);
61 inet_aton(host,&addy);
62 host_address.sin_addr = addy;
65 host_address.sin_port = htons(p);
67 if (bind(fd,(sockaddr*)&host_address,sizeof(host_address))<0)
72 // make the socket non-blocking
73 flags = fcntl(fd, F_GETFL, 0);
74 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
78 setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on));
81 setsockopt(fd,SOL_SOCKET,SO_LINGER,(const char*)&linger,sizeof(linger));
83 // attempt to increase socket sendq and recvq as high as its possible
84 // to get them on linux.
87 setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
88 setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
95 bool ircd_connector::SetHostAddress(char* host, int port)
97 memset((void*)&addr, 0, sizeof(addr));
98 addr.sin_family = AF_INET;
99 inet_aton(host,&addr.sin_addr);
100 addr.sin_port = htons(port);
104 bool ircd_connector::MakeOutboundConnection(char* host, int port)
106 hostent* hoste = gethostbyname(host);
109 WriteOpers("Failed to look up hostname for %s, using as an ip address",host);
110 this->SetHostAddress(host,port);
114 WriteOpers("Found hostname for %s",host);
115 this->SetHostAddress(hoste->h_addr,port);
118 this->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
121 if(connect(this->fd, (sockaddr*)&addr,sizeof(addr)))
123 WriteOpers("connect() failed for %s",host);
126 int flags = fcntl(this->fd, F_GETFL, 0);
127 fcntl(this->fd, F_SETFL, flags | O_NONBLOCK);
130 setsockopt(this->fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
131 setsockopt(this->fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
136 WriteOpers("socket() failed!");
143 bool connection::BeginLink(char* targethost, int port, char* password, char* servername)
145 char connect[MAXBUF];
147 ircd_connector connector;
151 if (connector.MakeOutboundConnection(targethost,port))
153 // targethost has been turned into an ip...
154 // we dont want this as the server name.
155 connector.SetServerName(servername);
156 sprintf(connect,"S %s %s :%s",getservername().c_str(),password,getserverdesc().c_str());
157 connector.SetState(STATE_NOAUTH_OUTBOUND);
158 this->connectors.push_back(connector);
159 return this->SendPacket(connect, servername);
163 WriteOpers("Could not create outbound connection to %s:%d",targethost,port);
169 bool connection::AddIncoming(int fd,char* targethost)
171 char connect[MAXBUF];
173 ircd_connector connector;
175 // targethost has been turned into an ip...
176 // we dont want this as the server name.
177 connector.SetServerName(targethost);
178 connector.SetDescriptor(fd);
179 connector.SetState(STATE_NOAUTH_INBOUND);
180 this->connectors.push_back(connector);
184 void connection::TerminateLink(char* targethost)
186 // this locates the targethost in the connection::connectors vector of the class,
187 // and terminates it by sending it an SQUIT token and closing its descriptor.
188 // TerminateLink with a null string causes a terminate of ALL links
192 // Returns a pointer to the connector for 'host'
193 ircd_connector* connection::FindHost(std::string host)
195 for (int i = 0; i < this->connectors.size(); i++)
197 if (this->connectors[i].GetServerName() == host)
199 return &this->connectors[i];
205 std::string ircd_connector::GetServerName()
207 return this->servername;
210 void ircd_connector::SetServerName(std::string serv)
212 this->servername = serv;
216 int ircd_connector::GetDescriptor()
221 int ircd_connector::GetState()
227 void ircd_connector::SetState(int state)
232 void ircd_connector::SetDescriptor(int fd)
237 bool connection::SendPacket(char *message, char* host)
239 ircd_connector* cn = this->FindHost(host);
243 log(DEBUG,"main: Connection::SendPacket() sent '%s' to %s",message,cn->GetServerName().c_str());
245 strncat(message,"\n",MAXBUF);
246 // returns false if the packet could not be sent (e.g. target host down)
247 if (send(cn->GetDescriptor(),message,strlen(message),0)<0)
249 log(DEBUG,"send() failed for Connection::SendPacket(): %s",strerror(errno));
256 // receives a packet from any where there is data waiting, first come, first served
257 // fills the message and host values with the host where the data came from.
259 bool connection::RecvPacket(char *message, char* host)
261 for (int i = 0; i < this->connectors.size(); i++)
263 // returns false if the packet could not be sent (e.g. target host down)
265 if (rcvsize = recv(this->connectors[i].GetDescriptor(),message,MAXBUF,0))
269 // something new on this socket, fill the return values and bail
270 strncpy(host,this->connectors[i].GetServerName().c_str(),160);
271 message[rcvsize-1] = 0;
276 // nothing new yet -- message and host will be undefined
280 long connection::GenKey()
283 return (random()*time(NULL));