1 #include <connection.h>
6 #include <sys/utsname.h>
19 connection::connection()
26 bool connection::CreateListener(char* host, int port)
28 sockaddr_in host_address;
32 fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
38 memset((void*)&host_address, 0, sizeof(host_address));
40 host_address.sin_family = AF_INET;
44 host_address.sin_addr.s_addr = htonl(INADDR_ANY);
48 inet_aton(host,&addy);
49 host_address.sin_addr = addy;
52 host_address.sin_port = htons(port);
54 if (bind(fd, (sockaddr*)&host_address, sizeof(host_address))<0)
59 // make the socket non-blocking
60 flags = fcntl(fd, F_GETFL, 0);
61 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
66 bool connection::BeginLink(char* targethost, int port, char* password)
72 sprintf(connect,"S %s %s :%s",getservername().c_str(),password,getserverdesc().c_str());
73 this->haspassed = false;
74 this->SendPacket(connect, targethost, port);
80 // targethost: in dot notation a.b.c.d
81 void connection::TerminateLink(char* targethost)
85 // host: in dot notation a.b.c.d
86 // port: host byte order
87 bool connection::SendPacket(char *message, char* host, int port)
89 sockaddr_in host_address;
93 memset((void*)&host_address, 0, sizeof(host_address));
95 host_address.sin_family = AF_INET;
96 inet_aton(host,&addy);
97 host_address.sin_addr = addy;
99 host_address.sin_port = htons(port);
101 strcpy(p.data,message);
102 p.type = PT_SYN_WITH_DATA;
105 // returns false if the packet could not be sent (e.g. target host down)
106 if (sendto(fd,&p,sizeof(p),0,(sockaddr*)&host_address,sizeof(host_address))<0)
114 bool connection::SendSYN(char* host, int port)
116 sockaddr_in host_address;
120 memset((void*)&host_address, 0, sizeof(host_address));
122 host_address.sin_family = AF_INET;
123 inet_aton(host,&addy);
124 host_address.sin_addr = addy;
126 host_address.sin_port = htons(port);
128 p.type = PT_SYN_ONLY;
132 if (sendto(fd,&p,sizeof(p),0,(sockaddr*)&host_address,sizeof(host_address))<0)
140 bool connection::SendACK(char* host, int port, int reply_id)
142 sockaddr_in host_address;
146 memset((void*)&host_address, 0, sizeof(host_address));
148 host_address.sin_family = AF_INET;
149 inet_aton(host,&addy);
150 host_address.sin_addr = addy;
152 host_address.sin_port = htons(port);
154 p.type = PT_ACK_ONLY;
159 if (sendto(fd,&p,sizeof(p),0,(sockaddr*)&host_address,sizeof(host_address))<0)
168 // Generates a server key. This is pseudo-random.
169 // the server always uses the same server-key in all communications
170 // across the network. All other servers must remember the server key
171 // of servers in the network, e.g.:
173 // ServerA: key=5555555555
174 // ServerB: key=6666666666
175 // I am ServerC: key=77777777777
177 // If ServerC sees a packet from ServerA, and the key stored for ServerA
178 // is 0, then cache the key as the servers key.
179 // after this point, any packet from ServerA which does not contain its key,
180 // 555555555, will be silently dropped.
181 // This should prevent blind spoofing, as to fake a server you must know its
182 // assigned key, and to do that you must receive messages that are origintated
183 // from it or hack the running executable.
185 // During the AUTH phase (when server passwords are checked, the key in any
186 // packet MUST be 0). Only the initial SERVER/PASS packets may have a key
187 // of 0 (and any ACK responses to them).
190 long connection::GenKey()
193 return (random()*time(NULL));
196 // host: in dot notation a.b.c.d
197 // port: host byte order
198 bool connection::RecvPacket(char *message, char* host, int &port)
200 // returns false if no packet waiting for receive, e.g. EAGAIN or ECONNRESET
201 sockaddr_in host_address;
202 socklen_t host_address_size;
205 memset((void*)&host_address, 0, sizeof(host_address));
207 host_address.sin_family=AF_INET;
208 host_address_size=sizeof(host_address);
210 if (recvfrom(fd,&p,sizeof(p),0,(sockaddr*)&host_address,&host_address_size)<0)
215 if (p.type == PT_SYN_ONLY)
217 strcpy(message,p.data);
218 strcpy(host,inet_ntoa(host_address.sin_addr));
219 port = ntohs(host_address.sin_port);
220 SendACK(host,port,p.id);
224 if (p.type == PT_ACK_ONLY)
226 strcpy(message,p.data);
227 strcpy(host,inet_ntoa(host_address.sin_addr));
228 port = ntohs(host_address.sin_port);
229 SendACK(host,port,p.id);
233 if (p.type == PT_SYN_WITH_DATA)
235 strcpy(message,p.data);
236 strcpy(host,inet_ntoa(host_address.sin_addr));
237 port = ntohs(host_address.sin_port);
238 SendACK(host,port,p.id);