1 #include <connection.h>
6 #include <sys/utsname.h>
10 extern std::vector<Module*> modules;
11 extern std::vector<ircd_module*> factory;
25 connection::connection()
32 bool connection::CreateListener(char* host, int p)
34 sockaddr_in host_address;
38 struct linger linger = { 0 };
40 fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
46 memset((void*)&host_address, 0, sizeof(host_address));
48 host_address.sin_family = AF_INET;
52 host_address.sin_addr.s_addr = htonl(INADDR_ANY);
56 inet_aton(host,&addy);
57 host_address.sin_addr = addy;
60 host_address.sin_port = htons(p);
62 if (bind(fd,(sockaddr*)&host_address,sizeof(host_address))<0)
67 // make the socket non-blocking
68 flags = fcntl(fd, F_GETFL, 0);
69 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
73 setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on));
76 setsockopt(fd,SOL_SOCKET,SO_LINGER,(const char*)&linger,sizeof(linger));
81 bool connection::BeginLink(char* targethost, int port, char* password)
87 sprintf(connect,"S %s %s :%s",getservername().c_str(),password,getserverdesc().c_str());
88 this->haspassed = false;
89 this->SendPacket(connect, targethost, port);
95 // targethost: in dot notation a.b.c.d
96 void connection::TerminateLink(char* targethost)
100 // host: in dot notation a.b.c.d
101 // port: host byte order
102 bool connection::SendPacket(char *message, char* host, int port)
104 sockaddr_in host_address;
108 memset((void*)&host_address, 0, sizeof(host_address));
110 host_address.sin_family = AF_INET;
111 inet_aton(host,&addy);
112 host_address.sin_addr = addy;
114 host_address.sin_port = htons(port);
116 strcpy(p.data,message);
117 p.type = PT_SYN_WITH_DATA;
121 FOREACH_MOD OnPacketTransmit(p.data);
123 // returns false if the packet could not be sent (e.g. target host down)
124 if (sendto(fd,&p,sizeof(p),0,(sockaddr*)&host_address,sizeof(host_address))<0)
132 bool connection::SendSYN(char* host, int port)
134 sockaddr_in host_address;
138 memset((void*)&host_address, 0, sizeof(host_address));
140 host_address.sin_family = AF_INET;
141 inet_aton(host,&addy);
142 host_address.sin_addr = addy;
144 host_address.sin_port = htons(port);
146 p.type = PT_SYN_ONLY;
150 if (sendto(fd,&p,sizeof(p),0,(sockaddr*)&host_address,sizeof(host_address))<0)
158 bool connection::SendACK(char* host, int port, int reply_id)
160 sockaddr_in host_address;
164 memset((void*)&host_address, 0, sizeof(host_address));
166 host_address.sin_family = AF_INET;
167 inet_aton(host,&addy);
168 host_address.sin_addr = addy;
170 host_address.sin_port = htons(port);
172 p.type = PT_ACK_ONLY;
177 if (sendto(fd,&p,sizeof(p),0,(sockaddr*)&host_address,sizeof(host_address))<0)
186 // Generates a server key. This is pseudo-random.
187 // the server always uses the same server-key in all communications
188 // across the network. All other servers must remember the server key
189 // of servers in the network, e.g.:
191 // ServerA: key=5555555555
192 // ServerB: key=6666666666
193 // I am ServerC: key=77777777777
195 // If ServerC sees a packet from ServerA, and the key stored for ServerA
196 // is 0, then cache the key as the servers key.
197 // after this point, any packet from ServerA which does not contain its key,
198 // 555555555, will be silently dropped.
199 // This should prevent blind spoofing, as to fake a server you must know its
200 // assigned key, and to do that you must receive messages that are origintated
201 // from it or hack the running executable.
203 // During the AUTH phase (when server passwords are checked, the key in any
204 // packet MUST be 0). Only the initial SERVER/PASS packets may have a key
205 // of 0 (and any ACK responses to them).
208 long connection::GenKey()
211 return (random()*time(NULL));
214 // host: in dot notation a.b.c.d
215 // port: host byte order
216 bool connection::RecvPacket(char *message, char* host, int &prt)
218 // returns false if no packet waiting for receive, e.g. EAGAIN or ECONNRESET
219 sockaddr_in host_address;
220 socklen_t host_address_size;
223 memset((void*)&host_address, 0, sizeof(host_address));
225 host_address.sin_family=AF_INET;
226 host_address_size=sizeof(host_address);
228 if (recvfrom(fd,&p,sizeof(p),0,(sockaddr*)&host_address,&host_address_size)<0)
233 if (p.type == PT_SYN_ONLY)
235 strcpy(message,p.data);
236 strcpy(host,inet_ntoa(host_address.sin_addr));
237 prt = ntohs(host_address.sin_port);
238 SendACK(host,this->port,p.id);
242 if (p.type == PT_ACK_ONLY)
244 strcpy(message,p.data);
245 strcpy(host,inet_ntoa(host_address.sin_addr));
246 prt = ntohs(host_address.sin_port);
250 if (p.type == PT_SYN_WITH_DATA)
252 strcpy(message,p.data);
253 strcpy(host,inet_ntoa(host_address.sin_addr));
254 prt = ntohs(host_address.sin_port);
255 SendACK(host,this->port,p.id);